UNPKG

fabric

Version:

Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.

96 lines (95 loc) 3.96 kB
import "../constants.mjs"; import { parsePreserveAspectRatioAttribute, parseUnit } from "../util/misc/svgParsing.mjs"; import { reViewBoxAttrValue, svgNS, svgViewBoxElementsRegEx } from "./constants.mjs"; //#region src/parser/applyViewboxTransform.ts /** * Add a <g> element that envelop all child elements and makes the viewbox transformMatrix descend on all elements */ function applyViewboxTransform(element) { if (!svgViewBoxElementsRegEx.test(element.nodeName)) return {}; const viewBoxAttr = element.getAttribute("viewBox"); let scaleX = 1; let scaleY = 1; let minX = 0; let minY = 0; let matrix; let el; const widthAttr = element.getAttribute("width"); const heightAttr = element.getAttribute("height"); const x = element.getAttribute("x") || 0; const y = element.getAttribute("y") || 0; const missingViewBox = !(viewBoxAttr && reViewBoxAttrValue.test(viewBoxAttr)); const missingDimAttr = !widthAttr || !heightAttr || widthAttr === "100%" || heightAttr === "100%"; let translateMatrix = ""; let widthDiff = 0; let heightDiff = 0; if (missingViewBox) { if ((x || y) && element.parentNode && element.parentNode.nodeName !== "#document") { translateMatrix = " translate(" + parseUnit(x || "0") + " " + parseUnit(y || "0") + ") "; matrix = (element.getAttribute("transform") || "") + translateMatrix; element.setAttribute("transform", matrix); element.removeAttribute("x"); element.removeAttribute("y"); } } if (missingViewBox && missingDimAttr) return { width: 0, height: 0 }; const parsedDim = { width: 0, height: 0 }; if (missingViewBox) { parsedDim.width = parseUnit(widthAttr); parsedDim.height = parseUnit(heightAttr); return parsedDim; } const pasedViewBox = viewBoxAttr.match(reViewBoxAttrValue); minX = -parseFloat(pasedViewBox[1]); minY = -parseFloat(pasedViewBox[2]); const viewBoxWidth = parseFloat(pasedViewBox[3]); const viewBoxHeight = parseFloat(pasedViewBox[4]); parsedDim.minX = minX; parsedDim.minY = minY; parsedDim.viewBoxWidth = viewBoxWidth; parsedDim.viewBoxHeight = viewBoxHeight; if (!missingDimAttr) { parsedDim.width = parseUnit(widthAttr); parsedDim.height = parseUnit(heightAttr); scaleX = parsedDim.width / viewBoxWidth; scaleY = parsedDim.height / viewBoxHeight; } else { parsedDim.width = viewBoxWidth; parsedDim.height = viewBoxHeight; } const preserveAspectRatio = parsePreserveAspectRatioAttribute(element.getAttribute("preserveAspectRatio") || ""); if (preserveAspectRatio.alignX !== "none") { if (preserveAspectRatio.meetOrSlice === "meet") scaleY = scaleX = scaleX > scaleY ? scaleY : scaleX; if (preserveAspectRatio.meetOrSlice === "slice") scaleY = scaleX = scaleX > scaleY ? scaleX : scaleY; widthDiff = parsedDim.width - viewBoxWidth * scaleX; heightDiff = parsedDim.height - viewBoxHeight * scaleX; if (preserveAspectRatio.alignX === "Mid") widthDiff /= 2; if (preserveAspectRatio.alignY === "Mid") heightDiff /= 2; if (preserveAspectRatio.alignX === "Min") widthDiff = 0; if (preserveAspectRatio.alignY === "Min") heightDiff = 0; } if (scaleX === 1 && scaleY === 1 && minX === 0 && minY === 0 && x === 0 && y === 0) return parsedDim; if ((x || y) && element.parentNode.nodeName !== "#document") translateMatrix = " translate(" + parseUnit(x || "0") + " " + parseUnit(y || "0") + ") "; matrix = translateMatrix + " matrix(" + scaleX + " 0 0 " + scaleY + " " + (minX * scaleX + widthDiff) + " " + (minY * scaleY + heightDiff) + ") "; if (element.nodeName === "svg") { el = element.ownerDocument.createElementNS(svgNS, "g"); while (element.firstChild) el.appendChild(element.firstChild); element.appendChild(el); } else { el = element; el.removeAttribute("x"); el.removeAttribute("y"); matrix = el.getAttribute("transform") + matrix; } el.setAttribute("transform", matrix); return parsedDim; } //#endregion export { applyViewboxTransform }; //# sourceMappingURL=applyViewboxTransform.mjs.map