Last active
June 26, 2023 08:14
-
-
Save daformat/617675c671c01d94be23d6097e0f04e2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(() => { | |
// get the original svg and clone it in a hidden container | |
const originalSvg = $0; | |
const container = document.createElement('div'); | |
container.style = 'position: absolute; height: 1px; width: 1px; opacity: 0; overflow: hidden' | |
originalSvg.insertAdjacentElement('afterend', container) | |
const svg = $0.cloneNode(true); | |
container.appendChild(svg); | |
// cleanup funciton | |
const cleanup = () => { | |
container.remove(); | |
} | |
// convert camelCase to kebab-case | |
const kebabize = (str) => str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, ($, offset) => (offset ? "-" : "") + $.toLowerCase()) | |
// get the resolved value of a css variable call | |
const getVariableValue = (value, styles) => { | |
if (value.toString().trim().startsWith('var(')) { | |
const varName = value.replace(/var\(([^),]+)(,[^)]+)?\)/, '$1') | |
return styles.getPropertyValue(varName); | |
} | |
} | |
const inlineAttributesVariables = (element, attribute) => { | |
const withFill = element.querySelectorAll(`[${attribute}]`); | |
withFill.forEach(element => { | |
const styles = getComputedStyle(element) | |
const value = element.getAttribute(attribute) | |
const varValue = getVariableValue(value, styles); | |
if (varValue) { | |
element.setAttribute(attribute, varValue); | |
} | |
}) | |
} | |
const withClassName = svg.querySelectorAll('[class]') | |
withClassName.forEach(element => { | |
const styles = getComputedStyle(element) | |
const rules = {}; | |
for (let property in styles) { | |
let value = styles[property]; | |
if (value) { | |
const varValue = getVariableValue(value, styles); | |
rules[property] = varValue ?? value; | |
} | |
} | |
const style = element.getAttribute('style') | |
const addedStyle = Object.entries(rules).map(([property, value]) => `${kebabize(property)}: ${value}`).join(';') | |
element.setAttribute('style', `${style ? `${style};` : ''}${addedStyle};`) | |
element.className = ''; | |
}) | |
inlineAttributesVariables(svg, 'fill'); | |
inlineAttributesVariables(svg, 'stroke'); | |
inlineAttributesVariables(svg, 'stop-color'); | |
// convert to png | |
const svgData = new XMLSerializer().serializeToString(svg) | |
const svgDataBase64 = btoa(unescape(encodeURIComponent(svgData))) | |
const svgDataUrl = `data:image/svg+xml;charset=utf-8;base64,${svgDataBase64}` | |
const image = new Image() | |
image.addEventListener('load', () => { | |
const width = svg.getAttribute('width') * 2; | |
const height = svg.getAttribute('height') * 2; | |
const canvas = document.createElement('canvas'); | |
canvas.setAttribute('width', width); | |
canvas.setAttribute('height', height); | |
const context = canvas.getContext('2d'); | |
context.drawImage(image, 0, 0, width, height); | |
const link = document.createElement('a'); | |
link.download = 'image.png'; | |
link.setAttribute('href', canvas.toDataURL('image/png')); | |
link.click() | |
cleanup(); | |
}); | |
svg.insertAdjacentElement('afterend', image) | |
image.src = svgDataUrl; | |
})() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment