Created
November 28, 2023 22:39
-
-
Save foxbunny/29af840be1043baa4d97cd6434bf9b4c to your computer and use it in GitHub Desktop.
SVG spritesheet creation script for use in Google Chrome Snippets
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
let svgMimeType = 'image/svg+xml' | |
let svgNS = 'http://www.w3.org/2000/svg' | |
let preamble = '<?xml version="1.0" encoding="utf-8"?>' | |
Object.assign(document.createElement('input'), { | |
type: 'file', | |
accept: svgMimeType, | |
multiple: true, | |
onchange: processFiles, | |
}).click() | |
function processFiles(ev) { | |
readFiles(ev.target.files, processSvgList) | |
} | |
function readFiles(files, callback) { | |
let filesRemaining = files.length | |
let fileContents = [] | |
for (let file of files) | |
readFile(file, function (content) { | |
fileContents.push({content, name: file.name}) | |
if (!(--filesRemaining)) callback(fileContents) | |
}) | |
} | |
function readFile(file, callback) { | |
let reader = new FileReader() | |
reader.onload = function () { | |
callback(reader.result) | |
} | |
reader.readAsText(file) | |
} | |
function processSvgList(svgContentList) { | |
let sprites = [] | |
let defs = [] | |
for (let svgContent of svgContentList) { | |
let result = processSvg(svgContent) | |
if (result.symbol) sprites.push(result.symbol) | |
if (result.defs?.length) defs.push(...result.defs) | |
} | |
let parser = new DOMParser() | |
let spritesheet = parser.parseFromString(`${preamble}<svg xmlns="${svgNS}"></svg>`, svgMimeType) | |
let spritesheetDefs = spritesheet.createElementNS(svgNS, 'defs') | |
spritesheet.querySelector('svg').append(spritesheetDefs) | |
for (let sprite of sprites) spritesheetDefs.append(sprite) | |
for (let def of defs) spritesheetDefs.append(def) | |
console.log(spritesheet.documentElement.outerHTML) | |
navigator.clipboard.writeText(spritesheet.documentElement.outerHTML) | |
} | |
function processSvg(svgContent) { | |
let svgText = svgContent.content | |
let svgName = svgContent.name.split('.')[0] | |
let parser = new DOMParser() | |
let svgDocument = parser.parseFromString(svgText, svgMimeType) | |
console.log(svgDocument) | |
let svg = svgDocument.querySelector('svg') | |
let graphics = svg.querySelectorAll(':not(defs):not([id])') | |
let svgDocumentDefs = svg.querySelectorAll('defs > *') | |
let symbol = document.createElementNS(svgNS, 'symbol') | |
let defs = [] | |
symbol.setAttribute('viewBox', svg.getAttribute('viewBox')) | |
symbol.setAttribute('id', svgName) | |
for (let graphic of graphics) { | |
for (let propertyName of graphic.style) { | |
graphic.setAttribute(propertyName, graphic.style[propertyName]) | |
graphic.style[propertyName] = '' | |
} | |
if (svgName == 'logo' || svgName === 'search') | |
graphic.setAttribute('fill', 'currentColor') | |
if (svgName == 'star') | |
graphic.setAttribute('stroke', 'currentColor') | |
symbol.append(graphic) | |
} | |
for (let def of svgDocumentDefs) defs.push(def.cloneNode(true)) | |
return {symbol, defs} | |
} | |
function convertStyleToAttribute(element, stylePropertyName) { | |
if (!element.style[stylePropertyName]) return | |
element[stylePropertyName] = element.style[stylePropertyName] | |
element.style[stylePropertyName] = '' | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment