Skip to content

Instantly share code, notes, and snippets.

@foxbunny
Created November 28, 2023 22:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save foxbunny/29af840be1043baa4d97cd6434bf9b4c to your computer and use it in GitHub Desktop.
Save foxbunny/29af840be1043baa4d97cd6434bf9b4c to your computer and use it in GitHub Desktop.
SVG spritesheet creation script for use in Google Chrome Snippets
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