UNPKG

fabric

Version:

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

1 lines 7.45 kB
{"version":3,"file":"applyViewboxTransform.mjs","names":[],"sources":["../../../src/parser/applyViewboxTransform.ts"],"sourcesContent":["import { svgNS } from './constants';\nimport {\n parsePreserveAspectRatioAttribute,\n parseUnit,\n} from '../util/misc/svgParsing';\nimport { svgViewBoxElementsRegEx, reViewBoxAttrValue } from './constants';\nimport { NONE } from '../constants';\n\nexport type ParsedViewboxTransform = Partial<{\n width: number;\n height: number;\n minX: number;\n minY: number;\n viewBoxWidth: number;\n viewBoxHeight: number;\n}>;\n\n/**\n * Add a <g> element that envelop all child elements and makes the viewbox transformMatrix descend on all elements\n */\nexport function applyViewboxTransform(\n element: Element,\n): ParsedViewboxTransform {\n if (!svgViewBoxElementsRegEx.test(element.nodeName)) {\n return {};\n }\n const viewBoxAttr: string | null = element.getAttribute('viewBox');\n let scaleX = 1;\n let scaleY = 1;\n let minX = 0;\n let minY = 0;\n let matrix;\n let el;\n const widthAttr = element.getAttribute('width');\n const heightAttr = element.getAttribute('height');\n const x = element.getAttribute('x') || 0;\n const y = element.getAttribute('y') || 0;\n const goodViewbox = viewBoxAttr && reViewBoxAttrValue.test(viewBoxAttr);\n const missingViewBox = !goodViewbox;\n const missingDimAttr =\n !widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%';\n\n let translateMatrix = '';\n let widthDiff = 0;\n let heightDiff = 0;\n\n if (missingViewBox) {\n if (\n (x || y) &&\n element.parentNode &&\n element.parentNode.nodeName !== '#document'\n ) {\n translateMatrix =\n ' translate(' + parseUnit(x || '0') + ' ' + parseUnit(y || '0') + ') ';\n matrix = (element.getAttribute('transform') || '') + translateMatrix;\n element.setAttribute('transform', matrix);\n element.removeAttribute('x');\n element.removeAttribute('y');\n }\n }\n\n if (missingViewBox && missingDimAttr) {\n return {\n width: 0,\n height: 0,\n };\n }\n\n const parsedDim: ParsedViewboxTransform = {\n width: 0,\n height: 0,\n };\n\n if (missingViewBox) {\n parsedDim.width = parseUnit(widthAttr!);\n parsedDim.height = parseUnit(heightAttr!);\n // set a transform for elements that have x y and are inner(only) SVGs\n return parsedDim;\n }\n\n const pasedViewBox = viewBoxAttr.match(reViewBoxAttrValue)!;\n minX = -parseFloat(pasedViewBox[1]);\n minY = -parseFloat(pasedViewBox[2]);\n const viewBoxWidth = parseFloat(pasedViewBox[3]);\n const viewBoxHeight = parseFloat(pasedViewBox[4]);\n parsedDim.minX = minX;\n parsedDim.minY = minY;\n parsedDim.viewBoxWidth = viewBoxWidth;\n parsedDim.viewBoxHeight = viewBoxHeight;\n if (!missingDimAttr) {\n parsedDim.width = parseUnit(widthAttr);\n parsedDim.height = parseUnit(heightAttr);\n scaleX = parsedDim.width / viewBoxWidth;\n scaleY = parsedDim.height / viewBoxHeight;\n } else {\n parsedDim.width = viewBoxWidth;\n parsedDim.height = viewBoxHeight;\n }\n\n // default is to preserve aspect ratio\n const preserveAspectRatio = parsePreserveAspectRatioAttribute(\n element.getAttribute('preserveAspectRatio') || '',\n );\n if (preserveAspectRatio.alignX !== NONE) {\n //translate all container for the effect of Mid, Min, Max\n if (preserveAspectRatio.meetOrSlice === 'meet') {\n scaleY = scaleX = scaleX > scaleY ? scaleY : scaleX;\n // calculate additional translation to move the viewbox\n }\n if (preserveAspectRatio.meetOrSlice === 'slice') {\n scaleY = scaleX = scaleX > scaleY ? scaleX : scaleY;\n // calculate additional translation to move the viewbox\n }\n widthDiff = parsedDim.width - viewBoxWidth * scaleX;\n heightDiff = parsedDim.height - viewBoxHeight * scaleX;\n if (preserveAspectRatio.alignX === 'Mid') {\n widthDiff /= 2;\n }\n if (preserveAspectRatio.alignY === 'Mid') {\n heightDiff /= 2;\n }\n if (preserveAspectRatio.alignX === 'Min') {\n widthDiff = 0;\n }\n if (preserveAspectRatio.alignY === 'Min') {\n heightDiff = 0;\n }\n }\n\n if (\n scaleX === 1 &&\n scaleY === 1 &&\n minX === 0 &&\n minY === 0 &&\n x === 0 &&\n y === 0\n ) {\n return parsedDim;\n }\n if ((x || y) && element.parentNode!.nodeName !== '#document') {\n translateMatrix =\n ' translate(' + parseUnit(x || '0') + ' ' + parseUnit(y || '0') + ') ';\n }\n\n matrix =\n translateMatrix +\n ' matrix(' +\n scaleX +\n ' 0' +\n ' 0 ' +\n scaleY +\n ' ' +\n (minX * scaleX + widthDiff) +\n ' ' +\n (minY * scaleY + heightDiff) +\n ') ';\n // seems unused.\n // parsedDim.viewboxTransform = parseTransformAttribute(matrix);\n if (element.nodeName === 'svg') {\n el = element.ownerDocument.createElementNS(svgNS, 'g');\n // element.firstChild != null\n while (element.firstChild) {\n el.appendChild(element.firstChild);\n }\n element.appendChild(el);\n } else {\n el = element;\n el.removeAttribute('x');\n el.removeAttribute('y');\n matrix = el.getAttribute('transform') + matrix;\n }\n el.setAttribute('transform', matrix);\n return parsedDim;\n}\n"],"mappings":";;;;;;;AAoBA,SAAgB,sBACd,SACwB;AACxB,KAAI,CAAC,wBAAwB,KAAK,QAAQ,SAAS,CACjD,QAAO,EAAE;CAEX,MAAM,cAA6B,QAAQ,aAAa,UAAU;CAClE,IAAI,SAAS;CACb,IAAI,SAAS;CACb,IAAI,OAAO;CACX,IAAI,OAAO;CACX,IAAI;CACJ,IAAI;CACJ,MAAM,YAAY,QAAQ,aAAa,QAAQ;CAC/C,MAAM,aAAa,QAAQ,aAAa,SAAS;CACjD,MAAM,IAAI,QAAQ,aAAa,IAAI,IAAI;CACvC,MAAM,IAAI,QAAQ,aAAa,IAAI,IAAI;CAEvC,MAAM,iBAAiB,EADH,eAAe,mBAAmB,KAAK,YAAY;CAEvE,MAAM,iBACJ,CAAC,aAAa,CAAC,cAAc,cAAc,UAAU,eAAe;CAEtE,IAAI,kBAAkB;CACtB,IAAI,YAAY;CAChB,IAAI,aAAa;AAEjB,KAAI;OAEC,KAAK,MACN,QAAQ,cACR,QAAQ,WAAW,aAAa,aAChC;AACA,qBACE,gBAAgB,UAAU,KAAK,IAAI,GAAG,MAAM,UAAU,KAAK,IAAI,GAAG;AACpE,aAAU,QAAQ,aAAa,YAAY,IAAI,MAAM;AACrD,WAAQ,aAAa,aAAa,OAAO;AACzC,WAAQ,gBAAgB,IAAI;AAC5B,WAAQ,gBAAgB,IAAI;;;AAIhC,KAAI,kBAAkB,eACpB,QAAO;EACL,OAAO;EACP,QAAQ;EACT;CAGH,MAAM,YAAoC;EACxC,OAAO;EACP,QAAQ;EACT;AAED,KAAI,gBAAgB;AAClB,YAAU,QAAQ,UAAU,UAAW;AACvC,YAAU,SAAS,UAAU,WAAY;AAEzC,SAAO;;CAGT,MAAM,eAAe,YAAY,MAAM,mBAAmB;AAC1D,QAAO,CAAC,WAAW,aAAa,GAAG;AACnC,QAAO,CAAC,WAAW,aAAa,GAAG;CACnC,MAAM,eAAe,WAAW,aAAa,GAAG;CAChD,MAAM,gBAAgB,WAAW,aAAa,GAAG;AACjD,WAAU,OAAO;AACjB,WAAU,OAAO;AACjB,WAAU,eAAe;AACzB,WAAU,gBAAgB;AAC1B,KAAI,CAAC,gBAAgB;AACnB,YAAU,QAAQ,UAAU,UAAU;AACtC,YAAU,SAAS,UAAU,WAAW;AACxC,WAAS,UAAU,QAAQ;AAC3B,WAAS,UAAU,SAAS;QACvB;AACL,YAAU,QAAQ;AAClB,YAAU,SAAS;;CAIrB,MAAM,sBAAsB,kCAC1B,QAAQ,aAAa,sBAAsB,IAAI,GAChD;AACD,KAAI,oBAAoB,WAAA,QAAiB;AAEvC,MAAI,oBAAoB,gBAAgB,OACtC,UAAS,SAAS,SAAS,SAAS,SAAS;AAG/C,MAAI,oBAAoB,gBAAgB,QACtC,UAAS,SAAS,SAAS,SAAS,SAAS;AAG/C,cAAY,UAAU,QAAQ,eAAe;AAC7C,eAAa,UAAU,SAAS,gBAAgB;AAChD,MAAI,oBAAoB,WAAW,MACjC,cAAa;AAEf,MAAI,oBAAoB,WAAW,MACjC,eAAc;AAEhB,MAAI,oBAAoB,WAAW,MACjC,aAAY;AAEd,MAAI,oBAAoB,WAAW,MACjC,cAAa;;AAIjB,KACE,WAAW,KACX,WAAW,KACX,SAAS,KACT,SAAS,KACT,MAAM,KACN,MAAM,EAEN,QAAO;AAET,MAAK,KAAK,MAAM,QAAQ,WAAY,aAAa,YAC/C,mBACE,gBAAgB,UAAU,KAAK,IAAI,GAAG,MAAM,UAAU,KAAK,IAAI,GAAG;AAGtE,UACE,kBACA,aACA,SACA,UAEA,SACA,OACC,OAAO,SAAS,aACjB,OACC,OAAO,SAAS,cACjB;AAGF,KAAI,QAAQ,aAAa,OAAO;AAC9B,OAAK,QAAQ,cAAc,gBAAgB,OAAO,IAAI;AAEtD,SAAO,QAAQ,WACb,IAAG,YAAY,QAAQ,WAAW;AAEpC,UAAQ,YAAY,GAAG;QAClB;AACL,OAAK;AACL,KAAG,gBAAgB,IAAI;AACvB,KAAG,gBAAgB,IAAI;AACvB,WAAS,GAAG,aAAa,YAAY,GAAG;;AAE1C,IAAG,aAAa,aAAa,OAAO;AACpC,QAAO"}