Last active
August 22, 2024 07:53
-
-
Save RH2/0603c47b257103cb1cff76f9b2bf9cd2 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
//best version yet... | |
function processElement(element, ALL_IDS) { | |
let stylesheet = ''; | |
let svgString = ''; | |
// Check if the element has children (e.g., <g> elements) | |
if (element.children.length > 0) { | |
// If it's a group, process each child | |
let groupContent = ''; | |
Array.from(element.children).forEach((child) => { | |
const { svgString: childSvgString, stylesheet: childStylesheet } = processElement(child, ALL_IDS); | |
groupContent += childSvgString; | |
stylesheet += childStylesheet; | |
}); | |
// Reconstruct the group element with its processed children | |
const groupTag = element.outerHTML.match(/^<g[^>]*>/)[0]; | |
svgString += groupTag + '\n' + groupContent + '</g>\n'; | |
} else { | |
// Extract the 'stroke-dasharray' value if it exists | |
const style = element.getAttribute('style'); | |
const dasharrayMatch = style ? style.match(/stroke-dasharray\s*:\s*([^;]+);?/) : null; | |
if (dasharrayMatch) { | |
const dasharray = dasharrayMatch[1]; | |
// Calculate the total length (sum of dashes and gaps) | |
const dashValues = dasharray.split(/[\s,]+/).map(Number); | |
let totalLength = dashValues.reduce((acc, val) => acc + val, 0).toFixed(0); // Rounds to the nearest integer | |
// Generate a unique ID based on the element's totalLength to avoid duplication | |
const uniqueId = `flowline-${totalLength}`; | |
// If the uniqueId is not already in ALL_IDS | |
if (!ALL_IDS.includes(uniqueId)) { | |
ALL_IDS.push(uniqueId); | |
// Generate CSS rule | |
stylesheet += ` | |
#${uniqueId} { | |
animation: dash-${uniqueId} 1s linear infinite; | |
} | |
@keyframes dash-${uniqueId} { | |
from { | |
stroke-dashoffset: 0; | |
} | |
to { | |
stroke-dashoffset: ${totalLength}; | |
} | |
} | |
`; | |
} | |
// Assign the unique ID to the element | |
element.setAttribute('id', uniqueId); | |
} | |
// Convert the element back to a string and append to svgString | |
svgString += element.outerHTML.replace('xmlns="http://www.w3.org/2000/svg" ', "") + '\n'; | |
} | |
return { svgString, stylesheet }; | |
} | |
function generateSvgAndStylesheet(elements) { | |
let stylesheet = ''; | |
let svgString = ''; | |
const ALL_IDS = []; // Use a local array to keep track of unique IDs | |
elements.forEach((element) => { | |
const { svgString: elementSvgString, stylesheet: elementStylesheet } = processElement(element, ALL_IDS); | |
svgString += elementSvgString; | |
stylesheet += elementStylesheet; | |
}); | |
return { svgString, stylesheet }; | |
} | |
// Select all <path>, <rect>, and <g> elements | |
const elements = document.querySelectorAll('svg > path, svg > rect, svg > g'); | |
// Generate the SVG string and stylesheet string | |
const { svgString, stylesheet } = generateSvgAndStylesheet(elements); | |
// Output the SVG string and stylesheet string | |
console.log(stylesheet); | |
console.log(svgString); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment