fabric 6.0.0 → 6.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +8 -18
- package/dist/fabric.d.ts +4 -0
- package/dist/fabric.d.ts.map +1 -1
- package/dist/fabric.min.mjs +1 -1
- package/dist/fabric.mjs +1 -0
- package/dist/fabric.mjs.map +1 -1
- package/dist/index.js +146 -107
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.min.mjs +1 -1
- package/dist/index.min.mjs.map +1 -1
- package/dist/index.mjs +146 -108
- package/dist/index.mjs.map +1 -1
- package/dist/index.node.cjs +146 -107
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +146 -108
- package/dist/index.node.mjs.map +1 -1
- package/dist/package.json.min.mjs +1 -1
- package/dist/package.json.mjs +1 -1
- package/dist/src/EventTypeDefs.d.ts +2 -1
- package/dist/src/EventTypeDefs.d.ts.map +1 -1
- package/dist/src/LayoutManager/LayoutManager.d.ts.map +1 -1
- package/dist/src/LayoutManager/LayoutManager.min.mjs +1 -1
- package/dist/src/LayoutManager/LayoutManager.min.mjs.map +1 -1
- package/dist/src/LayoutManager/LayoutManager.mjs +13 -8
- package/dist/src/LayoutManager/LayoutManager.mjs.map +1 -1
- package/dist/src/LayoutManager/LayoutStrategies/ClipPathLayout.min.mjs +1 -1
- package/dist/src/LayoutManager/LayoutStrategies/ClipPathLayout.min.mjs.map +1 -1
- package/dist/src/LayoutManager/LayoutStrategies/ClipPathLayout.mjs +3 -3
- package/dist/src/LayoutManager/LayoutStrategies/ClipPathLayout.mjs.map +1 -1
- package/dist/src/LayoutManager/LayoutStrategies/LayoutStrategy.d.ts +1 -1
- package/dist/src/LayoutManager/LayoutStrategies/LayoutStrategy.d.ts.map +1 -1
- package/dist/src/LayoutManager/LayoutStrategies/LayoutStrategy.min.mjs +1 -1
- package/dist/src/LayoutManager/LayoutStrategies/LayoutStrategy.min.mjs.map +1 -1
- package/dist/src/LayoutManager/LayoutStrategies/LayoutStrategy.mjs +15 -9
- package/dist/src/LayoutManager/LayoutStrategies/LayoutStrategy.mjs.map +1 -1
- package/dist/src/Observable.d.ts +8 -0
- package/dist/src/Observable.d.ts.map +1 -1
- package/dist/src/Observable.min.mjs.map +1 -1
- package/dist/src/Observable.mjs +8 -0
- package/dist/src/Observable.mjs.map +1 -1
- package/dist/src/canvas/SelectableCanvas.d.ts.map +1 -1
- package/dist/src/canvas/SelectableCanvas.min.mjs +1 -1
- package/dist/src/canvas/SelectableCanvas.min.mjs.map +1 -1
- package/dist/src/canvas/SelectableCanvas.mjs +5 -5
- package/dist/src/canvas/SelectableCanvas.mjs.map +1 -1
- package/dist/src/canvas/StaticCanvas.d.ts +1 -1
- package/dist/src/constants.d.ts +16 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.min.mjs +1 -1
- package/dist/src/constants.min.mjs.map +1 -1
- package/dist/src/constants.mjs +17 -1
- package/dist/src/constants.mjs.map +1 -1
- package/dist/src/controls/Control.d.ts.map +1 -1
- package/dist/src/controls/Control.min.mjs +1 -1
- package/dist/src/controls/Control.min.mjs.map +1 -1
- package/dist/src/controls/Control.mjs +2 -1
- package/dist/src/controls/Control.mjs.map +1 -1
- package/dist/src/controls/changeWidth.min.mjs +1 -1
- package/dist/src/controls/changeWidth.min.mjs.map +1 -1
- package/dist/src/controls/changeWidth.mjs +2 -2
- package/dist/src/controls/changeWidth.mjs.map +1 -1
- package/dist/src/controls/commonControls.d.ts.map +1 -1
- package/dist/src/controls/commonControls.min.mjs +1 -1
- package/dist/src/controls/commonControls.min.mjs.map +1 -1
- package/dist/src/controls/commonControls.mjs +4 -3
- package/dist/src/controls/commonControls.mjs.map +1 -1
- package/dist/src/controls/controlRendering.min.mjs +1 -1
- package/dist/src/controls/controlRendering.min.mjs.map +1 -1
- package/dist/src/controls/controlRendering.mjs +3 -3
- package/dist/src/controls/controlRendering.mjs.map +1 -1
- package/dist/src/controls/drag.min.mjs +1 -1
- package/dist/src/controls/drag.min.mjs.map +1 -1
- package/dist/src/controls/drag.mjs +2 -2
- package/dist/src/controls/drag.mjs.map +1 -1
- package/dist/src/controls/polyControl.d.ts.map +1 -1
- package/dist/src/controls/polyControl.min.mjs +1 -1
- package/dist/src/controls/polyControl.min.mjs.map +1 -1
- package/dist/src/controls/polyControl.mjs +2 -1
- package/dist/src/controls/polyControl.mjs.map +1 -1
- package/dist/src/controls/rotate.d.ts.map +1 -1
- package/dist/src/controls/rotate.min.mjs +1 -1
- package/dist/src/controls/rotate.min.mjs.map +1 -1
- package/dist/src/controls/rotate.mjs +2 -1
- package/dist/src/controls/rotate.mjs.map +1 -1
- package/dist/src/controls/scale.d.ts.map +1 -1
- package/dist/src/controls/scale.min.mjs +1 -1
- package/dist/src/controls/scale.min.mjs.map +1 -1
- package/dist/src/controls/scale.mjs +8 -7
- package/dist/src/controls/scale.mjs.map +1 -1
- package/dist/src/controls/scaleSkew.d.ts.map +1 -1
- package/dist/src/controls/scaleSkew.min.mjs +1 -1
- package/dist/src/controls/scaleSkew.min.mjs.map +1 -1
- package/dist/src/controls/scaleSkew.mjs +3 -2
- package/dist/src/controls/scaleSkew.mjs.map +1 -1
- package/dist/src/controls/skew.d.ts.map +1 -1
- package/dist/src/controls/skew.min.mjs +1 -1
- package/dist/src/controls/skew.min.mjs.map +1 -1
- package/dist/src/controls/skew.mjs +7 -7
- package/dist/src/controls/skew.mjs.map +1 -1
- package/dist/src/filters/Blur.min.mjs +1 -1
- package/dist/src/filters/Blur.min.mjs.map +1 -1
- package/dist/src/filters/Blur.mjs +1 -1
- package/dist/src/filters/Blur.mjs.map +1 -1
- package/dist/src/filters/Pixelate.min.mjs +1 -1
- package/dist/src/filters/Pixelate.min.mjs.map +1 -1
- package/dist/src/filters/Pixelate.mjs +1 -1
- package/dist/src/filters/Pixelate.mjs.map +1 -1
- package/dist/src/parser/attributes.d.ts.map +1 -1
- package/dist/src/parser/attributes.min.mjs +1 -1
- package/dist/src/parser/attributes.min.mjs.map +1 -1
- package/dist/src/parser/attributes.mjs +3 -1
- package/dist/src/parser/attributes.mjs.map +1 -1
- package/dist/src/parser/elements_parser.min.mjs +1 -1
- package/dist/src/parser/elements_parser.min.mjs.map +1 -1
- package/dist/src/parser/elements_parser.mjs +3 -3
- package/dist/src/parser/elements_parser.mjs.map +1 -1
- package/dist/src/parser/normalizeValue.min.mjs +1 -1
- package/dist/src/parser/normalizeValue.min.mjs.map +1 -1
- package/dist/src/parser/normalizeValue.mjs +7 -7
- package/dist/src/parser/normalizeValue.mjs.map +1 -1
- package/dist/src/parser/parseTransformAttribute.min.mjs +1 -1
- package/dist/src/parser/parseTransformAttribute.min.mjs.map +1 -1
- package/dist/src/parser/parseTransformAttribute.mjs +5 -5
- package/dist/src/parser/parseTransformAttribute.mjs.map +1 -1
- package/dist/src/shapes/Circle.d.ts.map +1 -1
- package/dist/src/shapes/Circle.min.mjs +1 -1
- package/dist/src/shapes/Circle.min.mjs.map +1 -1
- package/dist/src/shapes/Circle.mjs +3 -2
- package/dist/src/shapes/Circle.mjs.map +1 -1
- package/dist/src/shapes/Ellipse.min.mjs +1 -1
- package/dist/src/shapes/Ellipse.min.mjs.map +1 -1
- package/dist/src/shapes/Ellipse.mjs +3 -3
- package/dist/src/shapes/Ellipse.mjs.map +1 -1
- package/dist/src/shapes/IText/DraggableTextDelegate.min.mjs +1 -1
- package/dist/src/shapes/IText/DraggableTextDelegate.min.mjs.map +1 -1
- package/dist/src/shapes/IText/DraggableTextDelegate.mjs +3 -3
- package/dist/src/shapes/IText/DraggableTextDelegate.mjs.map +1 -1
- package/dist/src/shapes/IText/IText.min.mjs +1 -1
- package/dist/src/shapes/IText/IText.min.mjs.map +1 -1
- package/dist/src/shapes/IText/IText.mjs +3 -3
- package/dist/src/shapes/IText/IText.mjs.map +1 -1
- package/dist/src/shapes/IText/ITextBehavior.min.mjs +1 -1
- package/dist/src/shapes/IText/ITextBehavior.min.mjs.map +1 -1
- package/dist/src/shapes/IText/ITextBehavior.mjs +2 -2
- package/dist/src/shapes/IText/ITextBehavior.mjs.map +1 -1
- package/dist/src/shapes/IText/ITextKeyBehavior.min.mjs +1 -1
- package/dist/src/shapes/IText/ITextKeyBehavior.min.mjs.map +1 -1
- package/dist/src/shapes/IText/ITextKeyBehavior.mjs +2 -2
- package/dist/src/shapes/IText/ITextKeyBehavior.mjs.map +1 -1
- package/dist/src/shapes/Image.min.mjs +1 -1
- package/dist/src/shapes/Image.min.mjs.map +1 -1
- package/dist/src/shapes/Image.mjs +2 -2
- package/dist/src/shapes/Image.mjs.map +1 -1
- package/dist/src/shapes/Object/AnimatableObject.d.ts.map +1 -1
- package/dist/src/shapes/Object/AnimatableObject.min.mjs +1 -1
- package/dist/src/shapes/Object/AnimatableObject.min.mjs.map +1 -1
- package/dist/src/shapes/Object/AnimatableObject.mjs +2 -1
- package/dist/src/shapes/Object/AnimatableObject.mjs.map +1 -1
- package/dist/src/shapes/Object/FabricObjectSVGExportMixin.d.ts.map +1 -1
- package/dist/src/shapes/Object/FabricObjectSVGExportMixin.min.mjs +1 -1
- package/dist/src/shapes/Object/FabricObjectSVGExportMixin.min.mjs.map +1 -1
- package/dist/src/shapes/Object/FabricObjectSVGExportMixin.mjs +4 -4
- package/dist/src/shapes/Object/FabricObjectSVGExportMixin.mjs.map +1 -1
- package/dist/src/shapes/Object/InteractiveObject.d.ts.map +1 -1
- package/dist/src/shapes/Object/InteractiveObject.min.mjs +1 -1
- package/dist/src/shapes/Object/InteractiveObject.min.mjs.map +1 -1
- package/dist/src/shapes/Object/InteractiveObject.mjs +2 -1
- package/dist/src/shapes/Object/InteractiveObject.mjs.map +1 -1
- package/dist/src/shapes/Object/Object.d.ts +9 -7
- package/dist/src/shapes/Object/Object.d.ts.map +1 -1
- package/dist/src/shapes/Object/Object.min.mjs +1 -1
- package/dist/src/shapes/Object/Object.min.mjs.map +1 -1
- package/dist/src/shapes/Object/Object.mjs +14 -12
- package/dist/src/shapes/Object/Object.mjs.map +1 -1
- package/dist/src/shapes/Object/ObjectGeometry.min.mjs +1 -1
- package/dist/src/shapes/Object/ObjectGeometry.min.mjs.map +1 -1
- package/dist/src/shapes/Object/ObjectGeometry.mjs +3 -3
- package/dist/src/shapes/Object/ObjectGeometry.mjs.map +1 -1
- package/dist/src/shapes/Object/defaultValues.d.ts.map +1 -1
- package/dist/src/shapes/Object/defaultValues.min.mjs +1 -1
- package/dist/src/shapes/Object/defaultValues.min.mjs.map +1 -1
- package/dist/src/shapes/Object/defaultValues.mjs +4 -4
- package/dist/src/shapes/Object/defaultValues.mjs.map +1 -1
- package/dist/src/shapes/Object/types/ControlProps.d.ts +4 -3
- package/dist/src/shapes/Object/types/ControlProps.d.ts.map +1 -1
- package/dist/src/shapes/Polyline.d.ts.map +1 -1
- package/dist/src/shapes/Polyline.min.mjs +1 -1
- package/dist/src/shapes/Polyline.min.mjs.map +1 -1
- package/dist/src/shapes/Polyline.mjs +3 -3
- package/dist/src/shapes/Polyline.mjs.map +1 -1
- package/dist/src/shapes/Text/Text.d.ts +2 -2
- package/dist/src/shapes/Text/Text.d.ts.map +1 -1
- package/dist/src/shapes/Text/Text.min.mjs +1 -1
- package/dist/src/shapes/Text/Text.min.mjs.map +1 -1
- package/dist/src/shapes/Text/Text.mjs +5 -5
- package/dist/src/shapes/Text/Text.mjs.map +1 -1
- package/dist/src/shapes/Text/TextSVGExportMixin.d.ts.map +1 -1
- package/dist/src/shapes/Text/TextSVGExportMixin.min.mjs +1 -1
- package/dist/src/shapes/Text/TextSVGExportMixin.min.mjs.map +1 -1
- package/dist/src/shapes/Text/TextSVGExportMixin.mjs +2 -1
- package/dist/src/shapes/Text/TextSVGExportMixin.mjs.map +1 -1
- package/dist/src/shapes/Text/constants.min.mjs +1 -1
- package/dist/src/shapes/Text/constants.min.mjs.map +1 -1
- package/dist/src/shapes/Text/constants.mjs +2 -2
- package/dist/src/shapes/Text/constants.mjs.map +1 -1
- package/dist/src/util/misc/objectEnlive.d.ts +1 -0
- package/dist/src/util/misc/objectEnlive.d.ts.map +1 -1
- package/dist/src/util/misc/objectEnlive.min.mjs.map +1 -1
- package/dist/src/util/misc/objectEnlive.mjs +1 -0
- package/dist/src/util/misc/objectEnlive.mjs.map +1 -1
- package/dist/src/util/misc/svgParsing.min.mjs +1 -1
- package/dist/src/util/misc/svgParsing.min.mjs.map +1 -1
- package/dist/src/util/misc/svgParsing.mjs +2 -2
- package/dist/src/util/misc/svgParsing.mjs.map +1 -1
- package/dist/src/util/transform_matrix_removal.min.mjs +1 -1
- package/dist/src/util/transform_matrix_removal.min.mjs.map +1 -1
- package/dist/src/util/transform_matrix_removal.mjs +3 -3
- package/dist/src/util/transform_matrix_removal.mjs.map +1 -1
- package/fabric.ts +4 -0
- package/package.json +1 -1
- package/src/EventTypeDefs.ts +14 -6
- package/src/LayoutManager/LayoutManager.ts +28 -19
- package/src/LayoutManager/LayoutStrategies/ClipPathLayout.ts +2 -2
- package/src/LayoutManager/LayoutStrategies/LayoutStrategy.ts +7 -7
- package/src/Observable.ts +8 -0
- package/src/canvas/SelectableCanvas.ts +25 -11
- package/src/canvas/canvas_gestures.mixin.ts +6 -5
- package/src/constants.ts +17 -0
- package/src/controls/Control.ts +2 -1
- package/src/controls/changeWidth.ts +2 -2
- package/src/controls/commonControls.ts +4 -3
- package/src/controls/controlRendering.ts +3 -3
- package/src/controls/drag.ts +2 -2
- package/src/controls/polyControl.ts +2 -1
- package/src/controls/rotate.ts +2 -1
- package/src/controls/scale.ts +8 -7
- package/src/controls/scaleSkew.ts +3 -2
- package/src/controls/skew.ts +14 -7
- package/src/filters/Blur.ts +1 -1
- package/src/filters/Pixelate.ts +1 -1
- package/src/parser/attributes.ts +4 -2
- package/src/parser/elements_parser.ts +3 -3
- package/src/parser/normalizeValue.ts +7 -7
- package/src/parser/parseTransformAttribute.ts +5 -5
- package/src/shapes/Circle.ts +3 -2
- package/src/shapes/Ellipse.ts +3 -3
- package/src/shapes/IText/DraggableTextDelegate.ts +3 -3
- package/src/shapes/IText/IText.ts +3 -3
- package/src/shapes/IText/ITextBehavior.ts +2 -2
- package/src/shapes/IText/ITextKeyBehavior.ts +2 -2
- package/src/shapes/Image.ts +2 -2
- package/src/shapes/Object/AnimatableObject.ts +2 -1
- package/src/shapes/Object/FabricObjectSVGExportMixin.ts +4 -6
- package/src/shapes/Object/InteractiveObject.ts +2 -1
- package/src/shapes/Object/Object.ts +16 -11
- package/src/shapes/Object/ObjectGeometry.ts +3 -3
- package/src/shapes/Object/defaultValues.ts +17 -8
- package/src/shapes/Object/types/ControlProps.ts +4 -3
- package/src/shapes/Polyline.spec.ts +0 -1
- package/src/shapes/Polyline.ts +12 -4
- package/src/shapes/Text/Text.ts +7 -7
- package/src/shapes/Text/TextSVGExportMixin.ts +3 -2
- package/src/shapes/Text/constants.ts +3 -3
- package/src/util/misc/objectEnlive.ts +1 -0
- package/src/util/misc/svgParsing.ts +2 -2
- package/src/util/transform_matrix_removal.ts +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextSVGExportMixin.min.mjs","sources":["../../../../src/shapes/Text/TextSVGExportMixin.ts"],"sourcesContent":["import { config } from '../../config';\nimport type { TSVGReviver } from '../../typedefs';\nimport { escapeXml } from '../../util/lang_string';\nimport { colorPropToSVG, createSVGRect } from '../../util/misc/svgParsing';\nimport { hasStyleChanged } from '../../util/misc/textStyles';\nimport { toFixed } from '../../util/misc/toFixed';\nimport { FabricObjectSVGExportMixin } from '../Object/FabricObjectSVGExportMixin';\nimport { type TextStyleDeclaration } from './StyledText';\nimport { JUSTIFY } from '../Text/constants';\nimport type { FabricText } from './Text';\n\nconst multipleSpacesRegex = / +/g;\nconst dblQuoteRegex = /\"/g;\n\nfunction createSVGInlineRect(\n color: string,\n left: number,\n top: number,\n width: number,\n height: number\n) {\n return `\\t\\t${createSVGRect(color, { left, top, width, height })}\\n`;\n}\n\nexport class TextSVGExportMixin extends FabricObjectSVGExportMixin {\n _toSVG(this: TextSVGExportMixin & FabricText): string[] {\n const offsets = this._getSVGLeftTopOffsets(),\n textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);\n return this._wrapSVGTextAndBg(textAndBg);\n }\n\n toSVG(this: TextSVGExportMixin & FabricText, reviver?: TSVGReviver): string {\n return this._createBaseSVGMarkup(this._toSVG(), {\n reviver,\n noStyle: true,\n withShadow: true,\n });\n }\n\n private _getSVGLeftTopOffsets(this: TextSVGExportMixin & FabricText) {\n return {\n textLeft: -this.width / 2,\n textTop: -this.height / 2,\n lineTop: this.getHeightOfLine(0),\n };\n }\n\n private _wrapSVGTextAndBg(\n this: TextSVGExportMixin & FabricText,\n {\n textBgRects,\n textSpans,\n }: {\n textSpans: string[];\n textBgRects: string[];\n }\n ) {\n const noShadow = true,\n textDecoration = this.getSvgTextDecoration(this);\n return [\n textBgRects.join(''),\n '\\t\\t<text xml:space=\"preserve\" ',\n this.fontFamily\n ? `font-family=\"${this.fontFamily.replace(dblQuoteRegex, \"'\")}\" `\n : '',\n this.fontSize ? `font-size=\"${this.fontSize}\" ` : '',\n this.fontStyle ? `font-style=\"${this.fontStyle}\" ` : '',\n this.fontWeight ? `font-weight=\"${this.fontWeight}\" ` : '',\n textDecoration ? `text-decoration=\"${textDecoration}\" ` : '',\n this.direction === 'rtl' ? `direction=\"${this.direction}\" ` : '',\n 'style=\"',\n this.getSvgStyles(noShadow),\n '\"',\n this.addPaintOrder(),\n ' >',\n textSpans.join(''),\n '</text>\\n',\n ];\n }\n\n /**\n * @private\n * @param {Number} textTopOffset Text top offset\n * @param {Number} textLeftOffset Text left offset\n * @return {Object}\n */\n private _getSVGTextAndBg(\n this: TextSVGExportMixin & FabricText,\n textTopOffset: number,\n textLeftOffset: number\n ) {\n const textSpans: string[] = [],\n textBgRects: string[] = [];\n let height = textTopOffset,\n lineOffset;\n\n // bounding-box background\n this.backgroundColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n this.backgroundColor,\n -this.width / 2,\n -this.height / 2,\n this.width,\n this.height\n )\n );\n\n // text and text-background\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n lineOffset = this._getLineLeftOffset(i);\n if (this.direction === 'rtl') {\n lineOffset += this.width;\n }\n if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) {\n this._setSVGTextLineBg(\n textBgRects,\n i,\n textLeftOffset + lineOffset,\n height\n );\n }\n this._setSVGTextLineText(\n textSpans,\n i,\n textLeftOffset + lineOffset,\n height\n );\n height += this.getHeightOfLine(i);\n }\n\n return {\n textSpans,\n textBgRects,\n };\n }\n\n private _createTextCharSpan(\n this: TextSVGExportMixin & FabricText,\n char: string,\n styleDecl: TextStyleDeclaration,\n left: number,\n top: number\n ) {\n const styleProps = this.getSvgSpanStyles(\n styleDecl,\n char !== char.trim() || !!char.match(multipleSpacesRegex)\n ),\n fillStyles = styleProps ? `style=\"${styleProps}\"` : '',\n dy = styleDecl.deltaY,\n dySpan = dy ? ` dy=\"${toFixed(dy, config.NUM_FRACTION_DIGITS)}\" ` : '';\n\n return `<tspan x=\"${toFixed(\n left,\n config.NUM_FRACTION_DIGITS\n )}\" y=\"${toFixed(\n top,\n config.NUM_FRACTION_DIGITS\n )}\" ${dySpan}${fillStyles}>${escapeXml(char)}</tspan>`;\n }\n\n private _setSVGTextLineText(\n this: TextSVGExportMixin & FabricText,\n textSpans: string[],\n lineIndex: number,\n textLeftOffset: number,\n textTopOffset: number\n ) {\n const lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.includes(JUSTIFY),\n line = this._textLines[lineIndex];\n let actualStyle,\n nextStyle,\n charsToRender = '',\n charBox,\n style,\n boxWidth = 0,\n timeToRender;\n\n textTopOffset +=\n (lineHeight * (1 - this._fontSizeFraction)) / this.lineHeight;\n for (let i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i];\n if (boxWidth === 0) {\n textLeftOffset += charBox.kernedWidth - charBox.width;\n boxWidth += charBox.width;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle =\n actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = hasStyleChanged(actualStyle, nextStyle, true);\n }\n if (timeToRender) {\n style = this._getStyleDeclaration(lineIndex, i);\n textSpans.push(\n this._createTextCharSpan(\n charsToRender,\n style,\n textLeftOffset,\n textTopOffset\n )\n );\n charsToRender = '';\n actualStyle = nextStyle;\n if (this.direction === 'rtl') {\n textLeftOffset -= boxWidth;\n } else {\n textLeftOffset += boxWidth;\n }\n boxWidth = 0;\n }\n }\n }\n\n private _setSVGTextLineBg(\n this: TextSVGExportMixin & FabricText,\n textBgRects: (string | number)[],\n i: number,\n leftOffset: number,\n textTopOffset: number\n ) {\n const line = this._textLines[i],\n heightOfLine = this.getHeightOfLine(i) / this.lineHeight;\n let boxWidth = 0,\n boxStart = 0,\n currentColor,\n lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n for (let j = 0; j < line.length; j++) {\n const { left, width, kernedWidth } = this.__charBounds[i][j];\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n if (currentColor !== lastColor) {\n lastColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n lastColor,\n leftOffset + boxStart,\n textTopOffset,\n boxWidth,\n heightOfLine\n )\n );\n boxStart = left;\n boxWidth = width;\n lastColor = currentColor;\n } else {\n boxWidth += kernedWidth;\n }\n }\n currentColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n lastColor,\n leftOffset + boxStart,\n textTopOffset,\n boxWidth,\n heightOfLine\n )\n );\n }\n\n /**\n * @deprecated unused\n */\n _getSVGLineTopOffset(\n this: TextSVGExportMixin & FabricText,\n lineIndex: number\n ) {\n let lineTopOffset = 0,\n j;\n for (j = 0; j < lineIndex; j++) {\n lineTopOffset += this.getHeightOfLine(j);\n }\n const lastHeight = this.getHeightOfLine(j);\n return {\n lineTop: lineTopOffset,\n offset:\n ((this._fontSizeMult - this._fontSizeFraction) * lastHeight) /\n (this.lineHeight * this._fontSizeMult),\n };\n }\n\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles(this: TextSVGExportMixin & FabricText, skipShadow?: boolean) {\n // cant use ts-expect-error because of ts 5.3 cross check\n // @ts-ignore TS doesn't respect this type casting\n return `${super.getSvgStyles(skipShadow)} white-space: pre;`;\n }\n\n /**\n * Returns styles-string for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style.\n * @return {String}\n */\n getSvgSpanStyles(\n this: TextSVGExportMixin & FabricText,\n style: TextStyleDeclaration,\n useWhiteSpace?: boolean\n ) {\n const {\n fontFamily,\n strokeWidth,\n stroke,\n fill,\n fontSize,\n fontStyle,\n fontWeight,\n deltaY,\n } = style;\n\n const textDecoration = this.getSvgTextDecoration(style);\n\n return [\n stroke ? colorPropToSVG('stroke', stroke) : '',\n strokeWidth ? `stroke-width: ${strokeWidth}; ` : '',\n fontFamily\n ? `font-family: ${\n !fontFamily.includes(\"'\") && !fontFamily.includes('\"')\n ? `'${fontFamily}'`\n : fontFamily\n }; `\n : '',\n fontSize ? `font-size: ${fontSize}px; ` : '',\n fontStyle ? `font-style: ${fontStyle}; ` : '',\n fontWeight ? `font-weight: ${fontWeight}; ` : '',\n textDecoration ? `text-decoration: ${textDecoration}; ` : textDecoration,\n fill ? colorPropToSVG('fill', fill) : '',\n deltaY ? `baseline-shift: ${-deltaY}; ` : '',\n useWhiteSpace ? 'white-space: pre; ' : '',\n ].join('');\n }\n\n /**\n * Returns text-decoration property for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @return {String}\n */\n getSvgTextDecoration(\n this: TextSVGExportMixin & FabricText,\n style: TextStyleDeclaration\n ) {\n return (['overline', 'underline', 'line-through'] as const)\n .filter(\n (decoration) =>\n style[\n decoration.replace('-', '') as\n | 'overline'\n | 'underline'\n | 'linethrough'\n ]\n )\n .join(' ');\n }\n}\n"],"names":["multipleSpacesRegex","dblQuoteRegex","createSVGInlineRect","color","left","top","width","height","concat","createSVGRect","TextSVGExportMixin","FabricObjectSVGExportMixin","_toSVG","offsets","this","_getSVGLeftTopOffsets","textAndBg","_getSVGTextAndBg","textTop","textLeft","_wrapSVGTextAndBg","toSVG","reviver","_createBaseSVGMarkup","noStyle","withShadow","lineTop","getHeightOfLine","_ref","textBgRects","textSpans","textDecoration","getSvgTextDecoration","join","fontFamily","replace","fontSize","fontStyle","fontWeight","direction","getSvgStyles","addPaintOrder","textTopOffset","textLeftOffset","lineOffset","backgroundColor","push","i","len","_textLines","length","_getLineLeftOffset","textBackgroundColor","styleHas","_setSVGTextLineBg","_setSVGTextLineText","_createTextCharSpan","char","styleDecl","styleProps","getSvgSpanStyles","trim","match","fillStyles","dy","deltaY","dySpan","toFixed","config","NUM_FRACTION_DIGITS","escapeXml","lineIndex","lineHeight","isJustify","textAlign","includes","JUSTIFY","line","actualStyle","nextStyle","charBox","style","timeToRender","charsToRender","boxWidth","_fontSizeFraction","charSpacing","__charBounds","kernedWidth","_reSpaceAndTab","test","getCompleteStyleDeclaration","hasStyleChanged","_getStyleDeclaration","leftOffset","heightOfLine","currentColor","boxStart","lastColor","getValueOfPropertyAt","j","_getSVGLineTopOffset","lineTopOffset","lastHeight","offset","_fontSizeMult","skipShadow","super","useWhiteSpace","strokeWidth","stroke","fill","colorPropToSVG","filter","decoration"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TextSVGExportMixin.min.mjs","sources":["../../../../src/shapes/Text/TextSVGExportMixin.ts"],"sourcesContent":["import { config } from '../../config';\nimport type { TSVGReviver } from '../../typedefs';\nimport { escapeXml } from '../../util/lang_string';\nimport { colorPropToSVG, createSVGRect } from '../../util/misc/svgParsing';\nimport { hasStyleChanged } from '../../util/misc/textStyles';\nimport { toFixed } from '../../util/misc/toFixed';\nimport { FabricObjectSVGExportMixin } from '../Object/FabricObjectSVGExportMixin';\nimport { type TextStyleDeclaration } from './StyledText';\nimport { JUSTIFY } from '../Text/constants';\nimport type { FabricText } from './Text';\nimport { STROKE, FILL } from '../../constants';\n\nconst multipleSpacesRegex = / +/g;\nconst dblQuoteRegex = /\"/g;\n\nfunction createSVGInlineRect(\n color: string,\n left: number,\n top: number,\n width: number,\n height: number\n) {\n return `\\t\\t${createSVGRect(color, { left, top, width, height })}\\n`;\n}\n\nexport class TextSVGExportMixin extends FabricObjectSVGExportMixin {\n _toSVG(this: TextSVGExportMixin & FabricText): string[] {\n const offsets = this._getSVGLeftTopOffsets(),\n textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);\n return this._wrapSVGTextAndBg(textAndBg);\n }\n\n toSVG(this: TextSVGExportMixin & FabricText, reviver?: TSVGReviver): string {\n return this._createBaseSVGMarkup(this._toSVG(), {\n reviver,\n noStyle: true,\n withShadow: true,\n });\n }\n\n private _getSVGLeftTopOffsets(this: TextSVGExportMixin & FabricText) {\n return {\n textLeft: -this.width / 2,\n textTop: -this.height / 2,\n lineTop: this.getHeightOfLine(0),\n };\n }\n\n private _wrapSVGTextAndBg(\n this: TextSVGExportMixin & FabricText,\n {\n textBgRects,\n textSpans,\n }: {\n textSpans: string[];\n textBgRects: string[];\n }\n ) {\n const noShadow = true,\n textDecoration = this.getSvgTextDecoration(this);\n return [\n textBgRects.join(''),\n '\\t\\t<text xml:space=\"preserve\" ',\n this.fontFamily\n ? `font-family=\"${this.fontFamily.replace(dblQuoteRegex, \"'\")}\" `\n : '',\n this.fontSize ? `font-size=\"${this.fontSize}\" ` : '',\n this.fontStyle ? `font-style=\"${this.fontStyle}\" ` : '',\n this.fontWeight ? `font-weight=\"${this.fontWeight}\" ` : '',\n textDecoration ? `text-decoration=\"${textDecoration}\" ` : '',\n this.direction === 'rtl' ? `direction=\"${this.direction}\" ` : '',\n 'style=\"',\n this.getSvgStyles(noShadow),\n '\"',\n this.addPaintOrder(),\n ' >',\n textSpans.join(''),\n '</text>\\n',\n ];\n }\n\n /**\n * @private\n * @param {Number} textTopOffset Text top offset\n * @param {Number} textLeftOffset Text left offset\n * @return {Object}\n */\n private _getSVGTextAndBg(\n this: TextSVGExportMixin & FabricText,\n textTopOffset: number,\n textLeftOffset: number\n ) {\n const textSpans: string[] = [],\n textBgRects: string[] = [];\n let height = textTopOffset,\n lineOffset;\n\n // bounding-box background\n this.backgroundColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n this.backgroundColor,\n -this.width / 2,\n -this.height / 2,\n this.width,\n this.height\n )\n );\n\n // text and text-background\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n lineOffset = this._getLineLeftOffset(i);\n if (this.direction === 'rtl') {\n lineOffset += this.width;\n }\n if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) {\n this._setSVGTextLineBg(\n textBgRects,\n i,\n textLeftOffset + lineOffset,\n height\n );\n }\n this._setSVGTextLineText(\n textSpans,\n i,\n textLeftOffset + lineOffset,\n height\n );\n height += this.getHeightOfLine(i);\n }\n\n return {\n textSpans,\n textBgRects,\n };\n }\n\n private _createTextCharSpan(\n this: TextSVGExportMixin & FabricText,\n char: string,\n styleDecl: TextStyleDeclaration,\n left: number,\n top: number\n ) {\n const styleProps = this.getSvgSpanStyles(\n styleDecl,\n char !== char.trim() || !!char.match(multipleSpacesRegex)\n ),\n fillStyles = styleProps ? `style=\"${styleProps}\"` : '',\n dy = styleDecl.deltaY,\n dySpan = dy ? ` dy=\"${toFixed(dy, config.NUM_FRACTION_DIGITS)}\" ` : '';\n\n return `<tspan x=\"${toFixed(\n left,\n config.NUM_FRACTION_DIGITS\n )}\" y=\"${toFixed(\n top,\n config.NUM_FRACTION_DIGITS\n )}\" ${dySpan}${fillStyles}>${escapeXml(char)}</tspan>`;\n }\n\n private _setSVGTextLineText(\n this: TextSVGExportMixin & FabricText,\n textSpans: string[],\n lineIndex: number,\n textLeftOffset: number,\n textTopOffset: number\n ) {\n const lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.includes(JUSTIFY),\n line = this._textLines[lineIndex];\n let actualStyle,\n nextStyle,\n charsToRender = '',\n charBox,\n style,\n boxWidth = 0,\n timeToRender;\n\n textTopOffset +=\n (lineHeight * (1 - this._fontSizeFraction)) / this.lineHeight;\n for (let i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i];\n if (boxWidth === 0) {\n textLeftOffset += charBox.kernedWidth - charBox.width;\n boxWidth += charBox.width;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle =\n actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = hasStyleChanged(actualStyle, nextStyle, true);\n }\n if (timeToRender) {\n style = this._getStyleDeclaration(lineIndex, i);\n textSpans.push(\n this._createTextCharSpan(\n charsToRender,\n style,\n textLeftOffset,\n textTopOffset\n )\n );\n charsToRender = '';\n actualStyle = nextStyle;\n if (this.direction === 'rtl') {\n textLeftOffset -= boxWidth;\n } else {\n textLeftOffset += boxWidth;\n }\n boxWidth = 0;\n }\n }\n }\n\n private _setSVGTextLineBg(\n this: TextSVGExportMixin & FabricText,\n textBgRects: (string | number)[],\n i: number,\n leftOffset: number,\n textTopOffset: number\n ) {\n const line = this._textLines[i],\n heightOfLine = this.getHeightOfLine(i) / this.lineHeight;\n let boxWidth = 0,\n boxStart = 0,\n currentColor,\n lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n for (let j = 0; j < line.length; j++) {\n const { left, width, kernedWidth } = this.__charBounds[i][j];\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n if (currentColor !== lastColor) {\n lastColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n lastColor,\n leftOffset + boxStart,\n textTopOffset,\n boxWidth,\n heightOfLine\n )\n );\n boxStart = left;\n boxWidth = width;\n lastColor = currentColor;\n } else {\n boxWidth += kernedWidth;\n }\n }\n currentColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n lastColor,\n leftOffset + boxStart,\n textTopOffset,\n boxWidth,\n heightOfLine\n )\n );\n }\n\n /**\n * @deprecated unused\n */\n _getSVGLineTopOffset(\n this: TextSVGExportMixin & FabricText,\n lineIndex: number\n ) {\n let lineTopOffset = 0,\n j;\n for (j = 0; j < lineIndex; j++) {\n lineTopOffset += this.getHeightOfLine(j);\n }\n const lastHeight = this.getHeightOfLine(j);\n return {\n lineTop: lineTopOffset,\n offset:\n ((this._fontSizeMult - this._fontSizeFraction) * lastHeight) /\n (this.lineHeight * this._fontSizeMult),\n };\n }\n\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles(this: TextSVGExportMixin & FabricText, skipShadow?: boolean) {\n // cant use ts-expect-error because of ts 5.3 cross check\n // @ts-ignore TS doesn't respect this type casting\n return `${super.getSvgStyles(skipShadow)} white-space: pre;`;\n }\n\n /**\n * Returns styles-string for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style.\n * @return {String}\n */\n getSvgSpanStyles(\n this: TextSVGExportMixin & FabricText,\n style: TextStyleDeclaration,\n useWhiteSpace?: boolean\n ) {\n const {\n fontFamily,\n strokeWidth,\n stroke,\n fill,\n fontSize,\n fontStyle,\n fontWeight,\n deltaY,\n } = style;\n\n const textDecoration = this.getSvgTextDecoration(style);\n\n return [\n stroke ? colorPropToSVG(STROKE, stroke) : '',\n strokeWidth ? `stroke-width: ${strokeWidth}; ` : '',\n fontFamily\n ? `font-family: ${\n !fontFamily.includes(\"'\") && !fontFamily.includes('\"')\n ? `'${fontFamily}'`\n : fontFamily\n }; `\n : '',\n fontSize ? `font-size: ${fontSize}px; ` : '',\n fontStyle ? `font-style: ${fontStyle}; ` : '',\n fontWeight ? `font-weight: ${fontWeight}; ` : '',\n textDecoration ? `text-decoration: ${textDecoration}; ` : textDecoration,\n fill ? colorPropToSVG(FILL, fill) : '',\n deltaY ? `baseline-shift: ${-deltaY}; ` : '',\n useWhiteSpace ? 'white-space: pre; ' : '',\n ].join('');\n }\n\n /**\n * Returns text-decoration property for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @return {String}\n */\n getSvgTextDecoration(\n this: TextSVGExportMixin & FabricText,\n style: TextStyleDeclaration\n ) {\n return (['overline', 'underline', 'line-through'] as const)\n .filter(\n (decoration) =>\n style[\n decoration.replace('-', '') as\n | 'overline'\n | 'underline'\n | 'linethrough'\n ]\n )\n .join(' ');\n }\n}\n"],"names":["multipleSpacesRegex","dblQuoteRegex","createSVGInlineRect","color","left","top","width","height","concat","createSVGRect","TextSVGExportMixin","FabricObjectSVGExportMixin","_toSVG","offsets","this","_getSVGLeftTopOffsets","textAndBg","_getSVGTextAndBg","textTop","textLeft","_wrapSVGTextAndBg","toSVG","reviver","_createBaseSVGMarkup","noStyle","withShadow","lineTop","getHeightOfLine","_ref","textBgRects","textSpans","textDecoration","getSvgTextDecoration","join","fontFamily","replace","fontSize","fontStyle","fontWeight","direction","getSvgStyles","addPaintOrder","textTopOffset","textLeftOffset","lineOffset","backgroundColor","push","i","len","_textLines","length","_getLineLeftOffset","textBackgroundColor","styleHas","_setSVGTextLineBg","_setSVGTextLineText","_createTextCharSpan","char","styleDecl","styleProps","getSvgSpanStyles","trim","match","fillStyles","dy","deltaY","dySpan","toFixed","config","NUM_FRACTION_DIGITS","escapeXml","lineIndex","lineHeight","isJustify","textAlign","includes","JUSTIFY","line","actualStyle","nextStyle","charBox","style","timeToRender","charsToRender","boxWidth","_fontSizeFraction","charSpacing","__charBounds","kernedWidth","_reSpaceAndTab","test","getCompleteStyleDeclaration","hasStyleChanged","_getStyleDeclaration","leftOffset","heightOfLine","currentColor","boxStart","lastColor","getValueOfPropertyAt","j","_getSVGLineTopOffset","lineTopOffset","lastHeight","offset","_fontSizeMult","skipShadow","super","useWhiteSpace","strokeWidth","stroke","fill","colorPropToSVG","STROKE","FILL","filter","decoration"],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import { hasStyleChanged } from '../../util/misc/textStyles.mjs';
|
|
|
5
5
|
import { toFixed } from '../../util/misc/toFixed.mjs';
|
|
6
6
|
import { FabricObjectSVGExportMixin } from '../Object/FabricObjectSVGExportMixin.mjs';
|
|
7
7
|
import { JUSTIFY } from './constants.mjs';
|
|
8
|
+
import { STROKE, FILL } from '../../constants.mjs';
|
|
8
9
|
|
|
9
10
|
const multipleSpacesRegex = / +/g;
|
|
10
11
|
const dblQuoteRegex = /"/g;
|
|
@@ -203,7 +204,7 @@ class TextSVGExportMixin extends FabricObjectSVGExportMixin {
|
|
|
203
204
|
deltaY
|
|
204
205
|
} = style;
|
|
205
206
|
const textDecoration = this.getSvgTextDecoration(style);
|
|
206
|
-
return [stroke ? colorPropToSVG(
|
|
207
|
+
return [stroke ? colorPropToSVG(STROKE, stroke) : '', strokeWidth ? "stroke-width: ".concat(strokeWidth, "; ") : '', fontFamily ? "font-family: ".concat(!fontFamily.includes("'") && !fontFamily.includes('"') ? "'".concat(fontFamily, "'") : fontFamily, "; ") : '', fontSize ? "font-size: ".concat(fontSize, "px; ") : '', fontStyle ? "font-style: ".concat(fontStyle, "; ") : '', fontWeight ? "font-weight: ".concat(fontWeight, "; ") : '', textDecoration ? "text-decoration: ".concat(textDecoration, "; ") : textDecoration, fill ? colorPropToSVG(FILL, fill) : '', deltaY ? "baseline-shift: ".concat(-deltaY, "; ") : '', useWhiteSpace ? 'white-space: pre; ' : ''].join('');
|
|
207
208
|
}
|
|
208
209
|
|
|
209
210
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextSVGExportMixin.mjs","sources":["../../../../src/shapes/Text/TextSVGExportMixin.ts"],"sourcesContent":["import { config } from '../../config';\nimport type { TSVGReviver } from '../../typedefs';\nimport { escapeXml } from '../../util/lang_string';\nimport { colorPropToSVG, createSVGRect } from '../../util/misc/svgParsing';\nimport { hasStyleChanged } from '../../util/misc/textStyles';\nimport { toFixed } from '../../util/misc/toFixed';\nimport { FabricObjectSVGExportMixin } from '../Object/FabricObjectSVGExportMixin';\nimport { type TextStyleDeclaration } from './StyledText';\nimport { JUSTIFY } from '../Text/constants';\nimport type { FabricText } from './Text';\n\nconst multipleSpacesRegex = / +/g;\nconst dblQuoteRegex = /\"/g;\n\nfunction createSVGInlineRect(\n color: string,\n left: number,\n top: number,\n width: number,\n height: number\n) {\n return `\\t\\t${createSVGRect(color, { left, top, width, height })}\\n`;\n}\n\nexport class TextSVGExportMixin extends FabricObjectSVGExportMixin {\n _toSVG(this: TextSVGExportMixin & FabricText): string[] {\n const offsets = this._getSVGLeftTopOffsets(),\n textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);\n return this._wrapSVGTextAndBg(textAndBg);\n }\n\n toSVG(this: TextSVGExportMixin & FabricText, reviver?: TSVGReviver): string {\n return this._createBaseSVGMarkup(this._toSVG(), {\n reviver,\n noStyle: true,\n withShadow: true,\n });\n }\n\n private _getSVGLeftTopOffsets(this: TextSVGExportMixin & FabricText) {\n return {\n textLeft: -this.width / 2,\n textTop: -this.height / 2,\n lineTop: this.getHeightOfLine(0),\n };\n }\n\n private _wrapSVGTextAndBg(\n this: TextSVGExportMixin & FabricText,\n {\n textBgRects,\n textSpans,\n }: {\n textSpans: string[];\n textBgRects: string[];\n }\n ) {\n const noShadow = true,\n textDecoration = this.getSvgTextDecoration(this);\n return [\n textBgRects.join(''),\n '\\t\\t<text xml:space=\"preserve\" ',\n this.fontFamily\n ? `font-family=\"${this.fontFamily.replace(dblQuoteRegex, \"'\")}\" `\n : '',\n this.fontSize ? `font-size=\"${this.fontSize}\" ` : '',\n this.fontStyle ? `font-style=\"${this.fontStyle}\" ` : '',\n this.fontWeight ? `font-weight=\"${this.fontWeight}\" ` : '',\n textDecoration ? `text-decoration=\"${textDecoration}\" ` : '',\n this.direction === 'rtl' ? `direction=\"${this.direction}\" ` : '',\n 'style=\"',\n this.getSvgStyles(noShadow),\n '\"',\n this.addPaintOrder(),\n ' >',\n textSpans.join(''),\n '</text>\\n',\n ];\n }\n\n /**\n * @private\n * @param {Number} textTopOffset Text top offset\n * @param {Number} textLeftOffset Text left offset\n * @return {Object}\n */\n private _getSVGTextAndBg(\n this: TextSVGExportMixin & FabricText,\n textTopOffset: number,\n textLeftOffset: number\n ) {\n const textSpans: string[] = [],\n textBgRects: string[] = [];\n let height = textTopOffset,\n lineOffset;\n\n // bounding-box background\n this.backgroundColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n this.backgroundColor,\n -this.width / 2,\n -this.height / 2,\n this.width,\n this.height\n )\n );\n\n // text and text-background\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n lineOffset = this._getLineLeftOffset(i);\n if (this.direction === 'rtl') {\n lineOffset += this.width;\n }\n if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) {\n this._setSVGTextLineBg(\n textBgRects,\n i,\n textLeftOffset + lineOffset,\n height\n );\n }\n this._setSVGTextLineText(\n textSpans,\n i,\n textLeftOffset + lineOffset,\n height\n );\n height += this.getHeightOfLine(i);\n }\n\n return {\n textSpans,\n textBgRects,\n };\n }\n\n private _createTextCharSpan(\n this: TextSVGExportMixin & FabricText,\n char: string,\n styleDecl: TextStyleDeclaration,\n left: number,\n top: number\n ) {\n const styleProps = this.getSvgSpanStyles(\n styleDecl,\n char !== char.trim() || !!char.match(multipleSpacesRegex)\n ),\n fillStyles = styleProps ? `style=\"${styleProps}\"` : '',\n dy = styleDecl.deltaY,\n dySpan = dy ? ` dy=\"${toFixed(dy, config.NUM_FRACTION_DIGITS)}\" ` : '';\n\n return `<tspan x=\"${toFixed(\n left,\n config.NUM_FRACTION_DIGITS\n )}\" y=\"${toFixed(\n top,\n config.NUM_FRACTION_DIGITS\n )}\" ${dySpan}${fillStyles}>${escapeXml(char)}</tspan>`;\n }\n\n private _setSVGTextLineText(\n this: TextSVGExportMixin & FabricText,\n textSpans: string[],\n lineIndex: number,\n textLeftOffset: number,\n textTopOffset: number\n ) {\n const lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.includes(JUSTIFY),\n line = this._textLines[lineIndex];\n let actualStyle,\n nextStyle,\n charsToRender = '',\n charBox,\n style,\n boxWidth = 0,\n timeToRender;\n\n textTopOffset +=\n (lineHeight * (1 - this._fontSizeFraction)) / this.lineHeight;\n for (let i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i];\n if (boxWidth === 0) {\n textLeftOffset += charBox.kernedWidth - charBox.width;\n boxWidth += charBox.width;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle =\n actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = hasStyleChanged(actualStyle, nextStyle, true);\n }\n if (timeToRender) {\n style = this._getStyleDeclaration(lineIndex, i);\n textSpans.push(\n this._createTextCharSpan(\n charsToRender,\n style,\n textLeftOffset,\n textTopOffset\n )\n );\n charsToRender = '';\n actualStyle = nextStyle;\n if (this.direction === 'rtl') {\n textLeftOffset -= boxWidth;\n } else {\n textLeftOffset += boxWidth;\n }\n boxWidth = 0;\n }\n }\n }\n\n private _setSVGTextLineBg(\n this: TextSVGExportMixin & FabricText,\n textBgRects: (string | number)[],\n i: number,\n leftOffset: number,\n textTopOffset: number\n ) {\n const line = this._textLines[i],\n heightOfLine = this.getHeightOfLine(i) / this.lineHeight;\n let boxWidth = 0,\n boxStart = 0,\n currentColor,\n lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n for (let j = 0; j < line.length; j++) {\n const { left, width, kernedWidth } = this.__charBounds[i][j];\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n if (currentColor !== lastColor) {\n lastColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n lastColor,\n leftOffset + boxStart,\n textTopOffset,\n boxWidth,\n heightOfLine\n )\n );\n boxStart = left;\n boxWidth = width;\n lastColor = currentColor;\n } else {\n boxWidth += kernedWidth;\n }\n }\n currentColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n lastColor,\n leftOffset + boxStart,\n textTopOffset,\n boxWidth,\n heightOfLine\n )\n );\n }\n\n /**\n * @deprecated unused\n */\n _getSVGLineTopOffset(\n this: TextSVGExportMixin & FabricText,\n lineIndex: number\n ) {\n let lineTopOffset = 0,\n j;\n for (j = 0; j < lineIndex; j++) {\n lineTopOffset += this.getHeightOfLine(j);\n }\n const lastHeight = this.getHeightOfLine(j);\n return {\n lineTop: lineTopOffset,\n offset:\n ((this._fontSizeMult - this._fontSizeFraction) * lastHeight) /\n (this.lineHeight * this._fontSizeMult),\n };\n }\n\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles(this: TextSVGExportMixin & FabricText, skipShadow?: boolean) {\n // cant use ts-expect-error because of ts 5.3 cross check\n // @ts-ignore TS doesn't respect this type casting\n return `${super.getSvgStyles(skipShadow)} white-space: pre;`;\n }\n\n /**\n * Returns styles-string for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style.\n * @return {String}\n */\n getSvgSpanStyles(\n this: TextSVGExportMixin & FabricText,\n style: TextStyleDeclaration,\n useWhiteSpace?: boolean\n ) {\n const {\n fontFamily,\n strokeWidth,\n stroke,\n fill,\n fontSize,\n fontStyle,\n fontWeight,\n deltaY,\n } = style;\n\n const textDecoration = this.getSvgTextDecoration(style);\n\n return [\n stroke ? colorPropToSVG('stroke', stroke) : '',\n strokeWidth ? `stroke-width: ${strokeWidth}; ` : '',\n fontFamily\n ? `font-family: ${\n !fontFamily.includes(\"'\") && !fontFamily.includes('\"')\n ? `'${fontFamily}'`\n : fontFamily\n }; `\n : '',\n fontSize ? `font-size: ${fontSize}px; ` : '',\n fontStyle ? `font-style: ${fontStyle}; ` : '',\n fontWeight ? `font-weight: ${fontWeight}; ` : '',\n textDecoration ? `text-decoration: ${textDecoration}; ` : textDecoration,\n fill ? colorPropToSVG('fill', fill) : '',\n deltaY ? `baseline-shift: ${-deltaY}; ` : '',\n useWhiteSpace ? 'white-space: pre; ' : '',\n ].join('');\n }\n\n /**\n * Returns text-decoration property for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @return {String}\n */\n getSvgTextDecoration(\n this: TextSVGExportMixin & FabricText,\n style: TextStyleDeclaration\n ) {\n return (['overline', 'underline', 'line-through'] as const)\n .filter(\n (decoration) =>\n style[\n decoration.replace('-', '') as\n | 'overline'\n | 'underline'\n | 'linethrough'\n ]\n )\n .join(' ');\n }\n}\n"],"names":["multipleSpacesRegex","dblQuoteRegex","createSVGInlineRect","color","left","top","width","height","concat","createSVGRect","TextSVGExportMixin","FabricObjectSVGExportMixin","_toSVG","offsets","_getSVGLeftTopOffsets","textAndBg","_getSVGTextAndBg","textTop","textLeft","_wrapSVGTextAndBg","toSVG","reviver","_createBaseSVGMarkup","noStyle","withShadow","lineTop","getHeightOfLine","_ref","textBgRects","textSpans","noShadow","textDecoration","getSvgTextDecoration","join","fontFamily","replace","fontSize","fontStyle","fontWeight","direction","getSvgStyles","addPaintOrder","textTopOffset","textLeftOffset","lineOffset","backgroundColor","push","i","len","_textLines","length","_getLineLeftOffset","textBackgroundColor","styleHas","_setSVGTextLineBg","_setSVGTextLineText","_createTextCharSpan","char","styleDecl","styleProps","getSvgSpanStyles","trim","match","fillStyles","dy","deltaY","dySpan","toFixed","config","NUM_FRACTION_DIGITS","escapeXml","lineIndex","lineHeight","isJustify","textAlign","includes","JUSTIFY","line","actualStyle","nextStyle","charsToRender","charBox","style","boxWidth","timeToRender","_fontSizeFraction","charSpacing","__charBounds","kernedWidth","_reSpaceAndTab","test","getCompleteStyleDeclaration","hasStyleChanged","_getStyleDeclaration","leftOffset","heightOfLine","boxStart","currentColor","lastColor","getValueOfPropertyAt","j","_getSVGLineTopOffset","lineTopOffset","lastHeight","offset","_fontSizeMult","skipShadow","useWhiteSpace","strokeWidth","stroke","fill","colorPropToSVG","filter","decoration"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TextSVGExportMixin.mjs","sources":["../../../../src/shapes/Text/TextSVGExportMixin.ts"],"sourcesContent":["import { config } from '../../config';\nimport type { TSVGReviver } from '../../typedefs';\nimport { escapeXml } from '../../util/lang_string';\nimport { colorPropToSVG, createSVGRect } from '../../util/misc/svgParsing';\nimport { hasStyleChanged } from '../../util/misc/textStyles';\nimport { toFixed } from '../../util/misc/toFixed';\nimport { FabricObjectSVGExportMixin } from '../Object/FabricObjectSVGExportMixin';\nimport { type TextStyleDeclaration } from './StyledText';\nimport { JUSTIFY } from '../Text/constants';\nimport type { FabricText } from './Text';\nimport { STROKE, FILL } from '../../constants';\n\nconst multipleSpacesRegex = / +/g;\nconst dblQuoteRegex = /\"/g;\n\nfunction createSVGInlineRect(\n color: string,\n left: number,\n top: number,\n width: number,\n height: number\n) {\n return `\\t\\t${createSVGRect(color, { left, top, width, height })}\\n`;\n}\n\nexport class TextSVGExportMixin extends FabricObjectSVGExportMixin {\n _toSVG(this: TextSVGExportMixin & FabricText): string[] {\n const offsets = this._getSVGLeftTopOffsets(),\n textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);\n return this._wrapSVGTextAndBg(textAndBg);\n }\n\n toSVG(this: TextSVGExportMixin & FabricText, reviver?: TSVGReviver): string {\n return this._createBaseSVGMarkup(this._toSVG(), {\n reviver,\n noStyle: true,\n withShadow: true,\n });\n }\n\n private _getSVGLeftTopOffsets(this: TextSVGExportMixin & FabricText) {\n return {\n textLeft: -this.width / 2,\n textTop: -this.height / 2,\n lineTop: this.getHeightOfLine(0),\n };\n }\n\n private _wrapSVGTextAndBg(\n this: TextSVGExportMixin & FabricText,\n {\n textBgRects,\n textSpans,\n }: {\n textSpans: string[];\n textBgRects: string[];\n }\n ) {\n const noShadow = true,\n textDecoration = this.getSvgTextDecoration(this);\n return [\n textBgRects.join(''),\n '\\t\\t<text xml:space=\"preserve\" ',\n this.fontFamily\n ? `font-family=\"${this.fontFamily.replace(dblQuoteRegex, \"'\")}\" `\n : '',\n this.fontSize ? `font-size=\"${this.fontSize}\" ` : '',\n this.fontStyle ? `font-style=\"${this.fontStyle}\" ` : '',\n this.fontWeight ? `font-weight=\"${this.fontWeight}\" ` : '',\n textDecoration ? `text-decoration=\"${textDecoration}\" ` : '',\n this.direction === 'rtl' ? `direction=\"${this.direction}\" ` : '',\n 'style=\"',\n this.getSvgStyles(noShadow),\n '\"',\n this.addPaintOrder(),\n ' >',\n textSpans.join(''),\n '</text>\\n',\n ];\n }\n\n /**\n * @private\n * @param {Number} textTopOffset Text top offset\n * @param {Number} textLeftOffset Text left offset\n * @return {Object}\n */\n private _getSVGTextAndBg(\n this: TextSVGExportMixin & FabricText,\n textTopOffset: number,\n textLeftOffset: number\n ) {\n const textSpans: string[] = [],\n textBgRects: string[] = [];\n let height = textTopOffset,\n lineOffset;\n\n // bounding-box background\n this.backgroundColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n this.backgroundColor,\n -this.width / 2,\n -this.height / 2,\n this.width,\n this.height\n )\n );\n\n // text and text-background\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n lineOffset = this._getLineLeftOffset(i);\n if (this.direction === 'rtl') {\n lineOffset += this.width;\n }\n if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) {\n this._setSVGTextLineBg(\n textBgRects,\n i,\n textLeftOffset + lineOffset,\n height\n );\n }\n this._setSVGTextLineText(\n textSpans,\n i,\n textLeftOffset + lineOffset,\n height\n );\n height += this.getHeightOfLine(i);\n }\n\n return {\n textSpans,\n textBgRects,\n };\n }\n\n private _createTextCharSpan(\n this: TextSVGExportMixin & FabricText,\n char: string,\n styleDecl: TextStyleDeclaration,\n left: number,\n top: number\n ) {\n const styleProps = this.getSvgSpanStyles(\n styleDecl,\n char !== char.trim() || !!char.match(multipleSpacesRegex)\n ),\n fillStyles = styleProps ? `style=\"${styleProps}\"` : '',\n dy = styleDecl.deltaY,\n dySpan = dy ? ` dy=\"${toFixed(dy, config.NUM_FRACTION_DIGITS)}\" ` : '';\n\n return `<tspan x=\"${toFixed(\n left,\n config.NUM_FRACTION_DIGITS\n )}\" y=\"${toFixed(\n top,\n config.NUM_FRACTION_DIGITS\n )}\" ${dySpan}${fillStyles}>${escapeXml(char)}</tspan>`;\n }\n\n private _setSVGTextLineText(\n this: TextSVGExportMixin & FabricText,\n textSpans: string[],\n lineIndex: number,\n textLeftOffset: number,\n textTopOffset: number\n ) {\n const lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.includes(JUSTIFY),\n line = this._textLines[lineIndex];\n let actualStyle,\n nextStyle,\n charsToRender = '',\n charBox,\n style,\n boxWidth = 0,\n timeToRender;\n\n textTopOffset +=\n (lineHeight * (1 - this._fontSizeFraction)) / this.lineHeight;\n for (let i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i];\n if (boxWidth === 0) {\n textLeftOffset += charBox.kernedWidth - charBox.width;\n boxWidth += charBox.width;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle =\n actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = hasStyleChanged(actualStyle, nextStyle, true);\n }\n if (timeToRender) {\n style = this._getStyleDeclaration(lineIndex, i);\n textSpans.push(\n this._createTextCharSpan(\n charsToRender,\n style,\n textLeftOffset,\n textTopOffset\n )\n );\n charsToRender = '';\n actualStyle = nextStyle;\n if (this.direction === 'rtl') {\n textLeftOffset -= boxWidth;\n } else {\n textLeftOffset += boxWidth;\n }\n boxWidth = 0;\n }\n }\n }\n\n private _setSVGTextLineBg(\n this: TextSVGExportMixin & FabricText,\n textBgRects: (string | number)[],\n i: number,\n leftOffset: number,\n textTopOffset: number\n ) {\n const line = this._textLines[i],\n heightOfLine = this.getHeightOfLine(i) / this.lineHeight;\n let boxWidth = 0,\n boxStart = 0,\n currentColor,\n lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n for (let j = 0; j < line.length; j++) {\n const { left, width, kernedWidth } = this.__charBounds[i][j];\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n if (currentColor !== lastColor) {\n lastColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n lastColor,\n leftOffset + boxStart,\n textTopOffset,\n boxWidth,\n heightOfLine\n )\n );\n boxStart = left;\n boxWidth = width;\n lastColor = currentColor;\n } else {\n boxWidth += kernedWidth;\n }\n }\n currentColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n lastColor,\n leftOffset + boxStart,\n textTopOffset,\n boxWidth,\n heightOfLine\n )\n );\n }\n\n /**\n * @deprecated unused\n */\n _getSVGLineTopOffset(\n this: TextSVGExportMixin & FabricText,\n lineIndex: number\n ) {\n let lineTopOffset = 0,\n j;\n for (j = 0; j < lineIndex; j++) {\n lineTopOffset += this.getHeightOfLine(j);\n }\n const lastHeight = this.getHeightOfLine(j);\n return {\n lineTop: lineTopOffset,\n offset:\n ((this._fontSizeMult - this._fontSizeFraction) * lastHeight) /\n (this.lineHeight * this._fontSizeMult),\n };\n }\n\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles(this: TextSVGExportMixin & FabricText, skipShadow?: boolean) {\n // cant use ts-expect-error because of ts 5.3 cross check\n // @ts-ignore TS doesn't respect this type casting\n return `${super.getSvgStyles(skipShadow)} white-space: pre;`;\n }\n\n /**\n * Returns styles-string for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style.\n * @return {String}\n */\n getSvgSpanStyles(\n this: TextSVGExportMixin & FabricText,\n style: TextStyleDeclaration,\n useWhiteSpace?: boolean\n ) {\n const {\n fontFamily,\n strokeWidth,\n stroke,\n fill,\n fontSize,\n fontStyle,\n fontWeight,\n deltaY,\n } = style;\n\n const textDecoration = this.getSvgTextDecoration(style);\n\n return [\n stroke ? colorPropToSVG(STROKE, stroke) : '',\n strokeWidth ? `stroke-width: ${strokeWidth}; ` : '',\n fontFamily\n ? `font-family: ${\n !fontFamily.includes(\"'\") && !fontFamily.includes('\"')\n ? `'${fontFamily}'`\n : fontFamily\n }; `\n : '',\n fontSize ? `font-size: ${fontSize}px; ` : '',\n fontStyle ? `font-style: ${fontStyle}; ` : '',\n fontWeight ? `font-weight: ${fontWeight}; ` : '',\n textDecoration ? `text-decoration: ${textDecoration}; ` : textDecoration,\n fill ? colorPropToSVG(FILL, fill) : '',\n deltaY ? `baseline-shift: ${-deltaY}; ` : '',\n useWhiteSpace ? 'white-space: pre; ' : '',\n ].join('');\n }\n\n /**\n * Returns text-decoration property for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @return {String}\n */\n getSvgTextDecoration(\n this: TextSVGExportMixin & FabricText,\n style: TextStyleDeclaration\n ) {\n return (['overline', 'underline', 'line-through'] as const)\n .filter(\n (decoration) =>\n style[\n decoration.replace('-', '') as\n | 'overline'\n | 'underline'\n | 'linethrough'\n ]\n )\n .join(' ');\n }\n}\n"],"names":["multipleSpacesRegex","dblQuoteRegex","createSVGInlineRect","color","left","top","width","height","concat","createSVGRect","TextSVGExportMixin","FabricObjectSVGExportMixin","_toSVG","offsets","_getSVGLeftTopOffsets","textAndBg","_getSVGTextAndBg","textTop","textLeft","_wrapSVGTextAndBg","toSVG","reviver","_createBaseSVGMarkup","noStyle","withShadow","lineTop","getHeightOfLine","_ref","textBgRects","textSpans","noShadow","textDecoration","getSvgTextDecoration","join","fontFamily","replace","fontSize","fontStyle","fontWeight","direction","getSvgStyles","addPaintOrder","textTopOffset","textLeftOffset","lineOffset","backgroundColor","push","i","len","_textLines","length","_getLineLeftOffset","textBackgroundColor","styleHas","_setSVGTextLineBg","_setSVGTextLineText","_createTextCharSpan","char","styleDecl","styleProps","getSvgSpanStyles","trim","match","fillStyles","dy","deltaY","dySpan","toFixed","config","NUM_FRACTION_DIGITS","escapeXml","lineIndex","lineHeight","isJustify","textAlign","includes","JUSTIFY","line","actualStyle","nextStyle","charsToRender","charBox","style","boxWidth","timeToRender","_fontSizeFraction","charSpacing","__charBounds","kernedWidth","_reSpaceAndTab","test","getCompleteStyleDeclaration","hasStyleChanged","_getStyleDeclaration","leftOffset","heightOfLine","boxStart","currentColor","lastColor","getValueOfPropertyAt","j","_getSVGLineTopOffset","lineTopOffset","lastHeight","offset","_fontSizeMult","skipShadow","useWhiteSpace","strokeWidth","stroke","fill","colorPropToSVG","STROKE","FILL","filter","decoration"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{STROKE as t,FILL as e,reNewline as i,LEFT as n}from"../../constants.min.mjs";const o=["fontSize","fontWeight","fontFamily","fontStyle"],r=["underline","overline","linethrough"],l=[...o,"lineHeight","text","charSpacing","textAlign","styles","path","pathStartOffset","pathSide","pathAlign"],a=[...l,...r,"textBackgroundColor","direction"],s=[...o,...r,t,"strokeWidth",e,"deltaY","textBackgroundColor"],h={_reNewline:i,_reSpacesAndTabs:/[ \t\r]/g,_reSpaceAndTab:/[ \t\r]/,_reWords:/\S+/g,fontSize:40,fontWeight:"normal",fontFamily:"Times New Roman",underline:!1,overline:!1,linethrough:!1,textAlign:n,fontStyle:"normal",lineHeight:1.16,superscript:{size:.6,baseline:-.35},subscript:{size:.6,baseline:.11},textBackgroundColor:"",stroke:null,shadow:null,path:void 0,pathStartOffset:0,pathSide:n,pathAlign:"baseline",_fontSizeFraction:.222,offsets:{underline:.1,linethrough:-.315,overline:-.88},_fontSizeMult:1.13,charSpacing:0,deltaY:0,direction:"ltr",CACHE_FONT_SIZE:400,MIN_TEXT_WIDTH:2},f="justify",g="justify-left",d="justify-right",u="justify-center";export{f as JUSTIFY,u as JUSTIFY_CENTER,g as JUSTIFY_LEFT,d as JUSTIFY_RIGHT,a as additionalProps,s as styleProperties,r as textDecorationProperties,h as textDefaultValues,l as textLayoutProperties};
|
|
2
2
|
//# sourceMappingURL=constants.min.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.min.mjs","sources":["../../../../src/shapes/Text/constants.ts"],"sourcesContent":["import { LEFT, reNewline } from '../../constants';\nimport type { TClassProperties } from '../../typedefs';\nimport type { FabricText } from './Text';\n\nconst fontProperties = [\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'fontStyle',\n] as const;\n\nexport const textDecorationProperties = [\n 'underline',\n 'overline',\n 'linethrough',\n] as const;\n\nexport const textLayoutProperties: string[] = [\n ...fontProperties,\n 'lineHeight',\n 'text',\n 'charSpacing',\n 'textAlign',\n 'styles',\n 'path',\n 'pathStartOffset',\n 'pathSide',\n 'pathAlign',\n];\n\nexport const additionalProps = [\n ...textLayoutProperties,\n ...textDecorationProperties,\n 'textBackgroundColor',\n 'direction',\n] as const;\n\nexport type StylePropertiesType =\n | 'fill'\n | 'stroke'\n | 'strokeWidth'\n | 'fontSize'\n | 'fontFamily'\n | 'fontWeight'\n | 'fontStyle'\n | 'textBackgroundColor'\n | 'deltaY'\n | 'overline'\n | 'underline'\n | 'linethrough';\n\nexport const styleProperties: Readonly<StylePropertiesType[]> = [\n ...fontProperties,\n ...textDecorationProperties,\n
|
|
1
|
+
{"version":3,"file":"constants.min.mjs","sources":["../../../../src/shapes/Text/constants.ts"],"sourcesContent":["import { FILL, LEFT, STROKE, reNewline } from '../../constants';\nimport type { TClassProperties } from '../../typedefs';\nimport type { FabricText } from './Text';\n\nconst fontProperties = [\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'fontStyle',\n] as const;\n\nexport const textDecorationProperties = [\n 'underline',\n 'overline',\n 'linethrough',\n] as const;\n\nexport const textLayoutProperties: string[] = [\n ...fontProperties,\n 'lineHeight',\n 'text',\n 'charSpacing',\n 'textAlign',\n 'styles',\n 'path',\n 'pathStartOffset',\n 'pathSide',\n 'pathAlign',\n];\n\nexport const additionalProps = [\n ...textLayoutProperties,\n ...textDecorationProperties,\n 'textBackgroundColor',\n 'direction',\n] as const;\n\nexport type StylePropertiesType =\n | 'fill'\n | 'stroke'\n | 'strokeWidth'\n | 'fontSize'\n | 'fontFamily'\n | 'fontWeight'\n | 'fontStyle'\n | 'textBackgroundColor'\n | 'deltaY'\n | 'overline'\n | 'underline'\n | 'linethrough';\n\nexport const styleProperties: Readonly<StylePropertiesType[]> = [\n ...fontProperties,\n ...textDecorationProperties,\n STROKE,\n 'strokeWidth',\n FILL,\n 'deltaY',\n 'textBackgroundColor',\n] as const;\n\n// @TODO: Many things here are configuration related and shouldn't be on the class nor prototype\n// regexes, list of properties that are not suppose to change by instances, magic consts.\n// this will be a separated effort\nexport const textDefaultValues: Partial<TClassProperties<FabricText>> = {\n _reNewline: reNewline,\n _reSpacesAndTabs: /[ \\t\\r]/g,\n _reSpaceAndTab: /[ \\t\\r]/,\n _reWords: /\\S+/g,\n fontSize: 40,\n fontWeight: 'normal',\n fontFamily: 'Times New Roman',\n underline: false,\n overline: false,\n linethrough: false,\n textAlign: LEFT,\n fontStyle: 'normal',\n lineHeight: 1.16,\n superscript: {\n size: 0.6, // fontSize factor\n baseline: -0.35, // baseline-shift factor (upwards)\n },\n subscript: {\n size: 0.6, // fontSize factor\n baseline: 0.11, // baseline-shift factor (downwards)\n },\n textBackgroundColor: '',\n stroke: null,\n shadow: null,\n path: undefined,\n pathStartOffset: 0,\n pathSide: LEFT,\n pathAlign: 'baseline',\n _fontSizeFraction: 0.222,\n offsets: {\n underline: 0.1,\n linethrough: -0.315,\n overline: -0.88,\n },\n _fontSizeMult: 1.13,\n charSpacing: 0,\n deltaY: 0,\n direction: 'ltr',\n CACHE_FONT_SIZE: 400,\n MIN_TEXT_WIDTH: 2,\n};\n\nexport const JUSTIFY = 'justify';\nexport const JUSTIFY_LEFT = 'justify-left';\nexport const JUSTIFY_RIGHT = 'justify-right';\nexport const JUSTIFY_CENTER = 'justify-center';\n"],"names":["fontProperties","textDecorationProperties","textLayoutProperties","additionalProps","styleProperties","STROKE","FILL","textDefaultValues","_reNewline","reNewline","_reSpacesAndTabs","_reSpaceAndTab","_reWords","fontSize","fontWeight","fontFamily","underline","overline","linethrough","textAlign","LEFT","fontStyle","lineHeight","superscript","size","baseline","subscript","textBackgroundColor","stroke","shadow","path","undefined","pathStartOffset","pathSide","pathAlign","_fontSizeFraction","offsets","_fontSizeMult","charSpacing","deltaY","direction","CACHE_FONT_SIZE","MIN_TEXT_WIDTH","JUSTIFY","JUSTIFY_LEFT","JUSTIFY_RIGHT","JUSTIFY_CENTER"],"mappings":"oFAIA,MAAMA,EAAiB,CACrB,WACA,aACA,aACA,aAGWC,EAA2B,CACtC,YACA,WACA,eAGWC,EAAiC,IACzCF,EACH,aACA,OACA,cACA,YACA,SACA,OACA,kBACA,WACA,aAGWG,EAAkB,IAC1BD,KACAD,EACH,sBACA,aAiBWG,EAAmD,IAC3DJ,KACAC,EACHI,EACA,cACAC,EACA,SACA,uBAMWC,EAA2D,CACtEC,WAAYC,EACZC,iBAAkB,WAClBC,eAAgB,UAChBC,SAAU,OACVC,SAAU,GACVC,WAAY,SACZC,WAAY,kBACZC,WAAW,EACXC,UAAU,EACVC,aAAa,EACbC,UAAWC,EACXC,UAAW,SACXC,WAAY,KACZC,YAAa,CACXC,KAAM,GACNC,UAAW,KAEbC,UAAW,CACTF,KAAM,GACNC,SAAU,KAEZE,oBAAqB,GACrBC,OAAQ,KACRC,OAAQ,KACRC,UAAMC,EACNC,gBAAiB,EACjBC,SAAUb,EACVc,UAAW,WACXC,kBAAmB,KACnBC,QAAS,CACPpB,UAAW,GACXE,aAAc,KACdD,UAAW,KAEboB,cAAe,KACfC,YAAa,EACbC,OAAQ,EACRC,UAAW,MACXC,gBAAiB,IACjBC,eAAgB,GAGLC,EAAU,UACVC,EAAe,eACfC,EAAgB,gBAChBC,EAAiB"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { reNewline, LEFT } from '../../constants.mjs';
|
|
1
|
+
import { STROKE, FILL, reNewline, LEFT } from '../../constants.mjs';
|
|
2
2
|
|
|
3
3
|
const fontProperties = ['fontSize', 'fontWeight', 'fontFamily', 'fontStyle'];
|
|
4
4
|
const textDecorationProperties = ['underline', 'overline', 'linethrough'];
|
|
5
5
|
const textLayoutProperties = [...fontProperties, 'lineHeight', 'text', 'charSpacing', 'textAlign', 'styles', 'path', 'pathStartOffset', 'pathSide', 'pathAlign'];
|
|
6
6
|
const additionalProps = [...textLayoutProperties, ...textDecorationProperties, 'textBackgroundColor', 'direction'];
|
|
7
|
-
const styleProperties = [...fontProperties, ...textDecorationProperties,
|
|
7
|
+
const styleProperties = [...fontProperties, ...textDecorationProperties, STROKE, 'strokeWidth', FILL, 'deltaY', 'textBackgroundColor'];
|
|
8
8
|
|
|
9
9
|
// @TODO: Many things here are configuration related and shouldn't be on the class nor prototype
|
|
10
10
|
// regexes, list of properties that are not suppose to change by instances, magic consts.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.mjs","sources":["../../../../src/shapes/Text/constants.ts"],"sourcesContent":["import { LEFT, reNewline } from '../../constants';\nimport type { TClassProperties } from '../../typedefs';\nimport type { FabricText } from './Text';\n\nconst fontProperties = [\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'fontStyle',\n] as const;\n\nexport const textDecorationProperties = [\n 'underline',\n 'overline',\n 'linethrough',\n] as const;\n\nexport const textLayoutProperties: string[] = [\n ...fontProperties,\n 'lineHeight',\n 'text',\n 'charSpacing',\n 'textAlign',\n 'styles',\n 'path',\n 'pathStartOffset',\n 'pathSide',\n 'pathAlign',\n];\n\nexport const additionalProps = [\n ...textLayoutProperties,\n ...textDecorationProperties,\n 'textBackgroundColor',\n 'direction',\n] as const;\n\nexport type StylePropertiesType =\n | 'fill'\n | 'stroke'\n | 'strokeWidth'\n | 'fontSize'\n | 'fontFamily'\n | 'fontWeight'\n | 'fontStyle'\n | 'textBackgroundColor'\n | 'deltaY'\n | 'overline'\n | 'underline'\n | 'linethrough';\n\nexport const styleProperties: Readonly<StylePropertiesType[]> = [\n ...fontProperties,\n ...textDecorationProperties,\n
|
|
1
|
+
{"version":3,"file":"constants.mjs","sources":["../../../../src/shapes/Text/constants.ts"],"sourcesContent":["import { FILL, LEFT, STROKE, reNewline } from '../../constants';\nimport type { TClassProperties } from '../../typedefs';\nimport type { FabricText } from './Text';\n\nconst fontProperties = [\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'fontStyle',\n] as const;\n\nexport const textDecorationProperties = [\n 'underline',\n 'overline',\n 'linethrough',\n] as const;\n\nexport const textLayoutProperties: string[] = [\n ...fontProperties,\n 'lineHeight',\n 'text',\n 'charSpacing',\n 'textAlign',\n 'styles',\n 'path',\n 'pathStartOffset',\n 'pathSide',\n 'pathAlign',\n];\n\nexport const additionalProps = [\n ...textLayoutProperties,\n ...textDecorationProperties,\n 'textBackgroundColor',\n 'direction',\n] as const;\n\nexport type StylePropertiesType =\n | 'fill'\n | 'stroke'\n | 'strokeWidth'\n | 'fontSize'\n | 'fontFamily'\n | 'fontWeight'\n | 'fontStyle'\n | 'textBackgroundColor'\n | 'deltaY'\n | 'overline'\n | 'underline'\n | 'linethrough';\n\nexport const styleProperties: Readonly<StylePropertiesType[]> = [\n ...fontProperties,\n ...textDecorationProperties,\n STROKE,\n 'strokeWidth',\n FILL,\n 'deltaY',\n 'textBackgroundColor',\n] as const;\n\n// @TODO: Many things here are configuration related and shouldn't be on the class nor prototype\n// regexes, list of properties that are not suppose to change by instances, magic consts.\n// this will be a separated effort\nexport const textDefaultValues: Partial<TClassProperties<FabricText>> = {\n _reNewline: reNewline,\n _reSpacesAndTabs: /[ \\t\\r]/g,\n _reSpaceAndTab: /[ \\t\\r]/,\n _reWords: /\\S+/g,\n fontSize: 40,\n fontWeight: 'normal',\n fontFamily: 'Times New Roman',\n underline: false,\n overline: false,\n linethrough: false,\n textAlign: LEFT,\n fontStyle: 'normal',\n lineHeight: 1.16,\n superscript: {\n size: 0.6, // fontSize factor\n baseline: -0.35, // baseline-shift factor (upwards)\n },\n subscript: {\n size: 0.6, // fontSize factor\n baseline: 0.11, // baseline-shift factor (downwards)\n },\n textBackgroundColor: '',\n stroke: null,\n shadow: null,\n path: undefined,\n pathStartOffset: 0,\n pathSide: LEFT,\n pathAlign: 'baseline',\n _fontSizeFraction: 0.222,\n offsets: {\n underline: 0.1,\n linethrough: -0.315,\n overline: -0.88,\n },\n _fontSizeMult: 1.13,\n charSpacing: 0,\n deltaY: 0,\n direction: 'ltr',\n CACHE_FONT_SIZE: 400,\n MIN_TEXT_WIDTH: 2,\n};\n\nexport const JUSTIFY = 'justify';\nexport const JUSTIFY_LEFT = 'justify-left';\nexport const JUSTIFY_RIGHT = 'justify-right';\nexport const JUSTIFY_CENTER = 'justify-center';\n"],"names":["fontProperties","textDecorationProperties","textLayoutProperties","additionalProps","styleProperties","STROKE","FILL","textDefaultValues","_reNewline","reNewline","_reSpacesAndTabs","_reSpaceAndTab","_reWords","fontSize","fontWeight","fontFamily","underline","overline","linethrough","textAlign","LEFT","fontStyle","lineHeight","superscript","size","baseline","subscript","textBackgroundColor","stroke","shadow","path","undefined","pathStartOffset","pathSide","pathAlign","_fontSizeFraction","offsets","_fontSizeMult","charSpacing","deltaY","direction","CACHE_FONT_SIZE","MIN_TEXT_WIDTH","JUSTIFY","JUSTIFY_LEFT","JUSTIFY_RIGHT","JUSTIFY_CENTER"],"mappings":";;AAIA,MAAMA,cAAc,GAAG,CACrB,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,CACH,CAAA;AAEH,MAAMC,wBAAwB,GAAG,CACtC,WAAW,EACX,UAAU,EACV,aAAa,EACL;AAEH,MAAMC,oBAA8B,GAAG,CAC5C,GAAGF,cAAc,EACjB,YAAY,EACZ,MAAM,EACN,aAAa,EACb,WAAW,EACX,QAAQ,EACR,MAAM,EACN,iBAAiB,EACjB,UAAU,EACV,WAAW,EACZ;AAEYG,MAAAA,eAAe,GAAG,CAC7B,GAAGD,oBAAoB,EACvB,GAAGD,wBAAwB,EAC3B,qBAAqB,EACrB,WAAW,EACH;MAgBGG,eAAgD,GAAG,CAC9D,GAAGJ,cAAc,EACjB,GAAGC,wBAAwB,EAC3BI,MAAM,EACN,aAAa,EACbC,IAAI,EACJ,QAAQ,EACR,qBAAqB,EACb;;AAEV;AACA;AACA;AACO,MAAMC,iBAAwD,GAAG;AACtEC,EAAAA,UAAU,EAAEC,SAAS;AACrBC,EAAAA,gBAAgB,EAAE,UAAU;AAC5BC,EAAAA,cAAc,EAAE,SAAS;AACzBC,EAAAA,QAAQ,EAAE,MAAM;AAChBC,EAAAA,QAAQ,EAAE,EAAE;AACZC,EAAAA,UAAU,EAAE,QAAQ;AACpBC,EAAAA,UAAU,EAAE,iBAAiB;AAC7BC,EAAAA,SAAS,EAAE,KAAK;AAChBC,EAAAA,QAAQ,EAAE,KAAK;AACfC,EAAAA,WAAW,EAAE,KAAK;AAClBC,EAAAA,SAAS,EAAEC,IAAI;AACfC,EAAAA,SAAS,EAAE,QAAQ;AACnBC,EAAAA,UAAU,EAAE,IAAI;AAChBC,EAAAA,WAAW,EAAE;AACXC,IAAAA,IAAI,EAAE,GAAG;AAAE;IACXC,QAAQ,EAAE,CAAC,IAAI;GAChB;AACDC,EAAAA,SAAS,EAAE;AACTF,IAAAA,IAAI,EAAE,GAAG;AAAE;IACXC,QAAQ,EAAE,IAAI;GACf;AACDE,EAAAA,mBAAmB,EAAE,EAAE;AACvBC,EAAAA,MAAM,EAAE,IAAI;AACZC,EAAAA,MAAM,EAAE,IAAI;AACZC,EAAAA,IAAI,EAAEC,SAAS;AACfC,EAAAA,eAAe,EAAE,CAAC;AAClBC,EAAAA,QAAQ,EAAEb,IAAI;AACdc,EAAAA,SAAS,EAAE,UAAU;AACrBC,EAAAA,iBAAiB,EAAE,KAAK;AACxBC,EAAAA,OAAO,EAAE;AACPpB,IAAAA,SAAS,EAAE,GAAG;IACdE,WAAW,EAAE,CAAC,KAAK;AACnBD,IAAAA,QAAQ,EAAE,CAAC,IAAA;GACZ;AACDoB,EAAAA,aAAa,EAAE,IAAI;AACnBC,EAAAA,WAAW,EAAE,CAAC;AACdC,EAAAA,MAAM,EAAE,CAAC;AACTC,EAAAA,SAAS,EAAE,KAAK;AAChBC,EAAAA,eAAe,EAAE,GAAG;AACpBC,EAAAA,cAAc,EAAE,CAAA;AAClB,EAAC;AAEM,MAAMC,OAAO,GAAG,UAAS;AACzB,MAAMC,YAAY,GAAG,eAAc;AACnC,MAAMC,aAAa,GAAG,gBAAe;AACrC,MAAMC,cAAc,GAAG;;;;"}
|
|
@@ -24,6 +24,7 @@ export type EnlivenObjectOptions = Abortable & {
|
|
|
24
24
|
reviver?: <T extends BaseFabricObject | FabricObject | BaseFilter<string> | Shadow | TFiller>(serializedObj: Record<string, any>, instance: T) => void;
|
|
25
25
|
};
|
|
26
26
|
/**
|
|
27
|
+
* @TODO type this correctly.
|
|
27
28
|
* Creates corresponding fabric instances from their object representations
|
|
28
29
|
* @param {Object[]} objects Objects to enliven
|
|
29
30
|
* @param {EnlivenObjectOptions} [options]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"objectEnlive.d.ts","sourceRoot":"","sources":["../../../../src/util/misc/objectEnlive.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,KAAK,EACV,SAAS,EAET,YAAY,EACZ,OAAO,EACR,MAAM,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG;IACzC;;OAEG;IACH,WAAW,CAAC,EAAE,YAAY,CAAC;CAC5B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,SAAS,QACf,MAAM,4BACqB,gBAAgB,8BA+B9C,CAAC;AAEL,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG;IAC7C;;;OAGG;IACH,OAAO,CAAC,EAAE,CACR,CAAC,SACG,gBAAgB,GAChB,YAAY,GACZ,UAAU,CAAC,MAAM,CAAC,GAClB,MAAM,GACN,OAAO,EAEX,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAClC,QAAQ,EAAE,CAAC,KACR,IAAI,CAAC;CACX,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"objectEnlive.d.ts","sourceRoot":"","sources":["../../../../src/util/misc/objectEnlive.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,KAAK,EACV,SAAS,EAET,YAAY,EACZ,OAAO,EACR,MAAM,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG;IACzC;;OAEG;IACH,WAAW,CAAC,EAAE,YAAY,CAAC;CAC5B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,SAAS,QACf,MAAM,4BACqB,gBAAgB,8BA+B9C,CAAC;AAEL,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG;IAC7C;;;OAGG;IACH,OAAO,CAAC,EAAE,CACR,CAAC,SACG,gBAAgB,GAChB,YAAY,GACZ,UAAU,CAAC,MAAM,CAAC,GAClB,MAAM,GACN,OAAO,EAEX,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAClC,QAAQ,EAAE,CAAC,KACR,IAAI,CAAC;CACX,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,wYAQhB,GAAG,EAAE,wBACc,oBAAoB,iBAiC9C,CAAC;AAEL;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,6MAGhB,GAAG,eACT,SAAS,eAkDnB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"objectEnlive.min.mjs","sources":["../../../../src/util/misc/objectEnlive.ts"],"sourcesContent":["import { noop } from '../../constants';\nimport type { Pattern } from '../../Pattern';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport type {\n Abortable,\n Constructor,\n TCrossOrigin,\n TFiller,\n} from '../../typedefs';\nimport { createImage } from './dom';\nimport { classRegistry } from '../../ClassRegistry';\nimport type { BaseFilter } from '../../filters/BaseFilter';\nimport type { FabricObject as BaseFabricObject } from '../../shapes/Object/Object';\nimport { FabricError, SignalAbortedError } from '../internals/console';\nimport type { Shadow } from '../../Shadow';\n\nexport type LoadImageOptions = Abortable & {\n /**\n * cors value for the image loading, default to anonymous\n */\n crossOrigin?: TCrossOrigin;\n};\n\n/**\n * Loads image element from given url and resolve it, or catch.\n * @param {String} url URL representing an image\n * @param {LoadImageOptions} [options] image loading options\n * @returns {Promise<HTMLImageElement>} the loaded image.\n */\nexport const loadImage = (\n url: string,\n { signal, crossOrigin = null }: LoadImageOptions = {}\n) =>\n new Promise<HTMLImageElement>(function (resolve, reject) {\n if (signal && signal.aborted) {\n return reject(new SignalAbortedError('loadImage'));\n }\n const img = createImage();\n let abort: EventListenerOrEventListenerObject;\n if (signal) {\n abort = function (err: Event) {\n img.src = '';\n reject(err);\n };\n signal.addEventListener('abort', abort, { once: true });\n }\n const done = function () {\n img.onload = img.onerror = null;\n abort && signal?.removeEventListener('abort', abort);\n resolve(img);\n };\n if (!url) {\n done();\n return;\n }\n img.onload = done;\n img.onerror = function () {\n abort && signal?.removeEventListener('abort', abort);\n reject(new FabricError(`Error loading ${img.src}`));\n };\n crossOrigin && (img.crossOrigin = crossOrigin);\n img.src = url;\n });\n\nexport type EnlivenObjectOptions = Abortable & {\n /**\n * Method for further parsing of object elements,\n * called after each fabric object created.\n */\n reviver?: <\n T extends\n | BaseFabricObject\n | FabricObject\n | BaseFilter<string>\n | Shadow\n | TFiller\n >(\n serializedObj: Record<string, any>,\n instance: T\n ) => void;\n};\n\n/**\n * Creates corresponding fabric instances from their object representations\n * @param {Object[]} objects Objects to enliven\n * @param {EnlivenObjectOptions} [options]\n * @param {(serializedObj: object, instance: FabricObject) => any} [options.reviver] Method for further parsing of object elements,\n * called after each fabric object created.\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise<FabricObject[]>}\n */\nexport const enlivenObjects = <\n T extends\n | BaseFabricObject\n | FabricObject\n | BaseFilter<string>\n | Shadow\n | TFiller\n>(\n objects: any[],\n { signal, reviver = noop }: EnlivenObjectOptions = {}\n) =>\n new Promise<T[]>((resolve, reject) => {\n const instances: T[] = [];\n signal && signal.addEventListener('abort', reject, { once: true });\n Promise.all(\n objects.map((obj) =>\n classRegistry\n .getClass<\n Constructor<T> & {\n fromObject(options: any, context: Abortable): Promise<T>;\n }\n >(obj.type)\n .fromObject(obj, { signal })\n .then((fabricInstance) => {\n reviver(obj, fabricInstance);\n instances.push(fabricInstance);\n return fabricInstance;\n })\n )\n )\n .then(resolve)\n .catch((error) => {\n // cleanup\n instances.forEach((instance) => {\n (instance as FabricObject).dispose &&\n (instance as FabricObject).dispose();\n });\n reject(error);\n })\n .finally(() => {\n signal && signal.removeEventListener('abort', reject);\n });\n });\n\n/**\n * Creates corresponding fabric instances residing in an object, e.g. `clipPath`\n * @param {Object} object with properties to enlive ( fill, stroke, clipPath, path )\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise<Record<string, FabricObject | TFiller | null>>} the input object with enlived values\n */\nexport const enlivenObjectEnlivables = <\n R = Record<string, FabricObject | TFiller | null>\n>(\n serializedObject: any,\n { signal }: Abortable = {}\n) =>\n new Promise<R>((resolve, reject) => {\n const instances: (FabricObject | TFiller | Shadow)[] = [];\n signal && signal.addEventListener('abort', reject, { once: true });\n // enlive every possible property\n const promises = Object.values(serializedObject).map((value: any) => {\n if (!value) {\n return value;\n }\n // clipPath or shadow or gradient\n if (value.type) {\n return enlivenObjects<FabricObject | Shadow | TFiller>([value], {\n signal,\n }).then(([enlived]) => {\n instances.push(enlived);\n return enlived;\n });\n }\n // pattern\n if (value.source) {\n return classRegistry\n .getClass<typeof Pattern>('pattern')\n .fromObject(value, { signal })\n .then((pattern: Pattern) => {\n instances.push(pattern);\n return pattern;\n });\n }\n return value;\n });\n const keys = Object.keys(serializedObject);\n Promise.all(promises)\n .then((enlived) => {\n return enlived.reduce((acc, instance, index) => {\n acc[keys[index]] = instance;\n return acc;\n }, {});\n })\n .then(resolve)\n .catch((error) => {\n // cleanup\n instances.forEach((instance: any) => {\n instance.dispose && instance.dispose();\n });\n reject(error);\n })\n .finally(() => {\n signal && signal.removeEventListener('abort', reject);\n });\n });\n"],"names":["loadImage","url","signal","crossOrigin","arguments","length","undefined","Promise","resolve","reject","aborted","SignalAbortedError","img","createImage","abort","err","src","addEventListener","once","done","onload","onerror","removeEventListener","FabricError","concat","enlivenObjects","objects","reviver","noop","instances","all","map","obj","classRegistry","getClass","type","fromObject","then","fabricInstance","push","catch","error","forEach","instance","dispose","finally","enlivenObjectEnlivables","serializedObject","promises","Object","values","value","_ref","enlived","source","pattern","keys","reduce","acc","index"],"mappings":"0OA6BaA,MAAAA,EAAY,SACvBC,GAAW,IACXC,OAAEA,EAAMC,YAAEA,EAAc,MAAwBC,UAAAC,OAAAD,QAAAE,IAAAF,UAAAE,GAAAF,UAAG,GAAA,GAAE,OAErD,IAAIG,SAA0B,SAAUC,EAASC,GAC/C,GAAIP,GAAUA,EAAOQ,QACnB,OAAOD,EAAO,IAAIE,EAAmB,cAEvC,MAAMC,EAAMC,IACZ,IAAIC,EACAZ,IACFY,EAAQ,SAAUC,GAChBH,EAAII,IAAM,GACVP,EAAOM,IAETb,EAAOe,iBAAiB,QAASH,EAAO,CAAEI,MAAM,KAElD,MAAMC,EAAO,WACXP,EAAIQ,OAASR,EAAIS,QAAU,KAC3BP,IAASZ,SAAAA,EAAQoB,oBAAoB,QAASR,IAC9CN,EAAQI,IAELX,GAILW,EAAIQ,OAASD,EACbP,EAAIS,QAAU,WACZP,IAASZ,SAAAA,EAAQoB,oBAAoB,QAASR,IAC9CL,EAAO,IAAIc,EAAWC,iBAAAA,OAAkBZ,EAAII,QAE9Cb,IAAgBS,EAAIT,YAAcA,GAClCS,EAAII,IAAMf,GATRkB,GAUJ,GAAE,
|
|
1
|
+
{"version":3,"file":"objectEnlive.min.mjs","sources":["../../../../src/util/misc/objectEnlive.ts"],"sourcesContent":["import { noop } from '../../constants';\nimport type { Pattern } from '../../Pattern';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport type {\n Abortable,\n Constructor,\n TCrossOrigin,\n TFiller,\n} from '../../typedefs';\nimport { createImage } from './dom';\nimport { classRegistry } from '../../ClassRegistry';\nimport type { BaseFilter } from '../../filters/BaseFilter';\nimport type { FabricObject as BaseFabricObject } from '../../shapes/Object/Object';\nimport { FabricError, SignalAbortedError } from '../internals/console';\nimport type { Shadow } from '../../Shadow';\n\nexport type LoadImageOptions = Abortable & {\n /**\n * cors value for the image loading, default to anonymous\n */\n crossOrigin?: TCrossOrigin;\n};\n\n/**\n * Loads image element from given url and resolve it, or catch.\n * @param {String} url URL representing an image\n * @param {LoadImageOptions} [options] image loading options\n * @returns {Promise<HTMLImageElement>} the loaded image.\n */\nexport const loadImage = (\n url: string,\n { signal, crossOrigin = null }: LoadImageOptions = {}\n) =>\n new Promise<HTMLImageElement>(function (resolve, reject) {\n if (signal && signal.aborted) {\n return reject(new SignalAbortedError('loadImage'));\n }\n const img = createImage();\n let abort: EventListenerOrEventListenerObject;\n if (signal) {\n abort = function (err: Event) {\n img.src = '';\n reject(err);\n };\n signal.addEventListener('abort', abort, { once: true });\n }\n const done = function () {\n img.onload = img.onerror = null;\n abort && signal?.removeEventListener('abort', abort);\n resolve(img);\n };\n if (!url) {\n done();\n return;\n }\n img.onload = done;\n img.onerror = function () {\n abort && signal?.removeEventListener('abort', abort);\n reject(new FabricError(`Error loading ${img.src}`));\n };\n crossOrigin && (img.crossOrigin = crossOrigin);\n img.src = url;\n });\n\nexport type EnlivenObjectOptions = Abortable & {\n /**\n * Method for further parsing of object elements,\n * called after each fabric object created.\n */\n reviver?: <\n T extends\n | BaseFabricObject\n | FabricObject\n | BaseFilter<string>\n | Shadow\n | TFiller\n >(\n serializedObj: Record<string, any>,\n instance: T\n ) => void;\n};\n\n/**\n * @TODO type this correctly.\n * Creates corresponding fabric instances from their object representations\n * @param {Object[]} objects Objects to enliven\n * @param {EnlivenObjectOptions} [options]\n * @param {(serializedObj: object, instance: FabricObject) => any} [options.reviver] Method for further parsing of object elements,\n * called after each fabric object created.\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise<FabricObject[]>}\n */\nexport const enlivenObjects = <\n T extends\n | BaseFabricObject\n | FabricObject\n | BaseFilter<string>\n | Shadow\n | TFiller\n>(\n objects: any[],\n { signal, reviver = noop }: EnlivenObjectOptions = {}\n) =>\n new Promise<T[]>((resolve, reject) => {\n const instances: T[] = [];\n signal && signal.addEventListener('abort', reject, { once: true });\n Promise.all(\n objects.map((obj) =>\n classRegistry\n .getClass<\n Constructor<T> & {\n fromObject(options: any, context: Abortable): Promise<T>;\n }\n >(obj.type)\n .fromObject(obj, { signal })\n .then((fabricInstance) => {\n reviver(obj, fabricInstance);\n instances.push(fabricInstance);\n return fabricInstance;\n })\n )\n )\n .then(resolve)\n .catch((error) => {\n // cleanup\n instances.forEach((instance) => {\n (instance as FabricObject).dispose &&\n (instance as FabricObject).dispose();\n });\n reject(error);\n })\n .finally(() => {\n signal && signal.removeEventListener('abort', reject);\n });\n });\n\n/**\n * Creates corresponding fabric instances residing in an object, e.g. `clipPath`\n * @param {Object} object with properties to enlive ( fill, stroke, clipPath, path )\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise<Record<string, FabricObject | TFiller | null>>} the input object with enlived values\n */\nexport const enlivenObjectEnlivables = <\n R = Record<string, FabricObject | TFiller | null>\n>(\n serializedObject: any,\n { signal }: Abortable = {}\n) =>\n new Promise<R>((resolve, reject) => {\n const instances: (FabricObject | TFiller | Shadow)[] = [];\n signal && signal.addEventListener('abort', reject, { once: true });\n // enlive every possible property\n const promises = Object.values(serializedObject).map((value: any) => {\n if (!value) {\n return value;\n }\n // clipPath or shadow or gradient\n if (value.type) {\n return enlivenObjects<FabricObject | Shadow | TFiller>([value], {\n signal,\n }).then(([enlived]) => {\n instances.push(enlived);\n return enlived;\n });\n }\n // pattern\n if (value.source) {\n return classRegistry\n .getClass<typeof Pattern>('pattern')\n .fromObject(value, { signal })\n .then((pattern: Pattern) => {\n instances.push(pattern);\n return pattern;\n });\n }\n return value;\n });\n const keys = Object.keys(serializedObject);\n Promise.all(promises)\n .then((enlived) => {\n return enlived.reduce((acc, instance, index) => {\n acc[keys[index]] = instance;\n return acc;\n }, {});\n })\n .then(resolve)\n .catch((error) => {\n // cleanup\n instances.forEach((instance: any) => {\n instance.dispose && instance.dispose();\n });\n reject(error);\n })\n .finally(() => {\n signal && signal.removeEventListener('abort', reject);\n });\n });\n"],"names":["loadImage","url","signal","crossOrigin","arguments","length","undefined","Promise","resolve","reject","aborted","SignalAbortedError","img","createImage","abort","err","src","addEventListener","once","done","onload","onerror","removeEventListener","FabricError","concat","enlivenObjects","objects","reviver","noop","instances","all","map","obj","classRegistry","getClass","type","fromObject","then","fabricInstance","push","catch","error","forEach","instance","dispose","finally","enlivenObjectEnlivables","serializedObject","promises","Object","values","value","_ref","enlived","source","pattern","keys","reduce","acc","index"],"mappings":"0OA6BaA,MAAAA,EAAY,SACvBC,GAAW,IACXC,OAAEA,EAAMC,YAAEA,EAAc,MAAwBC,UAAAC,OAAAD,QAAAE,IAAAF,UAAAE,GAAAF,UAAG,GAAA,GAAE,OAErD,IAAIG,SAA0B,SAAUC,EAASC,GAC/C,GAAIP,GAAUA,EAAOQ,QACnB,OAAOD,EAAO,IAAIE,EAAmB,cAEvC,MAAMC,EAAMC,IACZ,IAAIC,EACAZ,IACFY,EAAQ,SAAUC,GAChBH,EAAII,IAAM,GACVP,EAAOM,IAETb,EAAOe,iBAAiB,QAASH,EAAO,CAAEI,MAAM,KAElD,MAAMC,EAAO,WACXP,EAAIQ,OAASR,EAAIS,QAAU,KAC3BP,IAASZ,SAAAA,EAAQoB,oBAAoB,QAASR,IAC9CN,EAAQI,IAELX,GAILW,EAAIQ,OAASD,EACbP,EAAIS,QAAU,WACZP,IAASZ,SAAAA,EAAQoB,oBAAoB,QAASR,IAC9CL,EAAO,IAAIc,EAAWC,iBAAAA,OAAkBZ,EAAII,QAE9Cb,IAAgBS,EAAIT,YAAcA,GAClCS,EAAII,IAAMf,GATRkB,GAUJ,GAAE,EA8BSM,EAAiB,SAQ5BC,GAAc,IACdxB,OAAEA,EAAMyB,QAAEA,EAAUC,GAA4BxB,UAAAC,OAAAD,QAAAE,IAAAF,UAAAE,GAAAF,UAAG,GAAA,GAAE,OAErD,IAAIG,SAAa,CAACC,EAASC,KACzB,MAAMoB,EAAiB,GACvB3B,GAAUA,EAAOe,iBAAiB,QAASR,EAAQ,CAAES,MAAM,IAC3DX,QAAQuB,IACNJ,EAAQK,KAAKC,GACXC,EACGC,SAICF,EAAIG,MACLC,WAAWJ,EAAK,CAAE9B,WAClBmC,MAAMC,IACLX,EAAQK,EAAKM,GACbT,EAAUU,KAAKD,GACRA,QAIZD,KAAK7B,GACLgC,OAAOC,IAENZ,EAAUa,SAASC,IAChBA,EAA0BC,SACxBD,EAA0BC,SAAS,IAExCnC,EAAOgC,EAAM,IAEdI,SAAQ,KACP3C,GAAUA,EAAOoB,oBAAoB,QAASb,EAAO,GACrD,GACJ,EASSqC,EAA0B,SAGrCC,GAAqB,IACrB7C,OAAEA,GAAmBE,UAAAC,OAAAD,QAAAE,IAAAF,UAAAE,GAAAF,UAAG,GAAA,GAAE,OAE1B,IAAIG,SAAW,CAACC,EAASC,KACvB,MAAMoB,EAAiD,GACvD3B,GAAUA,EAAOe,iBAAiB,QAASR,EAAQ,CAAES,MAAM,IAE3D,MAAM8B,EAAWC,OAAOC,OAAOH,GAAkBhB,KAAKoB,GAC/CA,EAIDA,EAAMhB,KACDV,EAAgD,CAAC0B,GAAQ,CAC9DjD,WACCmC,MAAKe,IAAe,IAAbC,GAAQD,EAEhB,OADAvB,EAAUU,KAAKc,GACRA,CAAO,IAIdF,EAAMG,OACDrB,EACJC,SAAyB,WACzBE,WAAWe,EAAO,CAAEjD,WACpBmC,MAAMkB,IACL1B,EAAUU,KAAKgB,GACRA,KAGNJ,EArBEA,IAuBLK,EAAOP,OAAOO,KAAKT,GACzBxC,QAAQuB,IAAIkB,GACTX,MAAMgB,GACEA,EAAQI,QAAO,CAACC,EAAKf,EAAUgB,KACpCD,EAAIF,EAAKG,IAAUhB,EACZe,IACN,CAAE,KAENrB,KAAK7B,GACLgC,OAAOC,IAENZ,EAAUa,SAASC,IACjBA,EAASC,SAAWD,EAASC,SAAS,IAExCnC,EAAOgC,EAAM,IAEdI,SAAQ,KACP3C,GAAUA,EAAOoB,oBAAoB,QAASb,EAAO,GACrD,GACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"objectEnlive.mjs","sources":["../../../../src/util/misc/objectEnlive.ts"],"sourcesContent":["import { noop } from '../../constants';\nimport type { Pattern } from '../../Pattern';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport type {\n Abortable,\n Constructor,\n TCrossOrigin,\n TFiller,\n} from '../../typedefs';\nimport { createImage } from './dom';\nimport { classRegistry } from '../../ClassRegistry';\nimport type { BaseFilter } from '../../filters/BaseFilter';\nimport type { FabricObject as BaseFabricObject } from '../../shapes/Object/Object';\nimport { FabricError, SignalAbortedError } from '../internals/console';\nimport type { Shadow } from '../../Shadow';\n\nexport type LoadImageOptions = Abortable & {\n /**\n * cors value for the image loading, default to anonymous\n */\n crossOrigin?: TCrossOrigin;\n};\n\n/**\n * Loads image element from given url and resolve it, or catch.\n * @param {String} url URL representing an image\n * @param {LoadImageOptions} [options] image loading options\n * @returns {Promise<HTMLImageElement>} the loaded image.\n */\nexport const loadImage = (\n url: string,\n { signal, crossOrigin = null }: LoadImageOptions = {}\n) =>\n new Promise<HTMLImageElement>(function (resolve, reject) {\n if (signal && signal.aborted) {\n return reject(new SignalAbortedError('loadImage'));\n }\n const img = createImage();\n let abort: EventListenerOrEventListenerObject;\n if (signal) {\n abort = function (err: Event) {\n img.src = '';\n reject(err);\n };\n signal.addEventListener('abort', abort, { once: true });\n }\n const done = function () {\n img.onload = img.onerror = null;\n abort && signal?.removeEventListener('abort', abort);\n resolve(img);\n };\n if (!url) {\n done();\n return;\n }\n img.onload = done;\n img.onerror = function () {\n abort && signal?.removeEventListener('abort', abort);\n reject(new FabricError(`Error loading ${img.src}`));\n };\n crossOrigin && (img.crossOrigin = crossOrigin);\n img.src = url;\n });\n\nexport type EnlivenObjectOptions = Abortable & {\n /**\n * Method for further parsing of object elements,\n * called after each fabric object created.\n */\n reviver?: <\n T extends\n | BaseFabricObject\n | FabricObject\n | BaseFilter<string>\n | Shadow\n | TFiller\n >(\n serializedObj: Record<string, any>,\n instance: T\n ) => void;\n};\n\n/**\n * Creates corresponding fabric instances from their object representations\n * @param {Object[]} objects Objects to enliven\n * @param {EnlivenObjectOptions} [options]\n * @param {(serializedObj: object, instance: FabricObject) => any} [options.reviver] Method for further parsing of object elements,\n * called after each fabric object created.\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise<FabricObject[]>}\n */\nexport const enlivenObjects = <\n T extends\n | BaseFabricObject\n | FabricObject\n | BaseFilter<string>\n | Shadow\n | TFiller\n>(\n objects: any[],\n { signal, reviver = noop }: EnlivenObjectOptions = {}\n) =>\n new Promise<T[]>((resolve, reject) => {\n const instances: T[] = [];\n signal && signal.addEventListener('abort', reject, { once: true });\n Promise.all(\n objects.map((obj) =>\n classRegistry\n .getClass<\n Constructor<T> & {\n fromObject(options: any, context: Abortable): Promise<T>;\n }\n >(obj.type)\n .fromObject(obj, { signal })\n .then((fabricInstance) => {\n reviver(obj, fabricInstance);\n instances.push(fabricInstance);\n return fabricInstance;\n })\n )\n )\n .then(resolve)\n .catch((error) => {\n // cleanup\n instances.forEach((instance) => {\n (instance as FabricObject).dispose &&\n (instance as FabricObject).dispose();\n });\n reject(error);\n })\n .finally(() => {\n signal && signal.removeEventListener('abort', reject);\n });\n });\n\n/**\n * Creates corresponding fabric instances residing in an object, e.g. `clipPath`\n * @param {Object} object with properties to enlive ( fill, stroke, clipPath, path )\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise<Record<string, FabricObject | TFiller | null>>} the input object with enlived values\n */\nexport const enlivenObjectEnlivables = <\n R = Record<string, FabricObject | TFiller | null>\n>(\n serializedObject: any,\n { signal }: Abortable = {}\n) =>\n new Promise<R>((resolve, reject) => {\n const instances: (FabricObject | TFiller | Shadow)[] = [];\n signal && signal.addEventListener('abort', reject, { once: true });\n // enlive every possible property\n const promises = Object.values(serializedObject).map((value: any) => {\n if (!value) {\n return value;\n }\n // clipPath or shadow or gradient\n if (value.type) {\n return enlivenObjects<FabricObject | Shadow | TFiller>([value], {\n signal,\n }).then(([enlived]) => {\n instances.push(enlived);\n return enlived;\n });\n }\n // pattern\n if (value.source) {\n return classRegistry\n .getClass<typeof Pattern>('pattern')\n .fromObject(value, { signal })\n .then((pattern: Pattern) => {\n instances.push(pattern);\n return pattern;\n });\n }\n return value;\n });\n const keys = Object.keys(serializedObject);\n Promise.all(promises)\n .then((enlived) => {\n return enlived.reduce((acc, instance, index) => {\n acc[keys[index]] = instance;\n return acc;\n }, {});\n })\n .then(resolve)\n .catch((error) => {\n // cleanup\n instances.forEach((instance: any) => {\n instance.dispose && instance.dispose();\n });\n reject(error);\n })\n .finally(() => {\n signal && signal.removeEventListener('abort', reject);\n });\n });\n"],"names":["loadImage","url","signal","crossOrigin","arguments","length","undefined","Promise","resolve","reject","aborted","SignalAbortedError","img","createImage","abort","err","src","addEventListener","once","done","onload","onerror","removeEventListener","FabricError","concat","enlivenObjects","objects","reviver","noop","instances","all","map","obj","classRegistry","getClass","type","fromObject","then","fabricInstance","push","catch","error","forEach","instance","dispose","finally","enlivenObjectEnlivables","serializedObject","promises","Object","values","value","_ref","enlived","source","pattern","keys","reduce","acc","index"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"objectEnlive.mjs","sources":["../../../../src/util/misc/objectEnlive.ts"],"sourcesContent":["import { noop } from '../../constants';\nimport type { Pattern } from '../../Pattern';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport type {\n Abortable,\n Constructor,\n TCrossOrigin,\n TFiller,\n} from '../../typedefs';\nimport { createImage } from './dom';\nimport { classRegistry } from '../../ClassRegistry';\nimport type { BaseFilter } from '../../filters/BaseFilter';\nimport type { FabricObject as BaseFabricObject } from '../../shapes/Object/Object';\nimport { FabricError, SignalAbortedError } from '../internals/console';\nimport type { Shadow } from '../../Shadow';\n\nexport type LoadImageOptions = Abortable & {\n /**\n * cors value for the image loading, default to anonymous\n */\n crossOrigin?: TCrossOrigin;\n};\n\n/**\n * Loads image element from given url and resolve it, or catch.\n * @param {String} url URL representing an image\n * @param {LoadImageOptions} [options] image loading options\n * @returns {Promise<HTMLImageElement>} the loaded image.\n */\nexport const loadImage = (\n url: string,\n { signal, crossOrigin = null }: LoadImageOptions = {}\n) =>\n new Promise<HTMLImageElement>(function (resolve, reject) {\n if (signal && signal.aborted) {\n return reject(new SignalAbortedError('loadImage'));\n }\n const img = createImage();\n let abort: EventListenerOrEventListenerObject;\n if (signal) {\n abort = function (err: Event) {\n img.src = '';\n reject(err);\n };\n signal.addEventListener('abort', abort, { once: true });\n }\n const done = function () {\n img.onload = img.onerror = null;\n abort && signal?.removeEventListener('abort', abort);\n resolve(img);\n };\n if (!url) {\n done();\n return;\n }\n img.onload = done;\n img.onerror = function () {\n abort && signal?.removeEventListener('abort', abort);\n reject(new FabricError(`Error loading ${img.src}`));\n };\n crossOrigin && (img.crossOrigin = crossOrigin);\n img.src = url;\n });\n\nexport type EnlivenObjectOptions = Abortable & {\n /**\n * Method for further parsing of object elements,\n * called after each fabric object created.\n */\n reviver?: <\n T extends\n | BaseFabricObject\n | FabricObject\n | BaseFilter<string>\n | Shadow\n | TFiller\n >(\n serializedObj: Record<string, any>,\n instance: T\n ) => void;\n};\n\n/**\n * @TODO type this correctly.\n * Creates corresponding fabric instances from their object representations\n * @param {Object[]} objects Objects to enliven\n * @param {EnlivenObjectOptions} [options]\n * @param {(serializedObj: object, instance: FabricObject) => any} [options.reviver] Method for further parsing of object elements,\n * called after each fabric object created.\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise<FabricObject[]>}\n */\nexport const enlivenObjects = <\n T extends\n | BaseFabricObject\n | FabricObject\n | BaseFilter<string>\n | Shadow\n | TFiller\n>(\n objects: any[],\n { signal, reviver = noop }: EnlivenObjectOptions = {}\n) =>\n new Promise<T[]>((resolve, reject) => {\n const instances: T[] = [];\n signal && signal.addEventListener('abort', reject, { once: true });\n Promise.all(\n objects.map((obj) =>\n classRegistry\n .getClass<\n Constructor<T> & {\n fromObject(options: any, context: Abortable): Promise<T>;\n }\n >(obj.type)\n .fromObject(obj, { signal })\n .then((fabricInstance) => {\n reviver(obj, fabricInstance);\n instances.push(fabricInstance);\n return fabricInstance;\n })\n )\n )\n .then(resolve)\n .catch((error) => {\n // cleanup\n instances.forEach((instance) => {\n (instance as FabricObject).dispose &&\n (instance as FabricObject).dispose();\n });\n reject(error);\n })\n .finally(() => {\n signal && signal.removeEventListener('abort', reject);\n });\n });\n\n/**\n * Creates corresponding fabric instances residing in an object, e.g. `clipPath`\n * @param {Object} object with properties to enlive ( fill, stroke, clipPath, path )\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise<Record<string, FabricObject | TFiller | null>>} the input object with enlived values\n */\nexport const enlivenObjectEnlivables = <\n R = Record<string, FabricObject | TFiller | null>\n>(\n serializedObject: any,\n { signal }: Abortable = {}\n) =>\n new Promise<R>((resolve, reject) => {\n const instances: (FabricObject | TFiller | Shadow)[] = [];\n signal && signal.addEventListener('abort', reject, { once: true });\n // enlive every possible property\n const promises = Object.values(serializedObject).map((value: any) => {\n if (!value) {\n return value;\n }\n // clipPath or shadow or gradient\n if (value.type) {\n return enlivenObjects<FabricObject | Shadow | TFiller>([value], {\n signal,\n }).then(([enlived]) => {\n instances.push(enlived);\n return enlived;\n });\n }\n // pattern\n if (value.source) {\n return classRegistry\n .getClass<typeof Pattern>('pattern')\n .fromObject(value, { signal })\n .then((pattern: Pattern) => {\n instances.push(pattern);\n return pattern;\n });\n }\n return value;\n });\n const keys = Object.keys(serializedObject);\n Promise.all(promises)\n .then((enlived) => {\n return enlived.reduce((acc, instance, index) => {\n acc[keys[index]] = instance;\n return acc;\n }, {});\n })\n .then(resolve)\n .catch((error) => {\n // cleanup\n instances.forEach((instance: any) => {\n instance.dispose && instance.dispose();\n });\n reject(error);\n })\n .finally(() => {\n signal && signal.removeEventListener('abort', reject);\n });\n });\n"],"names":["loadImage","url","signal","crossOrigin","arguments","length","undefined","Promise","resolve","reject","aborted","SignalAbortedError","img","createImage","abort","err","src","addEventListener","once","done","onload","onerror","removeEventListener","FabricError","concat","enlivenObjects","objects","reviver","noop","instances","all","map","obj","classRegistry","getClass","type","fromObject","then","fabricInstance","push","catch","error","forEach","instance","dispose","finally","enlivenObjectEnlivables","serializedObject","promises","Object","values","value","_ref","enlived","source","pattern","keys","reduce","acc","index"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Color as t}from"../../color/Color.min.mjs";import{config as n}from"../../config.min.mjs";import{DEFAULT_SVG_FONT_SIZE as c,NONE as e}from"../../constants.min.mjs";import{toFixed as
|
|
1
|
+
import{Color as t}from"../../color/Color.min.mjs";import{config as n}from"../../config.min.mjs";import{DEFAULT_SVG_FONT_SIZE as c,NONE as e,FILL as o}from"../../constants.min.mjs";import{toFixed as r}from"./toFixed.min.mjs";const a=t=>{const n=["instantiated_by_use","style","id","class"];switch(t){case"linearGradient":return n.concat(["x1","y1","x2","y2","gradientUnits","gradientTransform"]);case"radialGradient":return n.concat(["gradientUnits","gradientTransform","cx","cy","r","fx","fy","fr"]);case"stop":return n.concat(["offset","stop-color","stop-opacity"])}return n},i=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:c;const o=/\D{0,2}$/.exec(t),r=parseFloat(t),a=n.DPI;switch(null==o?void 0:o[0]){case"mm":return r*a/25.4;case"cm":return r*a/2.54;case"in":return r*a;case"pt":return r*a/72;case"pc":return r*a/72*12;case"em":return r*e;default:return r}},s=t=>{const[n,c]=t.trim().split(" "),[o,r]=(a=n)&&a!==e?[a.slice(1,4),a.slice(5,8)]:a===e?[a,a]:["Mid","Mid"];var a;return{meetOrSlice:c||"meet",alignX:o,alignY:r}},l=t=>"matrix("+t.map((t=>r(t,n.NUM_FRACTION_DIGITS))).join(" ")+")",m=function(n,c){let e,o,r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(c)if(c.toLive)e="url(#SVGID_".concat(c.id,")");else{const n=new t(c),r=n.getAlpha();e=n.toRgb(),1!==r&&(o=r.toString())}else e="none";return r?"".concat(n,": ").concat(e,"; ").concat(o?"".concat(n,"-opacity: ").concat(o,"; "):""):"".concat(n,'="').concat(e,'" ').concat(o?"".concat(n,'-opacity="').concat(o,'" '):"")},u=function(t,c){let{left:e,top:a,width:i,height:s}=c,l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:n.NUM_FRACTION_DIGITS;const u=m(o,t,!1),[d,f,p,g]=[e,a,i,s].map((t=>r(t,l)));return"<rect ".concat(u,' x="').concat(d,'" y="').concat(f,'" width="').concat(p,'" height="').concat(g,'"></rect>')};export{m as colorPropToSVG,u as createSVGRect,a as getSvgAttributes,l as matrixToSVG,s as parsePreserveAspectRatioAttribute,i as parseUnit};
|
|
2
2
|
//# sourceMappingURL=svgParsing.min.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"svgParsing.min.mjs","sources":["../../../../src/util/misc/svgParsing.ts"],"sourcesContent":["import { Color } from '../../color/Color';\nimport { config } from '../../config';\nimport { DEFAULT_SVG_FONT_SIZE, NONE } from '../../constants';\nimport type {\n TBBox,\n TMat2D,\n SVGElementName,\n SupportedSVGUnit,\n} from '../../typedefs';\nimport { toFixed } from './toFixed';\n\n/**\n * Returns array of attributes for given svg that fabric parses\n * @param {SVGElementName} type Type of svg element (eg. 'circle')\n * @return {Array} string names of supported attributes\n */\nexport const getSvgAttributes = (type: SVGElementName) => {\n const commonAttributes = ['instantiated_by_use', 'style', 'id', 'class'];\n switch (type) {\n case 'linearGradient':\n return commonAttributes.concat([\n 'x1',\n 'y1',\n 'x2',\n 'y2',\n 'gradientUnits',\n 'gradientTransform',\n ]);\n case 'radialGradient':\n return commonAttributes.concat([\n 'gradientUnits',\n 'gradientTransform',\n 'cx',\n 'cy',\n 'r',\n 'fx',\n 'fy',\n 'fr',\n ]);\n case 'stop':\n return commonAttributes.concat(['offset', 'stop-color', 'stop-opacity']);\n }\n return commonAttributes;\n};\n\n/**\n * Converts from attribute value to pixel value if applicable.\n * Returns converted pixels or original value not converted.\n * @param {string} value number to operate on\n * @param {number} fontSize\n * @return {number}\n */\nexport const parseUnit = (value: string, fontSize = DEFAULT_SVG_FONT_SIZE) => {\n const unit = /\\D{0,2}$/.exec(value),\n number = parseFloat(value);\n const dpi = config.DPI;\n switch (unit?.[0] as SupportedSVGUnit) {\n case 'mm':\n return (number * dpi) / 25.4;\n\n case 'cm':\n return (number * dpi) / 2.54;\n\n case 'in':\n return number * dpi;\n\n case 'pt':\n return (number * dpi) / 72; // or * 4 / 3\n\n case 'pc':\n return ((number * dpi) / 72) * 12; // or * 16\n\n case 'em':\n return number * fontSize;\n\n default:\n return number;\n }\n};\n\nexport type MeetOrSlice = 'meet' | 'slice';\n\nexport type MinMidMax = 'Min' | 'Mid' | 'Max' | 'none';\n\nexport type TPreserveArParsed = {\n meetOrSlice: MeetOrSlice;\n alignX: MinMidMax;\n alignY: MinMidMax;\n};\n\n// align can be either none or undefined or a combination of mid/max\nconst parseAlign = (align: string): MinMidMax[] => {\n //divide align in alignX and alignY\n if (align && align !== NONE) {\n return [align.slice(1, 4) as MinMidMax, align.slice(5, 8) as MinMidMax];\n } else if (align === NONE) {\n return [align, align];\n }\n return ['Mid', 'Mid'];\n};\n\n/**\n * Parse preserveAspectRatio attribute from element\n * https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio\n * @param {string} attribute to be parsed\n * @return {Object} an object containing align and meetOrSlice attribute\n */\nexport const parsePreserveAspectRatioAttribute = (\n attribute: string\n): TPreserveArParsed => {\n const [firstPart, secondPart] = attribute.trim().split(' ') as [\n MinMidMax,\n MeetOrSlice | undefined\n ];\n const [alignX, alignY] = parseAlign(firstPart);\n return {\n meetOrSlice: secondPart || 'meet',\n alignX,\n alignY,\n };\n};\n\n/**\n * given an array of 6 number returns something like `\"matrix(...numbers)\"`\n * @param {TMat2D} transform an array with 6 numbers\n * @return {String} transform matrix for svg\n */\nexport const matrixToSVG = (transform: TMat2D) =>\n 'matrix(' +\n transform\n .map((value) => toFixed(value, config.NUM_FRACTION_DIGITS))\n .join(' ') +\n ')';\n\n/**\n * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n * @param prop\n * @param value\n * @param {boolean} inlineStyle The default is inline style, the separator used is \":\", The other is \"=\"\n * @returns\n */\nexport const colorPropToSVG = (\n prop: string,\n value?: any,\n inlineStyle = true\n) => {\n let colorValue;\n let opacityValue;\n if (!value) {\n colorValue = 'none';\n } else if (value.toLive) {\n colorValue = `url(#SVGID_${value.id})`;\n } else {\n const color = new Color(value),\n opacity = color.getAlpha();\n\n colorValue = color.toRgb();\n if (opacity !== 1) {\n opacityValue = opacity.toString();\n }\n }\n if (inlineStyle) {\n return `${prop}: ${colorValue}; ${\n opacityValue ? `${prop}-opacity: ${opacityValue}; ` : ''\n }`;\n } else {\n return `${prop}=\"${colorValue}\" ${\n opacityValue ? `${prop}-opacity=\"${opacityValue}\" ` : ''\n }`;\n }\n};\n\nexport const createSVGRect = (\n color: string,\n { left, top, width, height }: TBBox,\n precision = config.NUM_FRACTION_DIGITS\n) => {\n const svgColor = colorPropToSVG(
|
|
1
|
+
{"version":3,"file":"svgParsing.min.mjs","sources":["../../../../src/util/misc/svgParsing.ts"],"sourcesContent":["import { Color } from '../../color/Color';\nimport { config } from '../../config';\nimport { DEFAULT_SVG_FONT_SIZE, FILL, NONE } from '../../constants';\nimport type {\n TBBox,\n TMat2D,\n SVGElementName,\n SupportedSVGUnit,\n} from '../../typedefs';\nimport { toFixed } from './toFixed';\n\n/**\n * Returns array of attributes for given svg that fabric parses\n * @param {SVGElementName} type Type of svg element (eg. 'circle')\n * @return {Array} string names of supported attributes\n */\nexport const getSvgAttributes = (type: SVGElementName) => {\n const commonAttributes = ['instantiated_by_use', 'style', 'id', 'class'];\n switch (type) {\n case 'linearGradient':\n return commonAttributes.concat([\n 'x1',\n 'y1',\n 'x2',\n 'y2',\n 'gradientUnits',\n 'gradientTransform',\n ]);\n case 'radialGradient':\n return commonAttributes.concat([\n 'gradientUnits',\n 'gradientTransform',\n 'cx',\n 'cy',\n 'r',\n 'fx',\n 'fy',\n 'fr',\n ]);\n case 'stop':\n return commonAttributes.concat(['offset', 'stop-color', 'stop-opacity']);\n }\n return commonAttributes;\n};\n\n/**\n * Converts from attribute value to pixel value if applicable.\n * Returns converted pixels or original value not converted.\n * @param {string} value number to operate on\n * @param {number} fontSize\n * @return {number}\n */\nexport const parseUnit = (value: string, fontSize = DEFAULT_SVG_FONT_SIZE) => {\n const unit = /\\D{0,2}$/.exec(value),\n number = parseFloat(value);\n const dpi = config.DPI;\n switch (unit?.[0] as SupportedSVGUnit) {\n case 'mm':\n return (number * dpi) / 25.4;\n\n case 'cm':\n return (number * dpi) / 2.54;\n\n case 'in':\n return number * dpi;\n\n case 'pt':\n return (number * dpi) / 72; // or * 4 / 3\n\n case 'pc':\n return ((number * dpi) / 72) * 12; // or * 16\n\n case 'em':\n return number * fontSize;\n\n default:\n return number;\n }\n};\n\nexport type MeetOrSlice = 'meet' | 'slice';\n\nexport type MinMidMax = 'Min' | 'Mid' | 'Max' | 'none';\n\nexport type TPreserveArParsed = {\n meetOrSlice: MeetOrSlice;\n alignX: MinMidMax;\n alignY: MinMidMax;\n};\n\n// align can be either none or undefined or a combination of mid/max\nconst parseAlign = (align: string): MinMidMax[] => {\n //divide align in alignX and alignY\n if (align && align !== NONE) {\n return [align.slice(1, 4) as MinMidMax, align.slice(5, 8) as MinMidMax];\n } else if (align === NONE) {\n return [align, align];\n }\n return ['Mid', 'Mid'];\n};\n\n/**\n * Parse preserveAspectRatio attribute from element\n * https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio\n * @param {string} attribute to be parsed\n * @return {Object} an object containing align and meetOrSlice attribute\n */\nexport const parsePreserveAspectRatioAttribute = (\n attribute: string\n): TPreserveArParsed => {\n const [firstPart, secondPart] = attribute.trim().split(' ') as [\n MinMidMax,\n MeetOrSlice | undefined\n ];\n const [alignX, alignY] = parseAlign(firstPart);\n return {\n meetOrSlice: secondPart || 'meet',\n alignX,\n alignY,\n };\n};\n\n/**\n * given an array of 6 number returns something like `\"matrix(...numbers)\"`\n * @param {TMat2D} transform an array with 6 numbers\n * @return {String} transform matrix for svg\n */\nexport const matrixToSVG = (transform: TMat2D) =>\n 'matrix(' +\n transform\n .map((value) => toFixed(value, config.NUM_FRACTION_DIGITS))\n .join(' ') +\n ')';\n\n/**\n * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n * @param prop\n * @param value\n * @param {boolean} inlineStyle The default is inline style, the separator used is \":\", The other is \"=\"\n * @returns\n */\nexport const colorPropToSVG = (\n prop: string,\n value?: any,\n inlineStyle = true\n) => {\n let colorValue;\n let opacityValue;\n if (!value) {\n colorValue = 'none';\n } else if (value.toLive) {\n colorValue = `url(#SVGID_${value.id})`;\n } else {\n const color = new Color(value),\n opacity = color.getAlpha();\n\n colorValue = color.toRgb();\n if (opacity !== 1) {\n opacityValue = opacity.toString();\n }\n }\n if (inlineStyle) {\n return `${prop}: ${colorValue}; ${\n opacityValue ? `${prop}-opacity: ${opacityValue}; ` : ''\n }`;\n } else {\n return `${prop}=\"${colorValue}\" ${\n opacityValue ? `${prop}-opacity=\"${opacityValue}\" ` : ''\n }`;\n }\n};\n\nexport const createSVGRect = (\n color: string,\n { left, top, width, height }: TBBox,\n precision = config.NUM_FRACTION_DIGITS\n) => {\n const svgColor = colorPropToSVG(FILL, color, false);\n const [x, y, w, h] = [left, top, width, height].map((value) =>\n toFixed(value, precision)\n );\n return `<rect ${svgColor} x=\"${x}\" y=\"${y}\" width=\"${w}\" height=\"${h}\"></rect>`;\n};\n"],"names":["getSvgAttributes","type","commonAttributes","concat","parseUnit","value","fontSize","arguments","length","undefined","DEFAULT_SVG_FONT_SIZE","unit","exec","number","parseFloat","dpi","config","DPI","parsePreserveAspectRatioAttribute","attribute","firstPart","secondPart","trim","split","alignX","alignY","align","NONE","slice","meetOrSlice","matrixToSVG","transform","map","toFixed","NUM_FRACTION_DIGITS","join","colorPropToSVG","prop","colorValue","opacityValue","inlineStyle","toLive","id","color","Color","opacity","getAlpha","toRgb","toString","createSVGRect","_ref","left","top","width","height","precision","svgColor","FILL","x","y","w","h"],"mappings":"gOAgBaA,MAAAA,EAAoBC,IAC/B,MAAMC,EAAmB,CAAC,sBAAuB,QAAS,KAAM,SAChE,OAAQD,GACN,IAAK,iBACH,OAAOC,EAAiBC,OAAO,CAC7B,KACA,KACA,KACA,KACA,gBACA,sBAEJ,IAAK,iBACH,OAAOD,EAAiBC,OAAO,CAC7B,gBACA,oBACA,KACA,KACA,IACA,KACA,KACA,OAEJ,IAAK,OACH,OAAOD,EAAiBC,OAAO,CAAC,SAAU,aAAc,iBAE5D,OAAOD,CAAgB,EAUZE,EAAY,SAACC,GAAoD,IAArCC,EAAQC,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAGG,EAClD,MAAMC,EAAO,WAAWC,KAAKP,GAC3BQ,EAASC,WAAWT,GAChBU,EAAMC,EAAOC,IACnB,OAAQN,eAAAA,EAAO,IACb,IAAK,KACH,OAAQE,EAASE,EAAO,KAE1B,IAAK,KACH,OAAQF,EAASE,EAAO,KAE1B,IAAK,KACH,OAAOF,EAASE,EAElB,IAAK,KACH,OAAQF,EAASE,EAAO,GAE1B,IAAK,KACH,OAASF,EAASE,EAAO,GAAM,GAEjC,IAAK,KACH,OAAOF,EAASP,EAElB,QACE,OAAOO,EAEb,EA6BaK,EACXC,IAEA,MAAOC,EAAWC,GAAcF,EAAUG,OAAOC,MAAM,MAIhDC,EAAQC,IAvBGC,EAuBkBN,IArBvBM,IAAUC,EACd,CAACD,EAAME,MAAM,EAAG,GAAiBF,EAAME,MAAM,EAAG,IAC9CF,IAAUC,EACZ,CAACD,EAAOA,GAEV,CAAC,MAAO,OAPGA,MAwBlB,MAAO,CACLG,YAAaR,GAAc,OAC3BG,SACAC,SACD,EAQUK,EAAeC,GAC1B,UACAA,EACGC,KAAK3B,GAAU4B,EAAQ5B,EAAOW,EAAOkB,uBACrCC,KAAK,KACR,IAUWC,EAAiB,SAC5BC,EACAhC,GAEG,IACCiC,EACAC,EAHJC,IAAWjC,UAAAC,OAAA,QAAAC,IAAAF,UAAA,KAAAA,UAAA,GAIX,GAAKF,EAEE,GAAIA,EAAMoC,OACfH,gBAAUnC,OAAiBE,EAAMqC,GAAK,SACjC,CACL,MAAMC,EAAQ,IAAIC,EAAMvC,GACtBwC,EAAUF,EAAMG,WAElBR,EAAaK,EAAMI,QACH,IAAZF,IACFN,EAAeM,EAAQG,WAE3B,MAXEV,EAAa,OAYf,OAAIE,EACFrC,GAAAA,OAAUkC,EAAI,MAAAlC,OAAKmC,QAAUnC,OAC3BoC,EAAYpC,GAAAA,OAAMkC,EAAI,cAAAlC,OAAaoC,QAAmB,IAGxDpC,GAAAA,OAAUkC,EAAI,MAAAlC,OAAKmC,QAAUnC,OAC3BoC,EAAYpC,GAAAA,OAAMkC,EAAI,cAAAlC,OAAaoC,QAAmB,GAG5D,EAEaU,EAAgB,SAC3BN,EAAaO,GAGV,IAFHC,KAAEA,EAAIC,IAAEA,EAAGC,MAAEA,EAAKC,OAAEA,GAAeJ,EACnCK,EAAShD,UAAAC,OAAAD,QAAAE,IAAAF,UAAAE,GAAAF,UAAGS,GAAAA,EAAOkB,oBAEnB,MAAMsB,EAAWpB,EAAeqB,EAAMd,GAAO,IACtCe,EAAGC,EAAGC,EAAGC,GAAK,CAACV,EAAMC,EAAKC,EAAOC,GAAQtB,KAAK3B,GACnD4B,EAAQ5B,EAAOkD,KAEjB,MAAA,SAAApD,OAAgBqD,UAAQrD,OAAOuD,EAACvD,SAAAA,OAAQwD,eAACxD,OAAYyD,EAACzD,cAAAA,OAAa0D,EAAC,YACtE"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Color } from '../../color/Color.mjs';
|
|
2
2
|
import { config } from '../../config.mjs';
|
|
3
|
-
import { DEFAULT_SVG_FONT_SIZE, NONE } from '../../constants.mjs';
|
|
3
|
+
import { DEFAULT_SVG_FONT_SIZE, NONE, FILL } from '../../constants.mjs';
|
|
4
4
|
import { toFixed } from './toFixed.mjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -126,7 +126,7 @@ const createSVGRect = function (color, _ref) {
|
|
|
126
126
|
height
|
|
127
127
|
} = _ref;
|
|
128
128
|
let precision = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : config.NUM_FRACTION_DIGITS;
|
|
129
|
-
const svgColor = colorPropToSVG(
|
|
129
|
+
const svgColor = colorPropToSVG(FILL, color, false);
|
|
130
130
|
const [x, y, w, h] = [left, top, width, height].map(value => toFixed(value, precision));
|
|
131
131
|
return "<rect ".concat(svgColor, " x=\"").concat(x, "\" y=\"").concat(y, "\" width=\"").concat(w, "\" height=\"").concat(h, "\"></rect>");
|
|
132
132
|
};
|