Make background-exporter work with multiple <image> instances
This commit is contained in:
@@ -11,54 +11,55 @@ async function inlineAndExport() {
|
|||||||
const bgDoc = parser.parseFromString(bgText, "image/svg+xml");
|
const bgDoc = parser.parseFromString(bgText, "image/svg+xml");
|
||||||
const svg = bgDoc.documentElement;
|
const svg = bgDoc.documentElement;
|
||||||
|
|
||||||
// Find the <image> referencing the logo (first one)
|
// Find ALL <image> elements
|
||||||
const imgEl = svg.querySelector("image[href], image[xlink\\:href]");
|
const imageEls = svg.querySelectorAll("image[href], image[xlink\\:href]");
|
||||||
if (!imgEl) {
|
|
||||||
console.error("No <image> element found in background.svg");
|
for (const imgEl of imageEls) {
|
||||||
return;
|
const href = imgEl.getAttribute("href") || imgEl.getAttribute("xlink:href");
|
||||||
|
|
||||||
|
// Only inline SVG images (skip PNG/JPG/etc.)
|
||||||
|
if (!href.endsWith(".svg")) continue;
|
||||||
|
|
||||||
|
// Load the referenced SVG
|
||||||
|
const logoText = await (await fetch(href)).text();
|
||||||
|
const logoDoc = parser.parseFromString(logoText, "image/svg+xml");
|
||||||
|
const logoSvg = logoDoc.documentElement;
|
||||||
|
|
||||||
|
// Extract inner content
|
||||||
|
const logoInner = Array.from(logoSvg.childNodes)
|
||||||
|
.filter(n => n.nodeType === 1)
|
||||||
|
.map(n => n.outerHTML)
|
||||||
|
.join("");
|
||||||
|
|
||||||
|
// Read viewBox
|
||||||
|
const vb = logoSvg.getAttribute("viewBox").split(" ").map(Number);
|
||||||
|
const vbWidth = vb[2];
|
||||||
|
const vbHeight = vb[3];
|
||||||
|
|
||||||
|
// Read <image> geometry
|
||||||
|
const x = parseFloat(imgEl.getAttribute("x") || 0);
|
||||||
|
const y = parseFloat(imgEl.getAttribute("y") || 0);
|
||||||
|
const w = parseFloat(imgEl.getAttribute("width"));
|
||||||
|
const h = parseFloat(imgEl.getAttribute("height"));
|
||||||
|
|
||||||
|
// Compute scale
|
||||||
|
const scaleX = w / vbWidth;
|
||||||
|
const scaleY = h / vbHeight;
|
||||||
|
|
||||||
|
// Create <g> wrapper
|
||||||
|
const g = bgDoc.createElementNS("http://www.w3.org/2000/svg", "g");
|
||||||
|
g.setAttribute("transform", `translate(${x},${y}) scale(${scaleX},${scaleY})`);
|
||||||
|
|
||||||
|
// Preserve width/height
|
||||||
|
g.setAttribute("width", imgEl.getAttribute("width"));
|
||||||
|
g.setAttribute("height", imgEl.getAttribute("height"));
|
||||||
|
|
||||||
|
g.innerHTML = logoInner;
|
||||||
|
|
||||||
|
// Replace <image> with <g>
|
||||||
|
imgEl.replaceWith(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
const logoHref = imgEl.getAttribute("href") || imgEl.getAttribute("xlink:href");
|
|
||||||
|
|
||||||
// Load logo
|
|
||||||
const logoText = await (await fetch(logoHref)).text();
|
|
||||||
const logoDoc = parser.parseFromString(logoText, "image/svg+xml");
|
|
||||||
const logoSvg = logoDoc.documentElement;
|
|
||||||
|
|
||||||
// Extract inner content of logo.svg
|
|
||||||
const logoInner = Array.from(logoSvg.childNodes)
|
|
||||||
.filter(n => n.nodeType === 1)
|
|
||||||
.map(n => n.outerHTML)
|
|
||||||
.join("");
|
|
||||||
|
|
||||||
// Read logo viewBox
|
|
||||||
const vb = logoSvg.getAttribute("viewBox").split(" ").map(Number);
|
|
||||||
const vbWidth = vb[2];
|
|
||||||
const vbHeight = vb[3];
|
|
||||||
|
|
||||||
// Read <image> geometry
|
|
||||||
const x = parseFloat(imgEl.getAttribute("x") || 0);
|
|
||||||
const y = parseFloat(imgEl.getAttribute("y") || 0);
|
|
||||||
const w = parseFloat(imgEl.getAttribute("width"));
|
|
||||||
const h = parseFloat(imgEl.getAttribute("height"));
|
|
||||||
|
|
||||||
// Compute scale
|
|
||||||
const scaleX = w / vbWidth;
|
|
||||||
const scaleY = h / vbHeight;
|
|
||||||
|
|
||||||
// Create <g> with correct transform
|
|
||||||
const g = bgDoc.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
||||||
g.setAttribute("transform", `translate(${x},${y}) scale(${scaleX},${scaleY})`);
|
|
||||||
|
|
||||||
// ⭐ NEW: preserve width/height from the original <image>
|
|
||||||
g.setAttribute("width", imgEl.getAttribute("width"));
|
|
||||||
g.setAttribute("height", imgEl.getAttribute("height"));
|
|
||||||
|
|
||||||
g.innerHTML = logoInner;
|
|
||||||
|
|
||||||
// Replace <image> with <g>
|
|
||||||
imgEl.replaceWith(g);
|
|
||||||
|
|
||||||
// Serialize final SVG
|
// Serialize final SVG
|
||||||
const finalSVG = new XMLSerializer().serializeToString(svg);
|
const finalSVG = new XMLSerializer().serializeToString(svg);
|
||||||
const svg64 = btoa(unescape(encodeURIComponent(finalSVG)));
|
const svg64 = btoa(unescape(encodeURIComponent(finalSVG)));
|
||||||
|
|||||||
Reference in New Issue
Block a user