diff options
| author | Tim Keller <tjk@tjkeller.xyz> | 2025-06-13 13:42:21 -0500 |
|---|---|---|
| committer | Tim Keller <tjk@tjkeller.xyz> | 2025-06-13 13:42:21 -0500 |
| commit | b4d0b0293812afba9637c7e636bfa51366a030f7 (patch) | |
| tree | 93b9e2d5ce841b76f5c41741a8ebca4a745571b0 /src/utils.js | |
| parent | 4154e0cc1744996788b6727cd2ef4a0d3a42095e (diff) | |
| download | material-svg-atlas-plugin-webpack-b4d0b0293812afba9637c7e636bfa51366a030f7.tar.xz material-svg-atlas-plugin-webpack-b4d0b0293812afba9637c7e636bfa51366a030f7.zip | |
cleanup package and fix bug from not importing fs/path in utils
Diffstat (limited to 'src/utils.js')
| -rw-r--r-- | src/utils.js | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 0000000..fc424d3 --- /dev/null +++ b/src/utils.js @@ -0,0 +1,83 @@ +const fs = require("fs") +const path = require("path") +const svgSprite = require("svg-sprite") +const { optimize } = require("svgo") +const { JSDOM } = require("jsdom") + +// Generate <view>'s for referencing sprites in css +function generateAtlasViews(svgFile, symbolId) { + const dom = new JSDOM(svgFile) + const document = dom.window.document + const svg = document.querySelector("svg") + + const symbols = document.querySelectorAll("symbol") + const width = 24 + const height = 24 + let row = 0 + let col = 0 + const totalCols = Math.floor(Math.sqrt(symbols.length)) + for (const symbol of symbols) { + const x = col * width + const y = row * height + + let id = symbol.getAttribute("id") + symbol.removeAttribute("xmlns") + if (symbolId) { + id = symbolId(id) + symbol.setAttribute("id", id) + } + + // Create elements + const svgView = document.createElement("view") + svgView.setAttribute("id", `${id}-view`) + svgView.setAttribute("viewBox", `${x} ${y} ${width} ${height}`) + const svgUse = document.createElement("use") + svgUse.setAttribute("width", width) + svgUse.setAttribute("height", height) + //svgUse.setAttribute("viewBox", "0 -960 960 960") + svgUse.setAttribute("x", x) + svgUse.setAttribute("y", y) + svgUse.setAttribute("href", `#${id}`) + + // Append elements + svg.appendChild(svgView) + svg.appendChild(svgUse) + + // Adjust row/col + col++ + if (col > totalCols) { + col = 0 + row++ + } + } + const cWidth = (totalCols + 1) * width + const cHeight = (row + 1) * height + svg.setAttribute("viewBox", `0 0 ${cWidth} ${cHeight}`) + svg.setAttribute("width", `${cWidth}px`) + svg.setAttribute("height", `${cHeight}px`) + + const svgStr = svg.outerHTML.replaceAll("viewbox", "viewBox") // JSDOM will lower-case all attributes + return optimize(svgStr, { + multipass: true, + plugins: [{ name: "removeUnknownsAndDefaults", active: false }], // Prevent changing of ids + }).data +} + +async function generateAtlasViewsFromReferences(refs, symbolId) { + const spriter = new svgSprite({ mode: { symbol: { dest: "", sprite: "icons.svg" } } }) + // Add refs to spriter + for (const ref of refs) { + const name = (ref.name ?? ref.symbol ?? ref.path.replace(".svg", "")) + ".svg" // Supposed to pass a file path, make a fake one + spriter.add(name, null, ref.svg) + } + + // Compile and return atlas + const { result } = await spriter.compileAsync() + return generateAtlasViews(result.symbol.sprite.contents.toString(), symbolId) +} + +function createDirectoriesForFile(filePath) { + fs.mkdirSync(path.dirname(filePath), { recursive: true }) +} + +module.exports = { generateAtlasViews, generateAtlasViewsFromReferences, createDirectoriesForFile } |
