fabric 7.0.0 → 7.2.0
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/.husky/pre-commit +1 -0
- package/CHANGELOG.md +21 -0
- package/dist/extensions/cropping_controls/croppingControls.d.ts +16 -0
- package/dist/extensions/cropping_controls/croppingControls.d.ts.map +1 -0
- package/dist/extensions/cropping_controls/croppingHandlers.d.ts +39 -0
- package/dist/extensions/cropping_controls/croppingHandlers.d.ts.map +1 -0
- package/dist/extensions/cropping_controls/enterCropMode.d.ts +7 -0
- package/dist/extensions/cropping_controls/enterCropMode.d.ts.map +1 -0
- package/dist/extensions/cropping_controls/renderCornerControl.d.ts +14 -0
- package/dist/extensions/cropping_controls/renderCornerControl.d.ts.map +1 -0
- package/dist/extensions/index.d.ts +3 -0
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/fabric.d.ts +1 -0
- package/dist/fabric.d.ts.map +1 -1
- package/dist/index.js +628 -537
- 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 +628 -537
- package/dist/index.mjs.map +1 -1
- package/dist/index.node.cjs +628 -537
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +628 -537
- 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 +5 -0
- package/dist/src/EventTypeDefs.d.ts.map +1 -1
- package/dist/src/Pattern/Pattern.d.ts.map +1 -1
- package/dist/src/Pattern/Pattern.min.mjs +1 -1
- package/dist/src/Pattern/Pattern.min.mjs.map +1 -1
- package/dist/src/Pattern/Pattern.mjs +2 -1
- package/dist/src/Pattern/Pattern.mjs.map +1 -1
- package/dist/src/Shadow.d.ts +1 -1
- package/dist/src/Shadow.d.ts.map +1 -1
- package/dist/src/Shadow.min.mjs +1 -1
- package/dist/src/Shadow.min.mjs.map +1 -1
- package/dist/src/Shadow.mjs +5 -4
- package/dist/src/Shadow.mjs.map +1 -1
- package/dist/src/canvas/CanvasOptions.d.ts.map +1 -1
- package/dist/src/canvas/CanvasOptions.min.mjs.map +1 -1
- package/dist/src/canvas/CanvasOptions.mjs.map +1 -1
- package/dist/src/canvas/SelectableCanvas.d.ts +2 -0
- 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 +33 -13
- package/dist/src/canvas/SelectableCanvas.mjs.map +1 -1
- package/dist/src/canvas/StaticCanvas.d.ts.map +1 -1
- package/dist/src/canvas/StaticCanvas.min.mjs +1 -1
- package/dist/src/canvas/StaticCanvas.min.mjs.map +1 -1
- package/dist/src/canvas/StaticCanvas.mjs +3 -1
- package/dist/src/canvas/StaticCanvas.mjs.map +1 -1
- package/dist/src/canvas/StaticCanvasOptions.d.ts.map +1 -1
- package/dist/src/canvas/StaticCanvasOptions.min.mjs.map +1 -1
- package/dist/src/canvas/StaticCanvasOptions.mjs.map +1 -1
- package/dist/src/constants.d.ts +1 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.min.mjs.map +1 -1
- package/dist/src/constants.mjs.map +1 -1
- package/dist/src/controls/Control.d.ts +22 -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 +45 -1
- package/dist/src/controls/Control.mjs.map +1 -1
- package/dist/src/controls/changeWidth.d.ts +22 -0
- package/dist/src/controls/changeWidth.d.ts.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 +46 -18
- package/dist/src/controls/changeWidth.mjs.map +1 -1
- package/dist/src/controls/controlRendering.d.ts.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 +18 -34
- package/dist/src/controls/controlRendering.mjs.map +1 -1
- package/dist/src/controls/index.d.ts +2 -1
- package/dist/src/controls/index.d.ts.map +1 -1
- package/dist/src/controls/index.min.mjs +1 -1
- package/dist/src/controls/index.mjs +1 -1
- package/dist/src/gradient/Gradient.d.ts.map +1 -1
- package/dist/src/gradient/Gradient.min.mjs +1 -1
- package/dist/src/gradient/Gradient.min.mjs.map +1 -1
- package/dist/src/gradient/Gradient.mjs +19 -6
- package/dist/src/gradient/Gradient.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 +10 -7
- package/dist/src/shapes/Circle.mjs.map +1 -1
- package/dist/src/shapes/Ellipse.d.ts.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 +2 -1
- package/dist/src/shapes/Ellipse.mjs.map +1 -1
- package/dist/src/shapes/Group.d.ts.map +1 -1
- package/dist/src/shapes/Group.min.mjs +1 -1
- package/dist/src/shapes/Group.min.mjs.map +1 -1
- package/dist/src/shapes/Group.mjs +2 -1
- package/dist/src/shapes/Group.mjs.map +1 -1
- package/dist/src/shapes/IText/IText.d.ts.map +1 -1
- package/dist/src/shapes/IText/IText.min.mjs.map +1 -1
- package/dist/src/shapes/IText/IText.mjs.map +1 -1
- package/dist/src/shapes/Image.d.ts +1 -1
- package/dist/src/shapes/Image.d.ts.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 +4 -3
- package/dist/src/shapes/Image.mjs.map +1 -1
- package/dist/src/shapes/Line.d.ts.map +1 -1
- package/dist/src/shapes/Line.min.mjs +1 -1
- package/dist/src/shapes/Line.min.mjs.map +1 -1
- package/dist/src/shapes/Line.mjs +6 -10
- package/dist/src/shapes/Line.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 +5 -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.map +1 -1
- package/dist/src/shapes/Object/InteractiveObject.mjs.map +1 -1
- 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 +3 -0
- 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 +1 -1
- package/dist/src/shapes/Object/ObjectGeometry.mjs.map +1 -1
- package/dist/src/shapes/Object/types/FabricObjectProps.d.ts.map +1 -1
- package/dist/src/shapes/Object/types/ObjectProps.d.ts.map +1 -1
- package/dist/src/shapes/Path.d.ts.map +1 -1
- package/dist/src/shapes/Path.min.mjs.map +1 -1
- package/dist/src/shapes/Path.mjs +1 -2
- package/dist/src/shapes/Path.mjs.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 +10 -6
- package/dist/src/shapes/Polyline.mjs.map +1 -1
- package/dist/src/shapes/Rect.d.ts.map +1 -1
- package/dist/src/shapes/Rect.min.mjs +1 -1
- package/dist/src/shapes/Rect.min.mjs.map +1 -1
- package/dist/src/shapes/Rect.mjs +2 -1
- package/dist/src/shapes/Rect.mjs.map +1 -1
- package/dist/src/shapes/Text/StyledText.d.ts.map +1 -1
- package/dist/src/shapes/Text/StyledText.min.mjs.map +1 -1
- package/dist/src/shapes/Text/StyledText.mjs +0 -3
- package/dist/src/shapes/Text/StyledText.mjs.map +1 -1
- package/dist/src/shapes/Text/Text.d.ts.map +1 -1
- package/dist/src/shapes/Text/Text.min.mjs.map +1 -1
- 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 +5 -6
- package/dist/src/shapes/Text/TextSVGExportMixin.mjs.map +1 -1
- package/dist/src/shapes/Textbox.d.ts.map +1 -1
- package/dist/src/shapes/Textbox.min.mjs.map +1 -1
- package/dist/src/shapes/Textbox.mjs.map +1 -1
- package/dist/src/shapes/Triangle.d.ts.map +1 -1
- package/dist/src/shapes/Triangle.min.mjs.map +1 -1
- package/dist/src/shapes/Triangle.mjs.map +1 -1
- package/dist/src/util/lang_string.d.ts +1 -1
- package/dist/src/util/lang_string.d.ts.map +1 -1
- package/dist/src/util/lang_string.min.mjs +1 -1
- package/dist/src/util/lang_string.min.mjs.map +1 -1
- package/dist/src/util/lang_string.mjs +1 -1
- package/dist/src/util/lang_string.mjs.map +1 -1
- package/dist/src/util/misc/svgParsing.d.ts.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 -1
- package/dist/src/util/misc/svgParsing.mjs.map +1 -1
- package/dist-extensions/cropping_controls/croppingControls.mjs +140 -0
- package/dist-extensions/cropping_controls/croppingControls.mjs.map +1 -0
- package/dist-extensions/cropping_controls/croppingHandlers.mjs +228 -0
- package/dist-extensions/cropping_controls/croppingHandlers.mjs.map +1 -0
- package/dist-extensions/cropping_controls/enterCropMode.mjs +38 -0
- package/dist-extensions/cropping_controls/enterCropMode.mjs.map +1 -0
- package/dist-extensions/cropping_controls/renderCornerControl.mjs +45 -0
- package/dist-extensions/cropping_controls/renderCornerControl.mjs.map +1 -0
- package/dist-extensions/extensions/cropping_controls/croppingControls.d.ts +16 -0
- package/dist-extensions/extensions/cropping_controls/croppingControls.d.ts.map +1 -0
- package/dist-extensions/extensions/cropping_controls/croppingHandlers.d.ts +39 -0
- package/dist-extensions/extensions/cropping_controls/croppingHandlers.d.ts.map +1 -0
- package/dist-extensions/extensions/cropping_controls/enterCropMode.d.ts +7 -0
- package/dist-extensions/extensions/cropping_controls/enterCropMode.d.ts.map +1 -0
- package/dist-extensions/extensions/cropping_controls/renderCornerControl.d.ts +14 -0
- package/dist-extensions/extensions/cropping_controls/renderCornerControl.d.ts.map +1 -0
- package/dist-extensions/extensions/index.d.ts +3 -0
- package/dist-extensions/extensions/index.d.ts.map +1 -1
- package/dist-extensions/fabric-extensions.min.js +1 -1
- package/dist-extensions/fabric-extensions.min.js.map +1 -1
- package/dist-extensions/fabric.d.ts +1 -0
- package/dist-extensions/fabric.d.ts.map +1 -1
- package/dist-extensions/index.mjs +3 -0
- package/dist-extensions/index.mjs.map +1 -1
- package/dist-extensions/src/EventTypeDefs.d.ts +5 -0
- package/dist-extensions/src/EventTypeDefs.d.ts.map +1 -1
- package/dist-extensions/src/Pattern/Pattern.d.ts.map +1 -1
- package/dist-extensions/src/Shadow.d.ts +1 -1
- package/dist-extensions/src/Shadow.d.ts.map +1 -1
- package/dist-extensions/src/canvas/CanvasOptions.d.ts.map +1 -1
- package/dist-extensions/src/canvas/SelectableCanvas.d.ts +2 -0
- package/dist-extensions/src/canvas/SelectableCanvas.d.ts.map +1 -1
- package/dist-extensions/src/canvas/StaticCanvas.d.ts.map +1 -1
- package/dist-extensions/src/canvas/StaticCanvasOptions.d.ts.map +1 -1
- package/dist-extensions/src/constants.d.ts +1 -0
- package/dist-extensions/src/constants.d.ts.map +1 -1
- package/dist-extensions/src/controls/Control.d.ts +22 -1
- package/dist-extensions/src/controls/Control.d.ts.map +1 -1
- package/dist-extensions/src/controls/changeWidth.d.ts +22 -0
- package/dist-extensions/src/controls/changeWidth.d.ts.map +1 -1
- package/dist-extensions/src/controls/controlRendering.d.ts.map +1 -1
- package/dist-extensions/src/controls/index.d.ts +2 -1
- package/dist-extensions/src/controls/index.d.ts.map +1 -1
- package/dist-extensions/src/gradient/Gradient.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Circle.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Ellipse.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Group.d.ts.map +1 -1
- package/dist-extensions/src/shapes/IText/IText.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Image.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Line.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Object/FabricObjectSVGExportMixin.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Object/InteractiveObject.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Object/Object.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Object/types/FabricObjectProps.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Object/types/ObjectProps.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Path.d.ts +1 -1
- package/dist-extensions/src/shapes/Path.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Polyline.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Rect.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Text/StyledText.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Text/Text.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Text/TextSVGExportMixin.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Textbox.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Triangle.d.ts.map +1 -1
- package/dist-extensions/src/util/lang_string.d.ts +1 -1
- package/dist-extensions/src/util/lang_string.d.ts.map +1 -1
- package/dist-extensions/src/util/misc/svgParsing.d.ts.map +1 -1
- package/eslint.config.mjs +2 -0
- package/extensions/cropping_controls/croppingControls.spec.ts +115 -0
- package/extensions/cropping_controls/croppingControls.ts +150 -0
- package/extensions/cropping_controls/croppingHandlers.spec.ts +579 -0
- package/extensions/cropping_controls/croppingHandlers.ts +285 -0
- package/extensions/cropping_controls/enterCropMode.ts +30 -0
- package/extensions/cropping_controls/renderCornerControl.ts +53 -0
- package/extensions/index.ts +9 -0
- package/fabric.ts +1 -0
- package/package.json +17 -8
- package/src/ClassRegistry.spec.ts +18 -19
- package/src/EventTypeDefs.ts +15 -11
- package/src/Pattern/Pattern.spec.ts +12 -0
- package/src/Pattern/Pattern.ts +3 -2
- package/src/Shadow.ts +9 -8
- package/src/brushes/PencilBrush.spec.ts +11 -11
- package/src/canvas/Canvas-dispose.spec.ts +8 -7
- package/src/canvas/Canvas.spec.ts +27 -29
- package/src/canvas/CanvasOptions.ts +2 -1
- package/src/canvas/SelectableCanvas.ts +38 -15
- package/src/canvas/StaticCanvas.spec.ts +20 -0
- package/src/canvas/StaticCanvas.ts +7 -4
- package/src/canvas/StaticCanvasOptions.ts +1 -3
- package/src/constants.ts +1 -0
- package/src/controls/Control.spec.ts +102 -0
- package/src/controls/Control.ts +71 -2
- package/src/controls/changeHeight.spec.ts +147 -0
- package/src/controls/changeWidth.ts +68 -35
- package/src/controls/controlRendering.ts +20 -48
- package/src/controls/index.ts +7 -1
- package/src/gradient/Gradient.spec.ts +101 -46
- package/src/gradient/Gradient.ts +27 -14
- package/src/shapes/Circle.spec.ts +10 -39
- package/src/shapes/Circle.ts +11 -11
- package/src/shapes/Ellipse.spec.ts +8 -37
- package/src/shapes/Ellipse.ts +7 -7
- package/src/shapes/Group.ts +3 -3
- package/src/shapes/IText/IText-click-behavior.spec.ts +36 -49
- package/src/shapes/IText/IText.ts +5 -6
- package/src/shapes/IText/ITextKeyBehavior.test.ts +0 -1
- package/src/shapes/IText/__snapshots__/ITextBehavior.test.ts.snap +6 -6
- package/src/shapes/Image.spec.ts +17 -33
- package/src/shapes/Image.ts +15 -11
- package/src/shapes/Line.spec.ts +4 -30
- package/src/shapes/Line.ts +11 -16
- package/src/shapes/Object/FabricObjectSVGExportMixin.ts +11 -4
- package/src/shapes/Object/InteractiveObject.ts +4 -4
- package/src/shapes/Object/Object.ts +6 -5
- package/src/shapes/Object/ObjectGeometry.spec.ts +15 -0
- package/src/shapes/Object/ObjectGeometry.ts +1 -1
- package/src/shapes/Object/objectSvgExport.spec.ts +112 -0
- package/src/shapes/Object/types/FabricObjectProps.ts +1 -4
- package/src/shapes/Object/types/ObjectProps.ts +1 -3
- package/src/shapes/Path.spec.ts +4 -27
- package/src/shapes/Path.ts +2 -4
- package/src/shapes/Polygon.spec.ts +4 -31
- package/src/shapes/Polyline.spec.ts +4 -31
- package/src/shapes/Polyline.ts +11 -12
- package/src/shapes/Rect.spec.ts +25 -33
- package/src/shapes/Rect.ts +7 -7
- package/src/shapes/Text/StyledText.ts +0 -3
- package/src/shapes/Text/Text.spec.ts +3 -32
- package/src/shapes/Text/Text.ts +5 -6
- package/src/shapes/Text/TextSVGExportMixin.spec.ts +9 -0
- package/src/shapes/Text/TextSVGExportMixin.ts +14 -16
- package/src/shapes/Text/__snapshots__/Text.spec.ts.snap +1 -1
- package/src/shapes/Text/__snapshots__/TextSVGExportMixin.spec.ts.snap +1 -1
- package/src/shapes/Textbox.spec.ts +5 -5
- package/src/shapes/Textbox.ts +6 -5
- package/src/shapes/Triangle.ts +4 -4
- package/src/shapes/__snapshots__/Image.spec.ts.snap +4 -4
- package/src/shapes/__snapshots__/Textbox.spec.ts.snap +5 -5
- package/src/util/lang_string.ts +3 -2
- package/src/util/misc/svgParsing.ts +2 -1
- package/tsconfig.spec.json +1 -0
- package/vitest.config.ts +12 -2
- package/vitest.extend.ts +6 -2
package/dist/index.node.mjs
CHANGED
|
@@ -412,7 +412,7 @@ class Cache {
|
|
|
412
412
|
}
|
|
413
413
|
const cache = new Cache();
|
|
414
414
|
|
|
415
|
-
var version = "7.
|
|
415
|
+
var version = "7.2.0";
|
|
416
416
|
|
|
417
417
|
// use this syntax so babel plugin see this import here
|
|
418
418
|
const VERSION = version;
|
|
@@ -2247,6 +2247,111 @@ const staticCanvasDefaults = {
|
|
|
2247
2247
|
patternQuality: 'best'
|
|
2248
2248
|
};
|
|
2249
2249
|
|
|
2250
|
+
/**
|
|
2251
|
+
* Capitalizes a string
|
|
2252
|
+
* @param {String} string String to capitalize
|
|
2253
|
+
* @param {Boolean} [firstLetterOnly] If true only first letter is capitalized
|
|
2254
|
+
* and other letters stay untouched, if false first letter is capitalized
|
|
2255
|
+
* and other letters are converted to lowercase.
|
|
2256
|
+
* @return {String} Capitalized version of a string
|
|
2257
|
+
*/
|
|
2258
|
+
const capitalize = function (string) {
|
|
2259
|
+
let firstLetterOnly = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
2260
|
+
return `${string.charAt(0).toUpperCase()}${firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase()}`;
|
|
2261
|
+
};
|
|
2262
|
+
|
|
2263
|
+
/**
|
|
2264
|
+
* Escapes XML in a string
|
|
2265
|
+
* @param {String} string String to escape
|
|
2266
|
+
* @return {String} Escaped version of a string
|
|
2267
|
+
*/
|
|
2268
|
+
const escapeXml = stringOrNumber => stringOrNumber.toString().replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(/</g, '<').replace(/>/g, '>');
|
|
2269
|
+
let segmenter;
|
|
2270
|
+
const getSegmenter = () => {
|
|
2271
|
+
if (!segmenter) {
|
|
2272
|
+
segmenter = 'Intl' in getFabricWindow() && 'Segmenter' in Intl && new Intl.Segmenter(undefined, {
|
|
2273
|
+
granularity: 'grapheme'
|
|
2274
|
+
});
|
|
2275
|
+
}
|
|
2276
|
+
return segmenter;
|
|
2277
|
+
};
|
|
2278
|
+
|
|
2279
|
+
/**
|
|
2280
|
+
* Divide a string in the user perceived single units
|
|
2281
|
+
* @param {String} textstring String to escape
|
|
2282
|
+
* @return {Array} array containing the graphemes
|
|
2283
|
+
*/
|
|
2284
|
+
const graphemeSplit = textstring => {
|
|
2285
|
+
segmenter || getSegmenter();
|
|
2286
|
+
if (segmenter) {
|
|
2287
|
+
const segments = segmenter.segment(textstring);
|
|
2288
|
+
return Array.from(segments).map(_ref => {
|
|
2289
|
+
let {
|
|
2290
|
+
segment
|
|
2291
|
+
} = _ref;
|
|
2292
|
+
return segment;
|
|
2293
|
+
});
|
|
2294
|
+
}
|
|
2295
|
+
|
|
2296
|
+
//Fallback
|
|
2297
|
+
return graphemeSplitImpl(textstring);
|
|
2298
|
+
};
|
|
2299
|
+
const graphemeSplitImpl = textstring => {
|
|
2300
|
+
const graphemes = [];
|
|
2301
|
+
for (let i = 0, chr; i < textstring.length; i++) {
|
|
2302
|
+
if ((chr = getWholeChar(textstring, i)) === false) {
|
|
2303
|
+
continue;
|
|
2304
|
+
}
|
|
2305
|
+
graphemes.push(chr);
|
|
2306
|
+
}
|
|
2307
|
+
return graphemes;
|
|
2308
|
+
};
|
|
2309
|
+
|
|
2310
|
+
// taken from mdn in the charAt doc page.
|
|
2311
|
+
const getWholeChar = (str, i) => {
|
|
2312
|
+
const code = str.charCodeAt(i);
|
|
2313
|
+
if (isNaN(code)) {
|
|
2314
|
+
return ''; // Position not found
|
|
2315
|
+
}
|
|
2316
|
+
if (code < 0xd800 || code > 0xdfff) {
|
|
2317
|
+
return str.charAt(i);
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
// High surrogate (could change last hex to 0xDB7F to treat high private
|
|
2321
|
+
// surrogates as single characters)
|
|
2322
|
+
if (0xd800 <= code && code <= 0xdbff) {
|
|
2323
|
+
if (str.length <= i + 1) {
|
|
2324
|
+
throw 'High surrogate without following low surrogate';
|
|
2325
|
+
}
|
|
2326
|
+
const next = str.charCodeAt(i + 1);
|
|
2327
|
+
if (0xdc00 > next || next > 0xdfff) {
|
|
2328
|
+
throw 'High surrogate without following low surrogate';
|
|
2329
|
+
}
|
|
2330
|
+
return str.charAt(i) + str.charAt(i + 1);
|
|
2331
|
+
}
|
|
2332
|
+
// Low surrogate (0xDC00 <= code && code <= 0xDFFF)
|
|
2333
|
+
if (i === 0) {
|
|
2334
|
+
throw 'Low surrogate without preceding high surrogate';
|
|
2335
|
+
}
|
|
2336
|
+
const prev = str.charCodeAt(i - 1);
|
|
2337
|
+
|
|
2338
|
+
// (could change last hex to 0xDB7F to treat high private
|
|
2339
|
+
// surrogates as single characters)
|
|
2340
|
+
if (0xd800 > prev || prev > 0xdbff) {
|
|
2341
|
+
throw 'Low surrogate without preceding high surrogate';
|
|
2342
|
+
}
|
|
2343
|
+
// We can pass over low surrogates now as the second component
|
|
2344
|
+
// in a pair which we have already processed
|
|
2345
|
+
return false;
|
|
2346
|
+
};
|
|
2347
|
+
|
|
2348
|
+
var lang_string = /*#__PURE__*/Object.freeze({
|
|
2349
|
+
__proto__: null,
|
|
2350
|
+
capitalize: capitalize,
|
|
2351
|
+
escapeXml: escapeXml,
|
|
2352
|
+
graphemeSplit: graphemeSplit
|
|
2353
|
+
});
|
|
2354
|
+
|
|
2250
2355
|
/**
|
|
2251
2356
|
* Having both options in TCanvasSizeOptions set to true transform the call in a calcOffset
|
|
2252
2357
|
* Better try to restrict with types to avoid confusion.
|
|
@@ -3016,7 +3121,8 @@ let StaticCanvas$1 = class StaticCanvas extends createCollectionMixin(CommonMeth
|
|
|
3016
3121
|
this._setSVGPreamble(markup, options);
|
|
3017
3122
|
this._setSVGHeader(markup, options);
|
|
3018
3123
|
if (this.clipPath) {
|
|
3019
|
-
|
|
3124
|
+
var _this$clipPath$clipPa;
|
|
3125
|
+
markup.push(`<g clip-path="url(#${escapeXml((_this$clipPath$clipPa = this.clipPath.clipPathId) !== null && _this$clipPath$clipPa !== void 0 ? _this$clipPath$clipPa : '')})" >\n`);
|
|
3020
3126
|
}
|
|
3021
3127
|
this._setSVGBgOverlayColor(markup, 'background');
|
|
3022
3128
|
this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver);
|
|
@@ -3695,20 +3801,6 @@ const sendObjectToPlane = (object, from, to) => {
|
|
|
3695
3801
|
return t;
|
|
3696
3802
|
};
|
|
3697
3803
|
|
|
3698
|
-
const fireEvent = (eventName, options) => {
|
|
3699
|
-
var _target$canvas;
|
|
3700
|
-
const {
|
|
3701
|
-
transform: {
|
|
3702
|
-
target
|
|
3703
|
-
}
|
|
3704
|
-
} = options;
|
|
3705
|
-
(_target$canvas = target.canvas) === null || _target$canvas === void 0 || _target$canvas.fire(`object:${eventName}`, {
|
|
3706
|
-
...options,
|
|
3707
|
-
target
|
|
3708
|
-
});
|
|
3709
|
-
target.fire(eventName, options);
|
|
3710
|
-
};
|
|
3711
|
-
|
|
3712
3804
|
const originOffset = {
|
|
3713
3805
|
left: -0.5,
|
|
3714
3806
|
top: -0.5,
|
|
@@ -3911,33 +4003,6 @@ function getLocalPoint(_ref, originX, originY, x, y) {
|
|
|
3911
4003
|
return localPoint;
|
|
3912
4004
|
}
|
|
3913
4005
|
|
|
3914
|
-
/**
|
|
3915
|
-
* Action handler
|
|
3916
|
-
* @private
|
|
3917
|
-
* @param {Event} eventData javascript event that is doing the transform
|
|
3918
|
-
* @param {Object} transform javascript object containing a series of information around the current transform
|
|
3919
|
-
* @param {number} x current mouse x position, canvas normalized
|
|
3920
|
-
* @param {number} y current mouse y position, canvas normalized
|
|
3921
|
-
* @return {Boolean} true if the translation occurred
|
|
3922
|
-
*/
|
|
3923
|
-
const dragHandler = (eventData, transform, x, y) => {
|
|
3924
|
-
const {
|
|
3925
|
-
target,
|
|
3926
|
-
offsetX,
|
|
3927
|
-
offsetY
|
|
3928
|
-
} = transform,
|
|
3929
|
-
newLeft = x - offsetX,
|
|
3930
|
-
newTop = y - offsetY,
|
|
3931
|
-
moveX = !isLocked(target, 'lockMovementX') && target.left !== newLeft,
|
|
3932
|
-
moveY = !isLocked(target, 'lockMovementY') && target.top !== newTop;
|
|
3933
|
-
moveX && target.set(LEFT, newLeft);
|
|
3934
|
-
moveY && target.set(TOP, newTop);
|
|
3935
|
-
if (moveX || moveY) {
|
|
3936
|
-
fireEvent(MOVING, commonEventInfo(eventData, transform, x, y));
|
|
3937
|
-
}
|
|
3938
|
-
return moveX || moveY;
|
|
3939
|
-
};
|
|
3940
|
-
|
|
3941
4006
|
const normalizeWs = value => value.replace(/\s+/g, ' ');
|
|
3942
4007
|
|
|
3943
4008
|
/**
|
|
@@ -4684,7 +4749,7 @@ const colorPropToSVG = function (prop, value) {
|
|
|
4684
4749
|
if (!value) {
|
|
4685
4750
|
colorValue = 'none';
|
|
4686
4751
|
} else if (value.toLive) {
|
|
4687
|
-
colorValue = `url(#SVGID_${value.id})`;
|
|
4752
|
+
colorValue = `url(#SVGID_${escapeXml(value.id)})`;
|
|
4688
4753
|
} else {
|
|
4689
4754
|
const color = new Color(value),
|
|
4690
4755
|
opacity = color.getAlpha();
|
|
@@ -4737,7 +4802,7 @@ class FabricObjectSVGExportMixin {
|
|
|
4737
4802
|
filter = skipShadow ? '' : this.getSvgFilter(),
|
|
4738
4803
|
fill = colorPropToSVG(FILL, this.fill),
|
|
4739
4804
|
stroke = colorPropToSVG(STROKE, this.stroke);
|
|
4740
|
-
return [stroke, 'stroke-width: ', strokeWidth, '; ', 'stroke-dasharray: ', strokeDashArray, '; ', 'stroke-linecap: ', strokeLineCap, '; ', 'stroke-dashoffset: ', strokeDashOffset, '; ', 'stroke-linejoin: ', strokeLineJoin, '; ', 'stroke-miterlimit: ', strokeMiterLimit, '; ', fill, 'fill-rule: ', fillRule, '; ', 'opacity: ', opacity, ';', filter, visibility].join('');
|
|
4805
|
+
return [stroke, 'stroke-width: ', strokeWidth, '; ', 'stroke-dasharray: ', strokeDashArray, '; ', 'stroke-linecap: ', strokeLineCap, '; ', 'stroke-dashoffset: ', strokeDashOffset, '; ', 'stroke-linejoin: ', strokeLineJoin, '; ', 'stroke-miterlimit: ', strokeMiterLimit, '; ', fill, 'fill-rule: ', fillRule, '; ', 'opacity: ', opacity, ';', filter, visibility].map(v => escapeXml(v)).join('');
|
|
4741
4806
|
}
|
|
4742
4807
|
|
|
4743
4808
|
/**
|
|
@@ -4745,7 +4810,7 @@ class FabricObjectSVGExportMixin {
|
|
|
4745
4810
|
* @return {String}
|
|
4746
4811
|
*/
|
|
4747
4812
|
getSvgFilter() {
|
|
4748
|
-
return this.shadow ? `filter: url(#SVGID_${this.shadow.id});` : '';
|
|
4813
|
+
return this.shadow ? `filter: url(#SVGID_${escapeXml(this.shadow.id)});` : '';
|
|
4749
4814
|
}
|
|
4750
4815
|
|
|
4751
4816
|
/**
|
|
@@ -4753,7 +4818,7 @@ class FabricObjectSVGExportMixin {
|
|
|
4753
4818
|
* @return {String}
|
|
4754
4819
|
*/
|
|
4755
4820
|
getSvgCommons() {
|
|
4756
|
-
return [this.id ? `id="${this.id}" ` : '', this.clipPath ? `clip-path="url(#${this.clipPath.clipPathId})" ` : ''].join('');
|
|
4821
|
+
return [this.id ? `id="${escapeXml(String(this.id))}" ` : '', this.clipPath ? `clip-path="url(#${this.clipPath.clipPathId})" ` : ''].join('');
|
|
4757
4822
|
}
|
|
4758
4823
|
|
|
4759
4824
|
/**
|
|
@@ -4866,7 +4931,7 @@ class FabricObjectSVGExportMixin {
|
|
|
4866
4931
|
return reviver ? reviver(markup.join('')) : markup.join('');
|
|
4867
4932
|
}
|
|
4868
4933
|
addPaintOrder() {
|
|
4869
|
-
return this.paintFirst !== FILL ? ` paint-order="${this.paintFirst}" ` : '';
|
|
4934
|
+
return this.paintFirst !== FILL ? ` paint-order="${escapeXml(this.paintFirst)}" ` : '';
|
|
4870
4935
|
}
|
|
4871
4936
|
}
|
|
4872
4937
|
|
|
@@ -5004,7 +5069,6 @@ const reViewBoxAttrValue = new RegExp(String.raw`^\s*(${reNum})${viewportSeparat
|
|
|
5004
5069
|
|
|
5005
5070
|
(?:$|\s): This captures either the end of the line or a whitespace character. It ensures that the match ends either at the end of the string or with a whitespace character.
|
|
5006
5071
|
*/
|
|
5007
|
-
// eslint-disable-next-line max-len
|
|
5008
5072
|
|
|
5009
5073
|
const shadowOffsetRegex = '(-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?';
|
|
5010
5074
|
const reOffsetsAndBlur = new RegExp('(?:\\s|^)' + shadowOffsetRegex + shadowOffsetRegex + '(' + reNum + '?(?:px)?)?(?:\\s?|$)(?:$|\\s)');
|
|
@@ -5063,14 +5127,15 @@ class Shadow {
|
|
|
5063
5127
|
toSVG(object) {
|
|
5064
5128
|
const offset = rotateVector(new Point(this.offsetX, this.offsetY), degreesToRadians(-object.angle)),
|
|
5065
5129
|
BLUR_BOX = 20,
|
|
5130
|
+
NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS,
|
|
5066
5131
|
color = new Color(this.color);
|
|
5067
5132
|
let fBoxX = 40,
|
|
5068
5133
|
fBoxY = 40;
|
|
5069
5134
|
if (object.width && object.height) {
|
|
5070
5135
|
//http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion
|
|
5071
5136
|
// we add some extra space to filter box to contain the blur ( 20 )
|
|
5072
|
-
fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width,
|
|
5073
|
-
fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height,
|
|
5137
|
+
fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;
|
|
5138
|
+
fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;
|
|
5074
5139
|
}
|
|
5075
5140
|
if (object.flipX) {
|
|
5076
5141
|
offset.x *= -1;
|
|
@@ -5078,7 +5143,7 @@ class Shadow {
|
|
|
5078
5143
|
if (object.flipY) {
|
|
5079
5144
|
offset.y *= -1;
|
|
5080
5145
|
}
|
|
5081
|
-
return `<filter id="SVGID_${this.id}" y="-${fBoxY}%" height="${100 + 2 * fBoxY}%" x="-${fBoxX}%" width="${100 + 2 * fBoxX}%" >\n\t<feGaussianBlur in="SourceAlpha" stdDeviation="${toFixed(this.blur ? this.blur / 2 : 0,
|
|
5146
|
+
return `<filter id="SVGID_${escapeXml(this.id)}" y="-${fBoxY}%" height="${100 + 2 * fBoxY}%" x="-${fBoxX}%" width="${100 + 2 * fBoxX}%" >\n\t<feGaussianBlur in="SourceAlpha" stdDeviation="${toFixed(this.blur ? this.blur / 2 : 0, NUM_FRACTION_DIGITS)}"></feGaussianBlur>\n\t<feOffset dx="${toFixed(offset.x, NUM_FRACTION_DIGITS)}" dy="${toFixed(offset.y, NUM_FRACTION_DIGITS)}" result="oBlur" ></feOffset>\n\t<feFlood flood-color="${color.toRgb()}" flood-opacity="${color.getAlpha()}"/>\n\t<feComposite in2="oBlur" operator="in" />\n\t<feMerge>\n\t\t<feMergeNode></feMergeNode>\n\t\t<feMergeNode in="SourceGraphic"></feMergeNode>\n\t</feMerge>\n</filter>\n`;
|
|
5082
5147
|
}
|
|
5083
5148
|
|
|
5084
5149
|
/**
|
|
@@ -6488,7 +6553,7 @@ class ObjectGeometry extends CommonMethods {
|
|
|
6488
6553
|
calcOwnMatrix() {
|
|
6489
6554
|
const key = this.transformMatrixKey(true),
|
|
6490
6555
|
cache = this.ownMatrixCache;
|
|
6491
|
-
if (cache && cache.key === key) {
|
|
6556
|
+
if (cache && cache.key.every((x, i) => x === key[i])) {
|
|
6492
6557
|
return cache.value;
|
|
6493
6558
|
}
|
|
6494
6559
|
const center = this.getRelativeCenterPoint(),
|
|
@@ -7229,6 +7294,9 @@ let FabricObject$1 = class FabricObject extends ObjectGeometry {
|
|
|
7229
7294
|
} else {
|
|
7230
7295
|
this._renderBackground(ctx);
|
|
7231
7296
|
}
|
|
7297
|
+
this.fire('before:render', {
|
|
7298
|
+
ctx
|
|
7299
|
+
});
|
|
7232
7300
|
this._render(ctx);
|
|
7233
7301
|
this._drawClipPath(ctx, this.clipPath, context);
|
|
7234
7302
|
this.fill = originalFill;
|
|
@@ -8229,6 +8297,20 @@ _defineProperty(FabricObject$1, "customProperties", []);
|
|
|
8229
8297
|
classRegistry.setClass(FabricObject$1);
|
|
8230
8298
|
classRegistry.setClass(FabricObject$1, 'object');
|
|
8231
8299
|
|
|
8300
|
+
const fireEvent = (eventName, options) => {
|
|
8301
|
+
var _target$canvas;
|
|
8302
|
+
const {
|
|
8303
|
+
transform: {
|
|
8304
|
+
target
|
|
8305
|
+
}
|
|
8306
|
+
} = options;
|
|
8307
|
+
(_target$canvas = target.canvas) === null || _target$canvas === void 0 || _target$canvas.fire(`object:${eventName}`, {
|
|
8308
|
+
...options,
|
|
8309
|
+
target
|
|
8310
|
+
});
|
|
8311
|
+
target.fire(eventName, options);
|
|
8312
|
+
};
|
|
8313
|
+
|
|
8232
8314
|
/**
|
|
8233
8315
|
* Wrap an action handler with firing an event if the action is performed
|
|
8234
8316
|
* @param {TModificationEvents} eventName the event we want to fire
|
|
@@ -8271,34 +8353,62 @@ function wrapWithFixedAnchor(actionHandler) {
|
|
|
8271
8353
|
};
|
|
8272
8354
|
}
|
|
8273
8355
|
|
|
8274
|
-
|
|
8275
|
-
* Action handler to change object's width
|
|
8276
|
-
* Needs to be wrapped with `wrapWithFixedAnchor` to be effective
|
|
8277
|
-
* @param {Event} eventData javascript event that is doing the transform
|
|
8278
|
-
* @param {Object} transform javascript object containing a series of information around the current transform
|
|
8279
|
-
* @param {number} x current mouse x position, canvas normalized
|
|
8280
|
-
* @param {number} y current mouse y position, canvas normalized
|
|
8281
|
-
* @return {Boolean} true if some change happened
|
|
8282
|
-
*/
|
|
8283
|
-
const changeObjectWidth = (eventData, transform, x, y) => {
|
|
8356
|
+
const changeObjectDimensionGen = (dimension, origin, xorY, scale) => (eventData, transform, x, y) => {
|
|
8284
8357
|
const localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y);
|
|
8358
|
+
const localPointValue = localPoint[xorY];
|
|
8285
8359
|
// make sure the control changes width ONLY from it's side of target
|
|
8286
|
-
|
|
8360
|
+
const originValue = resolveOrigin(transform[origin]);
|
|
8361
|
+
if (originValue === 0 || originValue > 0 && localPointValue < 0 || originValue < 0 && localPointValue > 0) {
|
|
8287
8362
|
const {
|
|
8288
8363
|
target
|
|
8289
8364
|
} = transform,
|
|
8290
|
-
strokePadding = target.strokeWidth / (target.strokeUniform ? target
|
|
8365
|
+
strokePadding = target.strokeWidth / (target.strokeUniform ? target[scale] : 1),
|
|
8291
8366
|
multiplier = isTransformCentered(transform) ? 2 : 1,
|
|
8292
|
-
oldWidth = target
|
|
8293
|
-
newWidth = Math.abs(
|
|
8294
|
-
target.set(
|
|
8367
|
+
oldWidth = target[dimension],
|
|
8368
|
+
newWidth = Math.abs(localPointValue * multiplier / target[scale]) - strokePadding;
|
|
8369
|
+
target.set(dimension, Math.max(newWidth, 1));
|
|
8295
8370
|
// check against actual target width in case `newWidth` was rejected
|
|
8296
|
-
return oldWidth !== target
|
|
8371
|
+
return oldWidth !== target[dimension];
|
|
8297
8372
|
}
|
|
8298
8373
|
return false;
|
|
8299
8374
|
};
|
|
8375
|
+
|
|
8376
|
+
/**
|
|
8377
|
+
* Action handler to change object's width
|
|
8378
|
+
* Needs to be wrapped with `wrapWithFixedAnchor` to be effective
|
|
8379
|
+
* You want to use this only if you are building a new control handler and you want
|
|
8380
|
+
* to reuse some logic. use "changeWidth" if you are looking to just use a control for width
|
|
8381
|
+
* @param {Event} eventData javascript event that is doing the transform
|
|
8382
|
+
* @param {Object} transform javascript object containing a series of information around the current transform
|
|
8383
|
+
* @param {number} x current mouse x position, canvas normalized
|
|
8384
|
+
* @param {number} y current mouse y position, canvas normalized
|
|
8385
|
+
* @return {Boolean} true if some change happened
|
|
8386
|
+
*/
|
|
8387
|
+
const changeObjectWidth = changeObjectDimensionGen('width', 'originX', 'x', 'scaleX');
|
|
8388
|
+
|
|
8389
|
+
/**
|
|
8390
|
+
* Action handler to change object's height
|
|
8391
|
+
* Needs to be wrapped with `wrapWithFixedAnchor` to be effective
|
|
8392
|
+
* You want to use this only if you are building a new control handler and you want
|
|
8393
|
+
* to reuse some logic. use "changeHeight" if you are looking to just use a control for height
|
|
8394
|
+
* @param {Event} eventData javascript event that is doing the transform
|
|
8395
|
+
* @param {Object} transform javascript object containing a series of information around the current transform
|
|
8396
|
+
* @param {number} x current mouse x position, canvas normalized
|
|
8397
|
+
* @param {number} y current mouse y position, canvas normalized
|
|
8398
|
+
* @return {Boolean} true if some change happened
|
|
8399
|
+
*/
|
|
8400
|
+
const changeObjectHeight = changeObjectDimensionGen('height', 'originY', 'y', 'scaleY');
|
|
8401
|
+
|
|
8402
|
+
/**
|
|
8403
|
+
* Control handler for changing width
|
|
8404
|
+
*/
|
|
8300
8405
|
const changeWidth = wrapWithFireEvent(RESIZING, wrapWithFixedAnchor(changeObjectWidth));
|
|
8301
8406
|
|
|
8407
|
+
/**
|
|
8408
|
+
* Control handler for changing height
|
|
8409
|
+
*/
|
|
8410
|
+
const changeHeight = wrapWithFireEvent(RESIZING, wrapWithFixedAnchor(changeObjectHeight));
|
|
8411
|
+
|
|
8302
8412
|
/**
|
|
8303
8413
|
* Render a round control, as per fabric features.
|
|
8304
8414
|
* This function is written to respect object properties like transparentCorners, cornerSize
|
|
@@ -8311,33 +8421,24 @@ const changeWidth = wrapWithFireEvent(RESIZING, wrapWithFixedAnchor(changeObject
|
|
|
8311
8421
|
* @param {FabricObject} fabricObject the fabric object for which we are rendering controls
|
|
8312
8422
|
*/
|
|
8313
8423
|
function renderCircleControl(ctx, left, top, styleOverride, fabricObject) {
|
|
8314
|
-
styleOverride = styleOverride || {};
|
|
8315
|
-
const xSize = this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize,
|
|
8316
|
-
ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize,
|
|
8317
|
-
transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ? styleOverride.transparentCorners : fabricObject.transparentCorners,
|
|
8318
|
-
methodName = transparentCorners ? STROKE : FILL,
|
|
8319
|
-
stroke = !transparentCorners && (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor);
|
|
8320
|
-
let myLeft = left,
|
|
8321
|
-
myTop = top,
|
|
8322
|
-
size;
|
|
8323
8424
|
ctx.save();
|
|
8324
|
-
|
|
8325
|
-
|
|
8425
|
+
const {
|
|
8426
|
+
stroke,
|
|
8427
|
+
xSize,
|
|
8428
|
+
ySize,
|
|
8429
|
+
opName
|
|
8430
|
+
} = this.commonRenderProps(ctx, left, top, fabricObject, styleOverride);
|
|
8431
|
+
let size = xSize;
|
|
8326
8432
|
// TODO: use proper ellipse code.
|
|
8327
8433
|
if (xSize > ySize) {
|
|
8328
|
-
size = xSize;
|
|
8329
8434
|
ctx.scale(1.0, ySize / xSize);
|
|
8330
|
-
myTop = top * xSize / ySize;
|
|
8331
8435
|
} else if (ySize > xSize) {
|
|
8332
8436
|
size = ySize;
|
|
8333
8437
|
ctx.scale(xSize / ySize, 1.0);
|
|
8334
|
-
myLeft = left * ySize / xSize;
|
|
8335
|
-
} else {
|
|
8336
|
-
size = xSize;
|
|
8337
8438
|
}
|
|
8338
8439
|
ctx.beginPath();
|
|
8339
|
-
ctx.arc(
|
|
8340
|
-
ctx[
|
|
8440
|
+
ctx.arc(0, 0, size / 2, 0, twoMathPi, false);
|
|
8441
|
+
ctx[opName]();
|
|
8341
8442
|
if (stroke) {
|
|
8342
8443
|
ctx.stroke();
|
|
8343
8444
|
}
|
|
@@ -8356,25 +8457,19 @@ function renderCircleControl(ctx, left, top, styleOverride, fabricObject) {
|
|
|
8356
8457
|
* @param {FabricObject} fabricObject the fabric object for which we are rendering controls
|
|
8357
8458
|
*/
|
|
8358
8459
|
function renderSquareControl(ctx, left, top, styleOverride, fabricObject) {
|
|
8359
|
-
|
|
8360
|
-
const
|
|
8361
|
-
|
|
8362
|
-
|
|
8363
|
-
|
|
8364
|
-
|
|
8460
|
+
ctx.save();
|
|
8461
|
+
const {
|
|
8462
|
+
stroke,
|
|
8463
|
+
xSize,
|
|
8464
|
+
ySize,
|
|
8465
|
+
opName
|
|
8466
|
+
} = this.commonRenderProps(ctx, left, top, fabricObject, styleOverride),
|
|
8365
8467
|
xSizeBy2 = xSize / 2,
|
|
8366
8468
|
ySizeBy2 = ySize / 2;
|
|
8367
|
-
ctx.save();
|
|
8368
|
-
ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor || '';
|
|
8369
|
-
ctx.strokeStyle = styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor || '';
|
|
8370
|
-
ctx.translate(left, top);
|
|
8371
|
-
// angle is relative to canvas plane
|
|
8372
|
-
const angle = fabricObject.getTotalAngle();
|
|
8373
|
-
ctx.rotate(degreesToRadians(angle));
|
|
8374
8469
|
// this does not work, and fixed with ( && ) does not make sense.
|
|
8375
8470
|
// to have real transparent corners we need the controls on upperCanvas
|
|
8376
8471
|
// transparentCorners || ctx.clearRect(-xSizeBy2, -ySizeBy2, xSize, ySize);
|
|
8377
|
-
ctx[`${
|
|
8472
|
+
ctx[`${opName}Rect`](-xSizeBy2, -ySizeBy2, xSize, ySize);
|
|
8378
8473
|
if (stroke) {
|
|
8379
8474
|
ctx.strokeRect(-xSizeBy2, -ySizeBy2, xSize, ySize);
|
|
8380
8475
|
}
|
|
@@ -8492,6 +8587,14 @@ class Control {
|
|
|
8492
8587
|
_defineProperty(this, "withConnection", false);
|
|
8493
8588
|
Object.assign(this, options);
|
|
8494
8589
|
}
|
|
8590
|
+
getTransformAnchorPoint() {
|
|
8591
|
+
var _this$transformAnchor;
|
|
8592
|
+
return (// return the control transformAnchorPoint
|
|
8593
|
+
(_this$transformAnchor = this.transformAnchorPoint) !== null && _this$transformAnchor !== void 0 ? _this$transformAnchor :
|
|
8594
|
+
// otherwise will return the opposite origin of where the control is located.
|
|
8595
|
+
new Point(-this.x + 0.5, -this.y + 0.5)
|
|
8596
|
+
);
|
|
8597
|
+
}
|
|
8495
8598
|
|
|
8496
8599
|
/**
|
|
8497
8600
|
* The control actionHandler, provide one to handle action ( control being moved )
|
|
@@ -8634,6 +8737,41 @@ class Control {
|
|
|
8634
8737
|
};
|
|
8635
8738
|
}
|
|
8636
8739
|
|
|
8740
|
+
/**
|
|
8741
|
+
* This is an helper method to prepare the canvas to render a control
|
|
8742
|
+
* It detectes common control properties and sets the correct fill and
|
|
8743
|
+
* stroke styles on the context. It does not execute translations or
|
|
8744
|
+
* rotations since different controls need differnt combination of these.
|
|
8745
|
+
*/
|
|
8746
|
+
commonRenderProps(ctx, left, top, fabricObject) {
|
|
8747
|
+
let styleOverride = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
|
|
8748
|
+
const {
|
|
8749
|
+
cornerSize,
|
|
8750
|
+
cornerColor,
|
|
8751
|
+
transparentCorners,
|
|
8752
|
+
cornerStrokeColor
|
|
8753
|
+
} = styleOverride,
|
|
8754
|
+
sizeFromProps = cornerSize || fabricObject.cornerSize,
|
|
8755
|
+
xSize = this.sizeX || sizeFromProps,
|
|
8756
|
+
ySize = this.sizeY || sizeFromProps,
|
|
8757
|
+
transparent = typeof transparentCorners !== 'undefined' ? transparentCorners : fabricObject.transparentCorners,
|
|
8758
|
+
opName = transparent ? STROKE : FILL,
|
|
8759
|
+
strokeColor = cornerStrokeColor || fabricObject.cornerStrokeColor,
|
|
8760
|
+
stroke = !transparent && !!strokeColor;
|
|
8761
|
+
ctx.fillStyle = cornerColor || fabricObject.cornerColor || '';
|
|
8762
|
+
ctx.strokeStyle = strokeColor || '';
|
|
8763
|
+
ctx.translate(left, top);
|
|
8764
|
+
// angle is relative to canvas plane
|
|
8765
|
+
ctx.rotate(degreesToRadians(fabricObject.getTotalAngle()));
|
|
8766
|
+
return {
|
|
8767
|
+
stroke,
|
|
8768
|
+
xSize,
|
|
8769
|
+
ySize,
|
|
8770
|
+
transparentCorners: transparent,
|
|
8771
|
+
opName
|
|
8772
|
+
};
|
|
8773
|
+
}
|
|
8774
|
+
|
|
8637
8775
|
/**
|
|
8638
8776
|
* Render function for the control.
|
|
8639
8777
|
* When this function runs the context is unscaled. unrotate. Just retina scaled.
|
|
@@ -10273,136 +10411,31 @@ const cloneStyles = style => {
|
|
|
10273
10411
|
};
|
|
10274
10412
|
|
|
10275
10413
|
/**
|
|
10276
|
-
*
|
|
10277
|
-
* @param {
|
|
10278
|
-
* @param {
|
|
10279
|
-
*
|
|
10280
|
-
* and other letters are converted to lowercase.
|
|
10281
|
-
* @return {String} Capitalized version of a string
|
|
10414
|
+
* @param {Object} prevStyle first style to compare
|
|
10415
|
+
* @param {Object} thisStyle second style to compare
|
|
10416
|
+
* @param {boolean} forTextSpans whether to check overline, underline, and line-through properties
|
|
10417
|
+
* @return {boolean} true if the style changed
|
|
10282
10418
|
*/
|
|
10283
|
-
const
|
|
10284
|
-
let
|
|
10285
|
-
return
|
|
10419
|
+
const hasStyleChanged = function (prevStyle, thisStyle) {
|
|
10420
|
+
let forTextSpans = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
10421
|
+
return prevStyle.fill !== thisStyle.fill || prevStyle.stroke !== thisStyle.stroke || prevStyle.strokeWidth !== thisStyle.strokeWidth || prevStyle.fontSize !== thisStyle.fontSize || prevStyle.fontFamily !== thisStyle.fontFamily || prevStyle.fontWeight !== thisStyle.fontWeight || prevStyle.fontStyle !== thisStyle.fontStyle || prevStyle.textDecorationThickness !== thisStyle.textDecorationThickness || prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor || prevStyle.deltaY !== thisStyle.deltaY || forTextSpans && (prevStyle.overline !== thisStyle.overline || prevStyle.underline !== thisStyle.underline || prevStyle.linethrough !== thisStyle.linethrough);
|
|
10286
10422
|
};
|
|
10287
10423
|
|
|
10288
10424
|
/**
|
|
10289
|
-
*
|
|
10290
|
-
*
|
|
10291
|
-
*
|
|
10425
|
+
* Returns the array form of a text object's inline styles property with styles grouped in ranges
|
|
10426
|
+
* rather than per character. This format is less verbose, and is better suited for storage
|
|
10427
|
+
* so it is used in serialization (not during runtime).
|
|
10428
|
+
* @param {object} styles per character styles for a text object
|
|
10429
|
+
* @param {String} text the text string that the styles are applied to
|
|
10430
|
+
* @return {{start: number, end: number, style: object}[]}
|
|
10292
10431
|
*/
|
|
10293
|
-
const
|
|
10294
|
-
|
|
10295
|
-
|
|
10296
|
-
|
|
10297
|
-
|
|
10298
|
-
|
|
10299
|
-
|
|
10300
|
-
}
|
|
10301
|
-
return segmenter;
|
|
10302
|
-
};
|
|
10303
|
-
|
|
10304
|
-
/**
|
|
10305
|
-
* Divide a string in the user perceived single units
|
|
10306
|
-
* @param {String} textstring String to escape
|
|
10307
|
-
* @return {Array} array containing the graphemes
|
|
10308
|
-
*/
|
|
10309
|
-
const graphemeSplit = textstring => {
|
|
10310
|
-
segmenter || getSegmenter();
|
|
10311
|
-
if (segmenter) {
|
|
10312
|
-
const segments = segmenter.segment(textstring);
|
|
10313
|
-
return Array.from(segments).map(_ref => {
|
|
10314
|
-
let {
|
|
10315
|
-
segment
|
|
10316
|
-
} = _ref;
|
|
10317
|
-
return segment;
|
|
10318
|
-
});
|
|
10319
|
-
}
|
|
10320
|
-
|
|
10321
|
-
//Fallback
|
|
10322
|
-
return graphemeSplitImpl(textstring);
|
|
10323
|
-
};
|
|
10324
|
-
const graphemeSplitImpl = textstring => {
|
|
10325
|
-
const graphemes = [];
|
|
10326
|
-
for (let i = 0, chr; i < textstring.length; i++) {
|
|
10327
|
-
if ((chr = getWholeChar(textstring, i)) === false) {
|
|
10328
|
-
continue;
|
|
10329
|
-
}
|
|
10330
|
-
graphemes.push(chr);
|
|
10331
|
-
}
|
|
10332
|
-
return graphemes;
|
|
10333
|
-
};
|
|
10334
|
-
|
|
10335
|
-
// taken from mdn in the charAt doc page.
|
|
10336
|
-
const getWholeChar = (str, i) => {
|
|
10337
|
-
const code = str.charCodeAt(i);
|
|
10338
|
-
if (isNaN(code)) {
|
|
10339
|
-
return ''; // Position not found
|
|
10340
|
-
}
|
|
10341
|
-
if (code < 0xd800 || code > 0xdfff) {
|
|
10342
|
-
return str.charAt(i);
|
|
10343
|
-
}
|
|
10344
|
-
|
|
10345
|
-
// High surrogate (could change last hex to 0xDB7F to treat high private
|
|
10346
|
-
// surrogates as single characters)
|
|
10347
|
-
if (0xd800 <= code && code <= 0xdbff) {
|
|
10348
|
-
if (str.length <= i + 1) {
|
|
10349
|
-
throw 'High surrogate without following low surrogate';
|
|
10350
|
-
}
|
|
10351
|
-
const next = str.charCodeAt(i + 1);
|
|
10352
|
-
if (0xdc00 > next || next > 0xdfff) {
|
|
10353
|
-
throw 'High surrogate without following low surrogate';
|
|
10354
|
-
}
|
|
10355
|
-
return str.charAt(i) + str.charAt(i + 1);
|
|
10356
|
-
}
|
|
10357
|
-
// Low surrogate (0xDC00 <= code && code <= 0xDFFF)
|
|
10358
|
-
if (i === 0) {
|
|
10359
|
-
throw 'Low surrogate without preceding high surrogate';
|
|
10360
|
-
}
|
|
10361
|
-
const prev = str.charCodeAt(i - 1);
|
|
10362
|
-
|
|
10363
|
-
// (could change last hex to 0xDB7F to treat high private
|
|
10364
|
-
// surrogates as single characters)
|
|
10365
|
-
if (0xd800 > prev || prev > 0xdbff) {
|
|
10366
|
-
throw 'Low surrogate without preceding high surrogate';
|
|
10367
|
-
}
|
|
10368
|
-
// We can pass over low surrogates now as the second component
|
|
10369
|
-
// in a pair which we have already processed
|
|
10370
|
-
return false;
|
|
10371
|
-
};
|
|
10372
|
-
|
|
10373
|
-
var lang_string = /*#__PURE__*/Object.freeze({
|
|
10374
|
-
__proto__: null,
|
|
10375
|
-
capitalize: capitalize,
|
|
10376
|
-
escapeXml: escapeXml,
|
|
10377
|
-
graphemeSplit: graphemeSplit
|
|
10378
|
-
});
|
|
10379
|
-
|
|
10380
|
-
/**
|
|
10381
|
-
* @param {Object} prevStyle first style to compare
|
|
10382
|
-
* @param {Object} thisStyle second style to compare
|
|
10383
|
-
* @param {boolean} forTextSpans whether to check overline, underline, and line-through properties
|
|
10384
|
-
* @return {boolean} true if the style changed
|
|
10385
|
-
*/
|
|
10386
|
-
const hasStyleChanged = function (prevStyle, thisStyle) {
|
|
10387
|
-
let forTextSpans = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
10388
|
-
return prevStyle.fill !== thisStyle.fill || prevStyle.stroke !== thisStyle.stroke || prevStyle.strokeWidth !== thisStyle.strokeWidth || prevStyle.fontSize !== thisStyle.fontSize || prevStyle.fontFamily !== thisStyle.fontFamily || prevStyle.fontWeight !== thisStyle.fontWeight || prevStyle.fontStyle !== thisStyle.fontStyle || prevStyle.textDecorationThickness !== thisStyle.textDecorationThickness || prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor || prevStyle.deltaY !== thisStyle.deltaY || forTextSpans && (prevStyle.overline !== thisStyle.overline || prevStyle.underline !== thisStyle.underline || prevStyle.linethrough !== thisStyle.linethrough);
|
|
10389
|
-
};
|
|
10390
|
-
|
|
10391
|
-
/**
|
|
10392
|
-
* Returns the array form of a text object's inline styles property with styles grouped in ranges
|
|
10393
|
-
* rather than per character. This format is less verbose, and is better suited for storage
|
|
10394
|
-
* so it is used in serialization (not during runtime).
|
|
10395
|
-
* @param {object} styles per character styles for a text object
|
|
10396
|
-
* @param {String} text the text string that the styles are applied to
|
|
10397
|
-
* @return {{start: number, end: number, style: object}[]}
|
|
10398
|
-
*/
|
|
10399
|
-
const stylesToArray = (styles, text) => {
|
|
10400
|
-
const textLines = text.split('\n'),
|
|
10401
|
-
stylesArray = [];
|
|
10402
|
-
let charIndex = -1,
|
|
10403
|
-
prevStyle = {};
|
|
10404
|
-
// clone style structure to prevent mutation
|
|
10405
|
-
styles = cloneStyles(styles);
|
|
10432
|
+
const stylesToArray = (styles, text) => {
|
|
10433
|
+
const textLines = text.split('\n'),
|
|
10434
|
+
stylesArray = [];
|
|
10435
|
+
let charIndex = -1,
|
|
10436
|
+
prevStyle = {};
|
|
10437
|
+
// clone style structure to prevent mutation
|
|
10438
|
+
styles = cloneStyles(styles);
|
|
10406
10439
|
|
|
10407
10440
|
//loop through each textLine
|
|
10408
10441
|
for (let i = 0; i < textLines.length; i++) {
|
|
@@ -10960,7 +10993,7 @@ class Rect extends FabricObject {
|
|
|
10960
10993
|
rx,
|
|
10961
10994
|
ry
|
|
10962
10995
|
} = this;
|
|
10963
|
-
return ['<rect ', 'COMMON_PARTS', `x="${-width / 2}" y="${-height / 2}" rx="${rx}" ry="${ry}" width="${width}" height="${height}" />\n`];
|
|
10996
|
+
return ['<rect ', 'COMMON_PARTS', `x="${-width / 2}" y="${-height / 2}" rx="${escapeXml(rx)}" ry="${escapeXml(ry)}" width="${escapeXml(width)}" height="${escapeXml(height)}" />\n`];
|
|
10964
10997
|
}
|
|
10965
10998
|
|
|
10966
10999
|
/**
|
|
@@ -11925,7 +11958,7 @@ class Group extends createCollectionMixin(FabricObject) {
|
|
|
11925
11958
|
* @return {String}
|
|
11926
11959
|
*/
|
|
11927
11960
|
getSvgStyles() {
|
|
11928
|
-
const opacity = typeof this.opacity !== 'undefined' && this.opacity !== 1 ? `opacity: ${this.opacity};` : '',
|
|
11961
|
+
const opacity = typeof this.opacity !== 'undefined' && this.opacity !== 1 ? `opacity: ${escapeXml(this.opacity)};` : '',
|
|
11929
11962
|
visibility = this.visible ? '' : ' visibility: hidden;';
|
|
11930
11963
|
return [opacity, this.getSvgFilter(), visibility].join('');
|
|
11931
11964
|
}
|
|
@@ -13227,6 +13260,288 @@ const canvasDefaults = {
|
|
|
13227
13260
|
preserveObjectStacking: true
|
|
13228
13261
|
};
|
|
13229
13262
|
|
|
13263
|
+
/**
|
|
13264
|
+
* Action handler
|
|
13265
|
+
* @private
|
|
13266
|
+
* @param {Event} eventData javascript event that is doing the transform
|
|
13267
|
+
* @param {Object} transform javascript object containing a series of information around the current transform
|
|
13268
|
+
* @param {number} x current mouse x position, canvas normalized
|
|
13269
|
+
* @param {number} y current mouse y position, canvas normalized
|
|
13270
|
+
* @return {Boolean} true if the translation occurred
|
|
13271
|
+
*/
|
|
13272
|
+
const dragHandler = (eventData, transform, x, y) => {
|
|
13273
|
+
const {
|
|
13274
|
+
target,
|
|
13275
|
+
offsetX,
|
|
13276
|
+
offsetY
|
|
13277
|
+
} = transform,
|
|
13278
|
+
newLeft = x - offsetX,
|
|
13279
|
+
newTop = y - offsetY,
|
|
13280
|
+
moveX = !isLocked(target, 'lockMovementX') && target.left !== newLeft,
|
|
13281
|
+
moveY = !isLocked(target, 'lockMovementY') && target.top !== newTop;
|
|
13282
|
+
moveX && target.set(LEFT, newLeft);
|
|
13283
|
+
moveY && target.set(TOP, newTop);
|
|
13284
|
+
if (moveX || moveY) {
|
|
13285
|
+
fireEvent(MOVING, commonEventInfo(eventData, transform, x, y));
|
|
13286
|
+
}
|
|
13287
|
+
return moveX || moveY;
|
|
13288
|
+
};
|
|
13289
|
+
|
|
13290
|
+
const ACTION_NAME$1 = MODIFY_POLY;
|
|
13291
|
+
/**
|
|
13292
|
+
* This function locates the controls.
|
|
13293
|
+
* It'll be used both for drawing and for interaction.
|
|
13294
|
+
*/
|
|
13295
|
+
const createPolyPositionHandler = pointIndex => {
|
|
13296
|
+
return function (dim, finalMatrix, polyObject) {
|
|
13297
|
+
const {
|
|
13298
|
+
points,
|
|
13299
|
+
pathOffset
|
|
13300
|
+
} = polyObject;
|
|
13301
|
+
return new Point(points[pointIndex]).subtract(pathOffset).transform(multiplyTransformMatrices(polyObject.getViewportTransform(), polyObject.calcTransformMatrix()));
|
|
13302
|
+
};
|
|
13303
|
+
};
|
|
13304
|
+
|
|
13305
|
+
/**
|
|
13306
|
+
* This function defines what the control does.
|
|
13307
|
+
* It'll be called on every mouse move after a control has been clicked and is being dragged.
|
|
13308
|
+
* The function receives as argument the mouse event, the current transform object
|
|
13309
|
+
* and the current position in canvas coordinate `transform.target` is a reference to the
|
|
13310
|
+
* current object being transformed.
|
|
13311
|
+
*/
|
|
13312
|
+
const polyActionHandler = (eventData, transform, x, y) => {
|
|
13313
|
+
const {
|
|
13314
|
+
target,
|
|
13315
|
+
pointIndex
|
|
13316
|
+
} = transform;
|
|
13317
|
+
const poly = target;
|
|
13318
|
+
const mouseLocalPosition = sendPointToPlane(new Point(x, y), undefined, poly.calcOwnMatrix());
|
|
13319
|
+
poly.points[pointIndex] = mouseLocalPosition.add(poly.pathOffset);
|
|
13320
|
+
poly.setDimensions();
|
|
13321
|
+
poly.set('dirty', true);
|
|
13322
|
+
return true;
|
|
13323
|
+
};
|
|
13324
|
+
|
|
13325
|
+
/**
|
|
13326
|
+
* Keep the polygon in the same position when we change its `width`/`height`/`top`/`left`.
|
|
13327
|
+
*/
|
|
13328
|
+
const factoryPolyActionHandler = (pointIndex, fn) => {
|
|
13329
|
+
return function (eventData, transform, x, y) {
|
|
13330
|
+
const poly = transform.target,
|
|
13331
|
+
anchorPoint = new Point(poly.points[(pointIndex > 0 ? pointIndex : poly.points.length) - 1]),
|
|
13332
|
+
anchorPointInParentPlane = anchorPoint.subtract(poly.pathOffset).transform(poly.calcOwnMatrix()),
|
|
13333
|
+
actionPerformed = fn(eventData, {
|
|
13334
|
+
...transform,
|
|
13335
|
+
pointIndex
|
|
13336
|
+
}, x, y);
|
|
13337
|
+
const newAnchorPointInParentPlane = anchorPoint.subtract(poly.pathOffset).transform(poly.calcOwnMatrix());
|
|
13338
|
+
const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane);
|
|
13339
|
+
poly.left -= diff.x;
|
|
13340
|
+
poly.top -= diff.y;
|
|
13341
|
+
return actionPerformed;
|
|
13342
|
+
};
|
|
13343
|
+
};
|
|
13344
|
+
const createPolyActionHandler = pointIndex => wrapWithFireEvent(ACTION_NAME$1, factoryPolyActionHandler(pointIndex, polyActionHandler));
|
|
13345
|
+
function createPolyControls(arg0) {
|
|
13346
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
13347
|
+
const controls = {};
|
|
13348
|
+
for (let idx = 0; idx < (typeof arg0 === 'number' ? arg0 : arg0.points.length); idx++) {
|
|
13349
|
+
controls[`p${idx}`] = new Control({
|
|
13350
|
+
actionName: ACTION_NAME$1,
|
|
13351
|
+
positionHandler: createPolyPositionHandler(idx),
|
|
13352
|
+
actionHandler: createPolyActionHandler(idx),
|
|
13353
|
+
...options
|
|
13354
|
+
});
|
|
13355
|
+
}
|
|
13356
|
+
return controls;
|
|
13357
|
+
}
|
|
13358
|
+
|
|
13359
|
+
const ACTION_NAME = 'modifyPath';
|
|
13360
|
+
const calcPathPointPosition = (pathObject, commandIndex, pointIndex) => {
|
|
13361
|
+
const {
|
|
13362
|
+
path,
|
|
13363
|
+
pathOffset
|
|
13364
|
+
} = pathObject;
|
|
13365
|
+
const command = path[commandIndex];
|
|
13366
|
+
return new Point(command[pointIndex] - pathOffset.x, command[pointIndex + 1] - pathOffset.y).transform(multiplyTransformMatrices(pathObject.getViewportTransform(), pathObject.calcTransformMatrix()));
|
|
13367
|
+
};
|
|
13368
|
+
const movePathPoint = (pathObject, x, y, commandIndex, pointIndex) => {
|
|
13369
|
+
const {
|
|
13370
|
+
path,
|
|
13371
|
+
pathOffset
|
|
13372
|
+
} = pathObject;
|
|
13373
|
+
const anchorCommand = path[(commandIndex > 0 ? commandIndex : path.length) - 1];
|
|
13374
|
+
const anchorPoint = new Point(anchorCommand[pointIndex], anchorCommand[pointIndex + 1]);
|
|
13375
|
+
const anchorPointInParentPlane = anchorPoint.subtract(pathOffset).transform(pathObject.calcOwnMatrix());
|
|
13376
|
+
const mouseLocalPosition = sendPointToPlane(new Point(x, y), undefined, pathObject.calcOwnMatrix());
|
|
13377
|
+
path[commandIndex][pointIndex] = mouseLocalPosition.x + pathOffset.x;
|
|
13378
|
+
path[commandIndex][pointIndex + 1] = mouseLocalPosition.y + pathOffset.y;
|
|
13379
|
+
pathObject.setDimensions();
|
|
13380
|
+
const newAnchorPointInParentPlane = anchorPoint.subtract(pathObject.pathOffset).transform(pathObject.calcOwnMatrix());
|
|
13381
|
+
const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane);
|
|
13382
|
+
pathObject.left -= diff.x;
|
|
13383
|
+
pathObject.top -= diff.y;
|
|
13384
|
+
pathObject.set('dirty', true);
|
|
13385
|
+
return true;
|
|
13386
|
+
};
|
|
13387
|
+
|
|
13388
|
+
/**
|
|
13389
|
+
* This function locates the controls.
|
|
13390
|
+
* It'll be used both for drawing and for interaction.
|
|
13391
|
+
*/
|
|
13392
|
+
function pathPositionHandler(dim, finalMatrix, pathObject) {
|
|
13393
|
+
const {
|
|
13394
|
+
commandIndex,
|
|
13395
|
+
pointIndex
|
|
13396
|
+
} = this;
|
|
13397
|
+
return calcPathPointPosition(pathObject, commandIndex, pointIndex);
|
|
13398
|
+
}
|
|
13399
|
+
|
|
13400
|
+
/**
|
|
13401
|
+
* This function defines what the control does.
|
|
13402
|
+
* It'll be called on every mouse move after a control has been clicked and is being dragged.
|
|
13403
|
+
* The function receives as argument the mouse event, the current transform object
|
|
13404
|
+
* and the current position in canvas coordinate `transform.target` is a reference to the
|
|
13405
|
+
* current object being transformed.
|
|
13406
|
+
*/
|
|
13407
|
+
function pathActionHandler(eventData, transform, x, y) {
|
|
13408
|
+
const {
|
|
13409
|
+
target
|
|
13410
|
+
} = transform;
|
|
13411
|
+
const {
|
|
13412
|
+
commandIndex,
|
|
13413
|
+
pointIndex
|
|
13414
|
+
} = this;
|
|
13415
|
+
const actionPerformed = movePathPoint(target, x, y, commandIndex, pointIndex);
|
|
13416
|
+
{
|
|
13417
|
+
fireEvent(this.actionName, {
|
|
13418
|
+
...commonEventInfo(eventData, transform, x, y),
|
|
13419
|
+
commandIndex,
|
|
13420
|
+
pointIndex
|
|
13421
|
+
});
|
|
13422
|
+
}
|
|
13423
|
+
return actionPerformed;
|
|
13424
|
+
}
|
|
13425
|
+
const indexFromPrevCommand = previousCommandType => previousCommandType === 'C' ? 5 : previousCommandType === 'Q' ? 3 : 1;
|
|
13426
|
+
class PathPointControl extends Control {
|
|
13427
|
+
constructor(options) {
|
|
13428
|
+
super(options);
|
|
13429
|
+
}
|
|
13430
|
+
render(ctx, left, top, styleOverride, fabricObject) {
|
|
13431
|
+
const overrides = {
|
|
13432
|
+
...styleOverride,
|
|
13433
|
+
cornerColor: this.controlFill,
|
|
13434
|
+
cornerStrokeColor: this.controlStroke,
|
|
13435
|
+
transparentCorners: !this.controlFill
|
|
13436
|
+
};
|
|
13437
|
+
super.render(ctx, left, top, overrides, fabricObject);
|
|
13438
|
+
}
|
|
13439
|
+
}
|
|
13440
|
+
class PathControlPointControl extends PathPointControl {
|
|
13441
|
+
constructor(options) {
|
|
13442
|
+
super(options);
|
|
13443
|
+
}
|
|
13444
|
+
render(ctx, left, top, styleOverride, fabricObject) {
|
|
13445
|
+
const {
|
|
13446
|
+
path
|
|
13447
|
+
} = fabricObject;
|
|
13448
|
+
const {
|
|
13449
|
+
commandIndex,
|
|
13450
|
+
pointIndex,
|
|
13451
|
+
connectToCommandIndex,
|
|
13452
|
+
connectToPointIndex
|
|
13453
|
+
} = this;
|
|
13454
|
+
ctx.save();
|
|
13455
|
+
ctx.strokeStyle = this.controlStroke;
|
|
13456
|
+
if (this.connectionDashArray) {
|
|
13457
|
+
ctx.setLineDash(this.connectionDashArray);
|
|
13458
|
+
}
|
|
13459
|
+
const [commandType] = path[commandIndex];
|
|
13460
|
+
const point = calcPathPointPosition(fabricObject, connectToCommandIndex, connectToPointIndex);
|
|
13461
|
+
if (commandType === 'Q') {
|
|
13462
|
+
// one control point connects to 2 points
|
|
13463
|
+
const point2 = calcPathPointPosition(fabricObject, commandIndex, pointIndex + 2);
|
|
13464
|
+
ctx.moveTo(point2.x, point2.y);
|
|
13465
|
+
ctx.lineTo(left, top);
|
|
13466
|
+
} else {
|
|
13467
|
+
ctx.moveTo(left, top);
|
|
13468
|
+
}
|
|
13469
|
+
ctx.lineTo(point.x, point.y);
|
|
13470
|
+
ctx.stroke();
|
|
13471
|
+
ctx.restore();
|
|
13472
|
+
super.render(ctx, left, top, styleOverride, fabricObject);
|
|
13473
|
+
}
|
|
13474
|
+
}
|
|
13475
|
+
const createControl = (commandIndexPos, pointIndexPos, isControlPoint, options, connectToCommandIndex, connectToPointIndex) => new (isControlPoint ? PathControlPointControl : PathPointControl)({
|
|
13476
|
+
commandIndex: commandIndexPos,
|
|
13477
|
+
pointIndex: pointIndexPos,
|
|
13478
|
+
actionName: ACTION_NAME,
|
|
13479
|
+
positionHandler: pathPositionHandler,
|
|
13480
|
+
actionHandler: pathActionHandler,
|
|
13481
|
+
connectToCommandIndex,
|
|
13482
|
+
connectToPointIndex,
|
|
13483
|
+
...options,
|
|
13484
|
+
...(isControlPoint ? options.controlPointStyle : options.pointStyle)
|
|
13485
|
+
});
|
|
13486
|
+
function createPathControls(path) {
|
|
13487
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
13488
|
+
const controls = {};
|
|
13489
|
+
let previousCommandType = 'M';
|
|
13490
|
+
path.path.forEach((command, commandIndex) => {
|
|
13491
|
+
const commandType = command[0];
|
|
13492
|
+
if (commandType !== 'Z') {
|
|
13493
|
+
controls[`c_${commandIndex}_${commandType}`] = createControl(commandIndex, command.length - 2, false, options);
|
|
13494
|
+
}
|
|
13495
|
+
switch (commandType) {
|
|
13496
|
+
case 'C':
|
|
13497
|
+
controls[`c_${commandIndex}_C_CP_1`] = createControl(commandIndex, 1, true, options, commandIndex - 1, indexFromPrevCommand(previousCommandType));
|
|
13498
|
+
controls[`c_${commandIndex}_C_CP_2`] = createControl(commandIndex, 3, true, options, commandIndex, 5);
|
|
13499
|
+
break;
|
|
13500
|
+
case 'Q':
|
|
13501
|
+
controls[`c_${commandIndex}_Q_CP_1`] = createControl(commandIndex, 1, true, options, commandIndex, 3);
|
|
13502
|
+
break;
|
|
13503
|
+
}
|
|
13504
|
+
previousCommandType = commandType;
|
|
13505
|
+
});
|
|
13506
|
+
return controls;
|
|
13507
|
+
}
|
|
13508
|
+
|
|
13509
|
+
var index = /*#__PURE__*/Object.freeze({
|
|
13510
|
+
__proto__: null,
|
|
13511
|
+
changeHeight: changeHeight,
|
|
13512
|
+
changeObjectHeight: changeObjectHeight,
|
|
13513
|
+
changeObjectWidth: changeObjectWidth,
|
|
13514
|
+
changeWidth: changeWidth,
|
|
13515
|
+
createObjectDefaultControls: createObjectDefaultControls,
|
|
13516
|
+
createPathControls: createPathControls,
|
|
13517
|
+
createPolyActionHandler: createPolyActionHandler,
|
|
13518
|
+
createPolyControls: createPolyControls,
|
|
13519
|
+
createPolyPositionHandler: createPolyPositionHandler,
|
|
13520
|
+
createResizeControls: createResizeControls,
|
|
13521
|
+
createTextboxDefaultControls: createTextboxDefaultControls,
|
|
13522
|
+
dragHandler: dragHandler,
|
|
13523
|
+
factoryPolyActionHandler: factoryPolyActionHandler,
|
|
13524
|
+
getLocalPoint: getLocalPoint,
|
|
13525
|
+
polyActionHandler: polyActionHandler,
|
|
13526
|
+
renderCircleControl: renderCircleControl,
|
|
13527
|
+
renderSquareControl: renderSquareControl,
|
|
13528
|
+
rotationStyleHandler: rotationStyleHandler,
|
|
13529
|
+
rotationWithSnapping: rotationWithSnapping,
|
|
13530
|
+
scaleCursorStyleHandler: scaleCursorStyleHandler,
|
|
13531
|
+
scaleOrSkewActionName: scaleOrSkewActionName,
|
|
13532
|
+
scaleSkewCursorStyleHandler: scaleSkewCursorStyleHandler,
|
|
13533
|
+
scalingEqually: scalingEqually,
|
|
13534
|
+
scalingX: scalingX,
|
|
13535
|
+
scalingXOrSkewingY: scalingXOrSkewingY,
|
|
13536
|
+
scalingY: scalingY,
|
|
13537
|
+
scalingYOrSkewingX: scalingYOrSkewingX,
|
|
13538
|
+
skewCursorStyleHandler: skewCursorStyleHandler,
|
|
13539
|
+
skewHandlerX: skewHandlerX,
|
|
13540
|
+
skewHandlerY: skewHandlerY,
|
|
13541
|
+
wrapWithFireEvent: wrapWithFireEvent,
|
|
13542
|
+
wrapWithFixedAnchor: wrapWithFixedAnchor
|
|
13543
|
+
});
|
|
13544
|
+
|
|
13230
13545
|
/**
|
|
13231
13546
|
* Canvas class
|
|
13232
13547
|
* @class Canvas
|
|
@@ -13597,11 +13912,13 @@ class SelectableCanvas extends StaticCanvas$1 {
|
|
|
13597
13912
|
* Given the control clicked, determine the origin of the transform.
|
|
13598
13913
|
* This is bad because controls can totally have custom names
|
|
13599
13914
|
* should disappear before release 4.0
|
|
13915
|
+
* Fabric 7.1, jan 2026 we are still using this.
|
|
13916
|
+
* Needs to go.
|
|
13600
13917
|
* @private
|
|
13601
13918
|
* @deprecated
|
|
13602
13919
|
*/
|
|
13603
13920
|
_getOriginFromCorner(target, controlName) {
|
|
13604
|
-
const origin = {
|
|
13921
|
+
const origin = controlName ? target.controls[controlName].getTransformAnchorPoint() : {
|
|
13605
13922
|
x: target.originX,
|
|
13606
13923
|
y: target.originY
|
|
13607
13924
|
};
|
|
@@ -13609,6 +13926,9 @@ class SelectableCanvas extends StaticCanvas$1 {
|
|
|
13609
13926
|
return origin;
|
|
13610
13927
|
}
|
|
13611
13928
|
|
|
13929
|
+
// this part down here is deprecated.
|
|
13930
|
+
// It is left to do not change the standard behavior in the middle of a major version
|
|
13931
|
+
// but when possible `getTransformAnchorPoint` will be the only source of truth
|
|
13612
13932
|
// is a left control ?
|
|
13613
13933
|
if (['ml', 'tl', 'bl'].includes(controlName)) {
|
|
13614
13934
|
origin.x = RIGHT;
|
|
@@ -13648,37 +13968,52 @@ class SelectableCanvas extends StaticCanvas$1 {
|
|
|
13648
13968
|
x: CENTER,
|
|
13649
13969
|
y: CENTER
|
|
13650
13970
|
} : this._getOriginFromCorner(target, corner),
|
|
13971
|
+
{
|
|
13972
|
+
scaleX,
|
|
13973
|
+
scaleY,
|
|
13974
|
+
skewX,
|
|
13975
|
+
skewY,
|
|
13976
|
+
left,
|
|
13977
|
+
top,
|
|
13978
|
+
angle,
|
|
13979
|
+
width,
|
|
13980
|
+
height,
|
|
13981
|
+
cropX,
|
|
13982
|
+
cropY
|
|
13983
|
+
} = target,
|
|
13651
13984
|
/**
|
|
13652
13985
|
* relative to target's containing coordinate plane
|
|
13653
13986
|
* both agree on every point
|
|
13654
13987
|
**/
|
|
13655
13988
|
transform = {
|
|
13656
|
-
target
|
|
13989
|
+
target,
|
|
13657
13990
|
action,
|
|
13658
13991
|
actionHandler,
|
|
13659
13992
|
actionPerformed: false,
|
|
13660
13993
|
corner,
|
|
13661
|
-
scaleX
|
|
13662
|
-
scaleY
|
|
13663
|
-
skewX
|
|
13664
|
-
skewY
|
|
13665
|
-
offsetX: pointer.x -
|
|
13666
|
-
offsetY: pointer.y -
|
|
13994
|
+
scaleX,
|
|
13995
|
+
scaleY,
|
|
13996
|
+
skewX,
|
|
13997
|
+
skewY,
|
|
13998
|
+
offsetX: pointer.x - left,
|
|
13999
|
+
offsetY: pointer.y - top,
|
|
13667
14000
|
originX: origin.x,
|
|
13668
14001
|
originY: origin.y,
|
|
13669
14002
|
ex: pointer.x,
|
|
13670
14003
|
ey: pointer.y,
|
|
13671
14004
|
lastX: pointer.x,
|
|
13672
14005
|
lastY: pointer.y,
|
|
13673
|
-
theta: degreesToRadians(
|
|
13674
|
-
width
|
|
13675
|
-
height
|
|
14006
|
+
theta: degreesToRadians(angle),
|
|
14007
|
+
width,
|
|
14008
|
+
height,
|
|
13676
14009
|
shiftKey: e.shiftKey,
|
|
13677
14010
|
altKey,
|
|
13678
14011
|
original: {
|
|
13679
14012
|
...saveObjectTransform(target),
|
|
13680
14013
|
originX: origin.x,
|
|
13681
|
-
originY: origin.y
|
|
14014
|
+
originY: origin.y,
|
|
14015
|
+
cropX,
|
|
14016
|
+
cropY
|
|
13682
14017
|
}
|
|
13683
14018
|
};
|
|
13684
14019
|
this._currentTransform = transform;
|
|
@@ -16091,7 +16426,8 @@ class Gradient {
|
|
|
16091
16426
|
}
|
|
16092
16427
|
transform[4] -= offsetX;
|
|
16093
16428
|
transform[5] -= offsetY;
|
|
16094
|
-
const commonAttributes = [`id="SVGID_${this.id}"`, `gradientUnits="${gradientUnits}"`, `gradientTransform="${preTransform ? preTransform + ' ' : ''}${matrixToSVG(transform)}"`, ''].join(' ');
|
|
16429
|
+
const commonAttributes = [`id="SVGID_${escapeXml(String(this.id))}"`, `gradientUnits="${gradientUnits}"`, `gradientTransform="${preTransform ? preTransform + ' ' : ''}${matrixToSVG(transform)}"`, ''].join(' ');
|
|
16430
|
+
const sanitizeCoord = value => parseFloat(String(value));
|
|
16095
16431
|
if (this.type === 'linear') {
|
|
16096
16432
|
const {
|
|
16097
16433
|
x1,
|
|
@@ -16099,7 +16435,11 @@ class Gradient {
|
|
|
16099
16435
|
x2,
|
|
16100
16436
|
y2
|
|
16101
16437
|
} = this.coords;
|
|
16102
|
-
|
|
16438
|
+
const sx1 = sanitizeCoord(x1);
|
|
16439
|
+
const sy1 = sanitizeCoord(y1);
|
|
16440
|
+
const sx2 = sanitizeCoord(x2);
|
|
16441
|
+
const sy2 = sanitizeCoord(y2);
|
|
16442
|
+
markup.push('<linearGradient ', commonAttributes, ' x1="', sx1, '" y1="', sy1, '" x2="', sx2, '" y2="', sy2, '">\n');
|
|
16103
16443
|
} else if (this.type === 'radial') {
|
|
16104
16444
|
const {
|
|
16105
16445
|
x1,
|
|
@@ -16109,9 +16449,15 @@ class Gradient {
|
|
|
16109
16449
|
r1,
|
|
16110
16450
|
r2
|
|
16111
16451
|
} = this.coords;
|
|
16112
|
-
const
|
|
16452
|
+
const sx1 = sanitizeCoord(x1);
|
|
16453
|
+
const sy1 = sanitizeCoord(y1);
|
|
16454
|
+
const sx2 = sanitizeCoord(x2);
|
|
16455
|
+
const sy2 = sanitizeCoord(y2);
|
|
16456
|
+
const sr1 = sanitizeCoord(r1);
|
|
16457
|
+
const sr2 = sanitizeCoord(r2);
|
|
16458
|
+
const needsSwap = sr1 > sr2;
|
|
16113
16459
|
// svg radial gradient has just 1 radius. the biggest.
|
|
16114
|
-
markup.push('<radialGradient ', commonAttributes, ' cx="', needsSwap ?
|
|
16460
|
+
markup.push('<radialGradient ', commonAttributes, ' cx="', needsSwap ? sx1 : sx2, '" cy="', needsSwap ? sy1 : sy2, '" r="', needsSwap ? sr1 : sr2, '" fx="', needsSwap ? sx2 : sx1, '" fy="', needsSwap ? sy2 : sy1, '">\n');
|
|
16115
16461
|
if (needsSwap) {
|
|
16116
16462
|
// svg goes from internal to external radius. if radius are inverted, swap color stops.
|
|
16117
16463
|
colorStops.reverse(); // mutates array
|
|
@@ -16119,16 +16465,17 @@ class Gradient {
|
|
|
16119
16465
|
colorStop.offset = 1 - colorStop.offset;
|
|
16120
16466
|
});
|
|
16121
16467
|
}
|
|
16122
|
-
const minRadius = Math.min(
|
|
16468
|
+
const minRadius = Math.min(sr1, sr2);
|
|
16123
16469
|
if (minRadius > 0) {
|
|
16124
16470
|
// i have to shift all colorStops and add new one in 0.
|
|
16125
|
-
const maxRadius = Math.max(
|
|
16471
|
+
const maxRadius = Math.max(sr1, sr2),
|
|
16126
16472
|
percentageShift = minRadius / maxRadius;
|
|
16127
16473
|
colorStops.forEach(colorStop => {
|
|
16128
16474
|
colorStop.offset += percentageShift * (1 - colorStop.offset);
|
|
16129
16475
|
});
|
|
16130
16476
|
}
|
|
16131
16477
|
}
|
|
16478
|
+
// todo make a malicious script tag injection test with color and also apply a fix with escapeXml
|
|
16132
16479
|
colorStops.forEach(_ref => {
|
|
16133
16480
|
let {
|
|
16134
16481
|
color,
|
|
@@ -16444,7 +16791,7 @@ class Pattern {
|
|
|
16444
16791
|
patternOffsetY = ifNaN(this.offsetY / height, 0),
|
|
16445
16792
|
patternWidth = repeat === 'repeat-y' || repeat === 'no-repeat' ? 1 + Math.abs(patternOffsetX || 0) : ifNaN(patternSource.width / width, 0),
|
|
16446
16793
|
patternHeight = repeat === 'repeat-x' || repeat === 'no-repeat' ? 1 + Math.abs(patternOffsetY || 0) : ifNaN(patternSource.height / height, 0);
|
|
16447
|
-
return [`<pattern id="SVGID_${id}" x="${patternOffsetX}" y="${patternOffsetY}" width="${patternWidth}" height="${patternHeight}">`, `<image x="0" y="0" width="${patternSource.width}" height="${patternSource.height}" xlink:href="${this.sourceToString()}"></image>`, `</pattern>`, ''].join('\n');
|
|
16794
|
+
return [`<pattern id="SVGID_${escapeXml(id)}" x="${patternOffsetX}" y="${patternOffsetY}" width="${patternWidth}" height="${patternHeight}">`, `<image x="0" y="0" width="${patternSource.width}" height="${patternSource.height}" xlink:href="${escapeXml(this.sourceToString())}"></image>`, `</pattern>`, ''].join('\n');
|
|
16448
16795
|
}
|
|
16449
16796
|
/* _TO_SVG_END_ */
|
|
16450
16797
|
|
|
@@ -16726,8 +17073,7 @@ class Path extends FabricObject {
|
|
|
16726
17073
|
* of the instance
|
|
16727
17074
|
*/
|
|
16728
17075
|
_toSVG() {
|
|
16729
|
-
|
|
16730
|
-
return ['<path ', 'COMMON_PARTS', `d="${path}" stroke-linecap="round" />\n`];
|
|
17076
|
+
return ['<path ', 'COMMON_PARTS', `d="${joinPath(this.path, config.NUM_FRACTION_DIGITS)}" stroke-linecap="round" />\n`];
|
|
16731
17077
|
}
|
|
16732
17078
|
|
|
16733
17079
|
/**
|
|
@@ -17278,15 +17624,17 @@ class Circle extends FabricObject {
|
|
|
17278
17624
|
* of the instance
|
|
17279
17625
|
*/
|
|
17280
17626
|
_toSVG() {
|
|
17281
|
-
const
|
|
17627
|
+
const {
|
|
17628
|
+
radius,
|
|
17629
|
+
startAngle,
|
|
17630
|
+
endAngle
|
|
17631
|
+
} = this;
|
|
17632
|
+
const angle = (endAngle - startAngle) % 360;
|
|
17282
17633
|
if (angle === 0) {
|
|
17283
|
-
return ['<circle ', 'COMMON_PARTS', 'cx="0" cy="0" ', 'r="', `${
|
|
17634
|
+
return ['<circle ', 'COMMON_PARTS', 'cx="0" cy="0" ', 'r="', `${escapeXml(radius)}`, '" />\n'];
|
|
17284
17635
|
} else {
|
|
17285
|
-
const
|
|
17286
|
-
|
|
17287
|
-
} = this;
|
|
17288
|
-
const start = degreesToRadians(this.startAngle),
|
|
17289
|
-
end = degreesToRadians(this.endAngle),
|
|
17636
|
+
const start = degreesToRadians(startAngle),
|
|
17637
|
+
end = degreesToRadians(endAngle),
|
|
17290
17638
|
startX = cos(start) * radius,
|
|
17291
17639
|
startY = sin(start) * radius,
|
|
17292
17640
|
endX = cos(end) * radius,
|
|
@@ -17858,17 +18206,13 @@ class Line extends FabricObject {
|
|
|
17858
18206
|
width,
|
|
17859
18207
|
height
|
|
17860
18208
|
} = this;
|
|
17861
|
-
const xMult = _x1 <= _x2 ? -
|
|
17862
|
-
yMult = _y1 <= _y2 ? -
|
|
17863
|
-
x1 = xMult * width / 2,
|
|
17864
|
-
y1 = yMult * height / 2,
|
|
17865
|
-
x2 = xMult * -width / 2,
|
|
17866
|
-
y2 = yMult * -height / 2;
|
|
18209
|
+
const xMult = _x1 <= _x2 ? -0.5 : 0.5,
|
|
18210
|
+
yMult = _y1 <= _y2 ? -0.5 : 0.5;
|
|
17867
18211
|
return {
|
|
17868
|
-
x1,
|
|
17869
|
-
x2,
|
|
17870
|
-
y1,
|
|
17871
|
-
y2
|
|
18212
|
+
x1: xMult * width,
|
|
18213
|
+
x2: xMult * -width,
|
|
18214
|
+
y1: yMult * height,
|
|
18215
|
+
y2: yMult * -height
|
|
17872
18216
|
};
|
|
17873
18217
|
}
|
|
17874
18218
|
|
|
@@ -18086,7 +18430,7 @@ class Ellipse extends FabricObject {
|
|
|
18086
18430
|
* of the instance
|
|
18087
18431
|
*/
|
|
18088
18432
|
_toSVG() {
|
|
18089
|
-
return ['<ellipse ', 'COMMON_PARTS', `cx="0" cy="0" rx="${this.rx}" ry="${this.ry}" />\n`];
|
|
18433
|
+
return ['<ellipse ', 'COMMON_PARTS', `cx="0" cy="0" rx="${escapeXml(this.rx)}" ry="${escapeXml(this.ry)}" />\n`];
|
|
18090
18434
|
}
|
|
18091
18435
|
|
|
18092
18436
|
/**
|
|
@@ -18404,14 +18748,17 @@ class Polyline extends FabricObject {
|
|
|
18404
18748
|
* of the instance
|
|
18405
18749
|
*/
|
|
18406
18750
|
_toSVG() {
|
|
18407
|
-
const
|
|
18408
|
-
diffX = this.pathOffset.x,
|
|
18751
|
+
const diffX = this.pathOffset.x,
|
|
18409
18752
|
diffY = this.pathOffset.y,
|
|
18410
18753
|
NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS;
|
|
18411
|
-
|
|
18412
|
-
|
|
18413
|
-
|
|
18414
|
-
|
|
18754
|
+
const points = this.points.map(_ref2 => {
|
|
18755
|
+
let {
|
|
18756
|
+
x,
|
|
18757
|
+
y
|
|
18758
|
+
} = _ref2;
|
|
18759
|
+
return `${toFixed(x - diffX, NUM_FRACTION_DIGITS)},${toFixed(y - diffY, NUM_FRACTION_DIGITS)}`;
|
|
18760
|
+
}).join(' ');
|
|
18761
|
+
return [`<${escapeXml(this.constructor.type).toLowerCase()} `, 'COMMON_PARTS', `points="${points}" />\n`];
|
|
18415
18762
|
}
|
|
18416
18763
|
|
|
18417
18764
|
/**
|
|
@@ -18534,7 +18881,6 @@ class StyledText extends FabricObject {
|
|
|
18534
18881
|
};
|
|
18535
18882
|
for (const p1 in obj) {
|
|
18536
18883
|
for (const p2 in obj[p1]) {
|
|
18537
|
-
// eslint-disable-next-line no-unused-vars
|
|
18538
18884
|
for (const p3 in obj[p1][p2]) {
|
|
18539
18885
|
return false;
|
|
18540
18886
|
}
|
|
@@ -18560,9 +18906,7 @@ class StyledText extends FabricObject {
|
|
|
18560
18906
|
const obj = typeof lineIndex === 'undefined' ? this.styles : {
|
|
18561
18907
|
0: this.styles[lineIndex]
|
|
18562
18908
|
};
|
|
18563
|
-
// eslint-disable-next-line
|
|
18564
18909
|
for (const p1 in obj) {
|
|
18565
|
-
// eslint-disable-next-line
|
|
18566
18910
|
for (const p2 in obj[p1]) {
|
|
18567
18911
|
if (typeof obj[p1][p2][property] !== 'undefined') {
|
|
18568
18912
|
return true;
|
|
@@ -18838,7 +19182,7 @@ class TextSVGExportMixin extends FabricObjectSVGExportMixin {
|
|
|
18838
19182
|
} = _ref;
|
|
18839
19183
|
const noShadow = true,
|
|
18840
19184
|
textDecoration = this.getSvgTextDecoration(this);
|
|
18841
|
-
return [textBgRects.join(''), '\t\t<text xml:space="preserve" ', `font-family="${this.fontFamily.replace(dblQuoteRegex, "'")}" `, `font-size="${this.fontSize}" `, this.fontStyle ? `font-style="${this.fontStyle}" ` : '', this.fontWeight ? `font-weight="${this.fontWeight}" ` : '', textDecoration ? `text-decoration="${textDecoration}" ` : '', this.direction === 'rtl' ? `direction="
|
|
19185
|
+
return [textBgRects.join(''), '\t\t<text xml:space="preserve" ', `font-family="${escapeXml(this.fontFamily.replace(dblQuoteRegex, "'"))}" `, `font-size="${escapeXml(this.fontSize)}" `, this.fontStyle ? `font-style="${escapeXml(this.fontStyle)}" ` : '', this.fontWeight ? `font-weight="${escapeXml(this.fontWeight)}" ` : '', textDecoration ? `text-decoration="${textDecoration}" ` : '', this.direction === 'rtl' ? `direction="rtl" ` : '', 'style="', this.getSvgStyles(noShadow), '"', this.addPaintOrder(), ' >', textSpans.join(''), '</text>\n'];
|
|
18842
19186
|
}
|
|
18843
19187
|
|
|
18844
19188
|
/**
|
|
@@ -18854,7 +19198,7 @@ class TextSVGExportMixin extends FabricObjectSVGExportMixin {
|
|
|
18854
19198
|
lineOffset;
|
|
18855
19199
|
|
|
18856
19200
|
// bounding-box background
|
|
18857
|
-
this.backgroundColor && textBgRects.push(
|
|
19201
|
+
this.backgroundColor && textBgRects.push(createSVGInlineRect(this.backgroundColor, -this.width / 2, -this.height / 2, this.width, this.height));
|
|
18858
19202
|
|
|
18859
19203
|
// text and text-background
|
|
18860
19204
|
for (let i = 0, len = this._textLines.length; i < len; i++) {
|
|
@@ -18962,7 +19306,7 @@ class TextSVGExportMixin extends FabricObjectSVGExportMixin {
|
|
|
18962
19306
|
} = this.__charBounds[i][j];
|
|
18963
19307
|
currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');
|
|
18964
19308
|
if (currentColor !== lastColor) {
|
|
18965
|
-
lastColor && textBgRects.push(
|
|
19309
|
+
lastColor && textBgRects.push(createSVGInlineRect(lastColor, leftOffset + boxStart, textTopOffset, boxWidth, heightOfLine));
|
|
18966
19310
|
boxStart = left;
|
|
18967
19311
|
boxWidth = width;
|
|
18968
19312
|
lastColor = currentColor;
|
|
@@ -18970,7 +19314,7 @@ class TextSVGExportMixin extends FabricObjectSVGExportMixin {
|
|
|
18970
19314
|
boxWidth += kernedWidth;
|
|
18971
19315
|
}
|
|
18972
19316
|
}
|
|
18973
|
-
currentColor && textBgRects.push(
|
|
19317
|
+
currentColor && textBgRects.push(createSVGInlineRect(lastColor, leftOffset + boxStart, textTopOffset, boxWidth, heightOfLine));
|
|
18974
19318
|
}
|
|
18975
19319
|
|
|
18976
19320
|
/**
|
|
@@ -18997,7 +19341,6 @@ class TextSVGExportMixin extends FabricObjectSVGExportMixin {
|
|
|
18997
19341
|
fontSize,
|
|
18998
19342
|
fontStyle,
|
|
18999
19343
|
fontWeight,
|
|
19000
|
-
deltaY,
|
|
19001
19344
|
textDecorationThickness,
|
|
19002
19345
|
linethrough,
|
|
19003
19346
|
overline,
|
|
@@ -19009,7 +19352,7 @@ class TextSVGExportMixin extends FabricObjectSVGExportMixin {
|
|
|
19009
19352
|
linethrough: linethrough !== null && linethrough !== void 0 ? linethrough : this.linethrough
|
|
19010
19353
|
});
|
|
19011
19354
|
const thickness = textDecorationThickness || this.textDecorationThickness;
|
|
19012
|
-
return [stroke ? colorPropToSVG(STROKE, stroke) : '', strokeWidth ? `stroke-width: ${strokeWidth}; ` : '', fontFamily ? `font-family: ${!fontFamily.includes("'") && !fontFamily.includes('"') ? `'${fontFamily}'` : fontFamily}; ` : '', fontSize ? `font-size: ${fontSize}px; ` : '', fontStyle ? `font-style: ${fontStyle}; ` : '', fontWeight ? `font-weight: ${fontWeight}; ` : '', textDecoration ? `text-decoration: ${textDecoration}; text-decoration-thickness: ${toFixed(thickness * this.getObjectScaling().y / 10, config.NUM_FRACTION_DIGITS)}%; ` : '', fill ? colorPropToSVG(FILL, fill) : '',
|
|
19355
|
+
return [stroke ? colorPropToSVG(STROKE, stroke) : '', strokeWidth ? `stroke-width: ${escapeXml(strokeWidth)}; ` : '', fontFamily ? `font-family: ${!fontFamily.includes("'") && !fontFamily.includes('"') ? `'${escapeXml(fontFamily)}'` : escapeXml(fontFamily)}; ` : '', fontSize ? `font-size: ${escapeXml(fontSize)}px; ` : '', fontStyle ? `font-style: ${escapeXml(fontStyle)}; ` : '', fontWeight ? `font-weight: ${escapeXml(fontWeight)}; ` : '', textDecoration ? `text-decoration: ${textDecoration}; text-decoration-thickness: ${toFixed(thickness * this.getObjectScaling().y / 10, config.NUM_FRACTION_DIGITS)}%; ` : '', fill ? colorPropToSVG(FILL, fill) : '', useWhiteSpace ? 'white-space: pre; ' : ''].join('');
|
|
19013
19356
|
}
|
|
19014
19357
|
|
|
19015
19358
|
/**
|
|
@@ -24573,13 +24916,13 @@ class FabricImage extends FabricObject {
|
|
|
24573
24916
|
}
|
|
24574
24917
|
if (this.hasCrop()) {
|
|
24575
24918
|
const clipPathId = uid();
|
|
24576
|
-
svgString.push('<clipPath id="imageCrop_' + clipPathId + '">\n', '\t<rect x="' + x + '" y="' + y + '" width="' + this.width + '" height="' + this.height + '" />\n', '</clipPath>\n');
|
|
24919
|
+
svgString.push('<clipPath id="imageCrop_' + clipPathId + '">\n', '\t<rect x="' + x + '" y="' + y + '" width="' + escapeXml(this.width) + '" height="' + escapeXml(this.height) + '" />\n', '</clipPath>\n');
|
|
24577
24920
|
clipPath = ' clip-path="url(#imageCrop_' + clipPathId + ')" ';
|
|
24578
24921
|
}
|
|
24579
24922
|
if (!this.imageSmoothing) {
|
|
24580
24923
|
imageRendering = ' image-rendering="optimizeSpeed"';
|
|
24581
24924
|
}
|
|
24582
|
-
imageMarkup.push('\t<image ', 'COMMON_PARTS', `xlink:href="${this.
|
|
24925
|
+
imageMarkup.push('\t<image ', 'COMMON_PARTS', `xlink:href="${escapeXml(this.getSrc(true))}" x="${x - this.cropX}" y="${y - this.cropY
|
|
24583
24926
|
// we're essentially moving origin of transformation from top/left corner to the center of the shape
|
|
24584
24927
|
// by wrapping it in container <g> element with actual transformation, then offsetting object to the top/left
|
|
24585
24928
|
// so that object's center aligns with container's left/top
|
|
@@ -24587,7 +24930,7 @@ class FabricImage extends FabricObject {
|
|
|
24587
24930
|
if (this.stroke || this.strokeDashArray) {
|
|
24588
24931
|
const origFill = this.fill;
|
|
24589
24932
|
this.fill = null;
|
|
24590
|
-
strokeSvg = [`\t<rect x="${x}" y="${y}" width="${this.width}" height="${this.height}" style="${this.getSvgStyles()}" />\n`];
|
|
24933
|
+
strokeSvg = [`\t<rect x="${x}" y="${y}" width="${escapeXml(this.width)}" height="${escapeXml(this.height)}" style="${this.getSvgStyles()}" />\n`];
|
|
24591
24934
|
this.fill = origFill;
|
|
24592
24935
|
}
|
|
24593
24936
|
if (this.paintFirst !== FILL) {
|
|
@@ -25570,258 +25913,6 @@ function loadSVGFromURL(url, reviver) {
|
|
|
25570
25913
|
});
|
|
25571
25914
|
}
|
|
25572
25915
|
|
|
25573
|
-
const ACTION_NAME$1 = MODIFY_POLY;
|
|
25574
|
-
/**
|
|
25575
|
-
* This function locates the controls.
|
|
25576
|
-
* It'll be used both for drawing and for interaction.
|
|
25577
|
-
*/
|
|
25578
|
-
const createPolyPositionHandler = pointIndex => {
|
|
25579
|
-
return function (dim, finalMatrix, polyObject) {
|
|
25580
|
-
const {
|
|
25581
|
-
points,
|
|
25582
|
-
pathOffset
|
|
25583
|
-
} = polyObject;
|
|
25584
|
-
return new Point(points[pointIndex]).subtract(pathOffset).transform(multiplyTransformMatrices(polyObject.getViewportTransform(), polyObject.calcTransformMatrix()));
|
|
25585
|
-
};
|
|
25586
|
-
};
|
|
25587
|
-
|
|
25588
|
-
/**
|
|
25589
|
-
* This function defines what the control does.
|
|
25590
|
-
* It'll be called on every mouse move after a control has been clicked and is being dragged.
|
|
25591
|
-
* The function receives as argument the mouse event, the current transform object
|
|
25592
|
-
* and the current position in canvas coordinate `transform.target` is a reference to the
|
|
25593
|
-
* current object being transformed.
|
|
25594
|
-
*/
|
|
25595
|
-
const polyActionHandler = (eventData, transform, x, y) => {
|
|
25596
|
-
const {
|
|
25597
|
-
target,
|
|
25598
|
-
pointIndex
|
|
25599
|
-
} = transform;
|
|
25600
|
-
const poly = target;
|
|
25601
|
-
const mouseLocalPosition = sendPointToPlane(new Point(x, y), undefined, poly.calcOwnMatrix());
|
|
25602
|
-
poly.points[pointIndex] = mouseLocalPosition.add(poly.pathOffset);
|
|
25603
|
-
poly.setDimensions();
|
|
25604
|
-
poly.set('dirty', true);
|
|
25605
|
-
return true;
|
|
25606
|
-
};
|
|
25607
|
-
|
|
25608
|
-
/**
|
|
25609
|
-
* Keep the polygon in the same position when we change its `width`/`height`/`top`/`left`.
|
|
25610
|
-
*/
|
|
25611
|
-
const factoryPolyActionHandler = (pointIndex, fn) => {
|
|
25612
|
-
return function (eventData, transform, x, y) {
|
|
25613
|
-
const poly = transform.target,
|
|
25614
|
-
anchorPoint = new Point(poly.points[(pointIndex > 0 ? pointIndex : poly.points.length) - 1]),
|
|
25615
|
-
anchorPointInParentPlane = anchorPoint.subtract(poly.pathOffset).transform(poly.calcOwnMatrix()),
|
|
25616
|
-
actionPerformed = fn(eventData, {
|
|
25617
|
-
...transform,
|
|
25618
|
-
pointIndex
|
|
25619
|
-
}, x, y);
|
|
25620
|
-
const newAnchorPointInParentPlane = anchorPoint.subtract(poly.pathOffset).transform(poly.calcOwnMatrix());
|
|
25621
|
-
const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane);
|
|
25622
|
-
poly.left -= diff.x;
|
|
25623
|
-
poly.top -= diff.y;
|
|
25624
|
-
return actionPerformed;
|
|
25625
|
-
};
|
|
25626
|
-
};
|
|
25627
|
-
const createPolyActionHandler = pointIndex => wrapWithFireEvent(ACTION_NAME$1, factoryPolyActionHandler(pointIndex, polyActionHandler));
|
|
25628
|
-
function createPolyControls(arg0) {
|
|
25629
|
-
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
25630
|
-
const controls = {};
|
|
25631
|
-
for (let idx = 0; idx < (typeof arg0 === 'number' ? arg0 : arg0.points.length); idx++) {
|
|
25632
|
-
controls[`p${idx}`] = new Control({
|
|
25633
|
-
actionName: ACTION_NAME$1,
|
|
25634
|
-
positionHandler: createPolyPositionHandler(idx),
|
|
25635
|
-
actionHandler: createPolyActionHandler(idx),
|
|
25636
|
-
...options
|
|
25637
|
-
});
|
|
25638
|
-
}
|
|
25639
|
-
return controls;
|
|
25640
|
-
}
|
|
25641
|
-
|
|
25642
|
-
const ACTION_NAME = 'modifyPath';
|
|
25643
|
-
const calcPathPointPosition = (pathObject, commandIndex, pointIndex) => {
|
|
25644
|
-
const {
|
|
25645
|
-
path,
|
|
25646
|
-
pathOffset
|
|
25647
|
-
} = pathObject;
|
|
25648
|
-
const command = path[commandIndex];
|
|
25649
|
-
return new Point(command[pointIndex] - pathOffset.x, command[pointIndex + 1] - pathOffset.y).transform(multiplyTransformMatrices(pathObject.getViewportTransform(), pathObject.calcTransformMatrix()));
|
|
25650
|
-
};
|
|
25651
|
-
const movePathPoint = (pathObject, x, y, commandIndex, pointIndex) => {
|
|
25652
|
-
const {
|
|
25653
|
-
path,
|
|
25654
|
-
pathOffset
|
|
25655
|
-
} = pathObject;
|
|
25656
|
-
const anchorCommand = path[(commandIndex > 0 ? commandIndex : path.length) - 1];
|
|
25657
|
-
const anchorPoint = new Point(anchorCommand[pointIndex], anchorCommand[pointIndex + 1]);
|
|
25658
|
-
const anchorPointInParentPlane = anchorPoint.subtract(pathOffset).transform(pathObject.calcOwnMatrix());
|
|
25659
|
-
const mouseLocalPosition = sendPointToPlane(new Point(x, y), undefined, pathObject.calcOwnMatrix());
|
|
25660
|
-
path[commandIndex][pointIndex] = mouseLocalPosition.x + pathOffset.x;
|
|
25661
|
-
path[commandIndex][pointIndex + 1] = mouseLocalPosition.y + pathOffset.y;
|
|
25662
|
-
pathObject.setDimensions();
|
|
25663
|
-
const newAnchorPointInParentPlane = anchorPoint.subtract(pathObject.pathOffset).transform(pathObject.calcOwnMatrix());
|
|
25664
|
-
const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane);
|
|
25665
|
-
pathObject.left -= diff.x;
|
|
25666
|
-
pathObject.top -= diff.y;
|
|
25667
|
-
pathObject.set('dirty', true);
|
|
25668
|
-
return true;
|
|
25669
|
-
};
|
|
25670
|
-
|
|
25671
|
-
/**
|
|
25672
|
-
* This function locates the controls.
|
|
25673
|
-
* It'll be used both for drawing and for interaction.
|
|
25674
|
-
*/
|
|
25675
|
-
function pathPositionHandler(dim, finalMatrix, pathObject) {
|
|
25676
|
-
const {
|
|
25677
|
-
commandIndex,
|
|
25678
|
-
pointIndex
|
|
25679
|
-
} = this;
|
|
25680
|
-
return calcPathPointPosition(pathObject, commandIndex, pointIndex);
|
|
25681
|
-
}
|
|
25682
|
-
|
|
25683
|
-
/**
|
|
25684
|
-
* This function defines what the control does.
|
|
25685
|
-
* It'll be called on every mouse move after a control has been clicked and is being dragged.
|
|
25686
|
-
* The function receives as argument the mouse event, the current transform object
|
|
25687
|
-
* and the current position in canvas coordinate `transform.target` is a reference to the
|
|
25688
|
-
* current object being transformed.
|
|
25689
|
-
*/
|
|
25690
|
-
function pathActionHandler(eventData, transform, x, y) {
|
|
25691
|
-
const {
|
|
25692
|
-
target
|
|
25693
|
-
} = transform;
|
|
25694
|
-
const {
|
|
25695
|
-
commandIndex,
|
|
25696
|
-
pointIndex
|
|
25697
|
-
} = this;
|
|
25698
|
-
const actionPerformed = movePathPoint(target, x, y, commandIndex, pointIndex);
|
|
25699
|
-
{
|
|
25700
|
-
fireEvent(this.actionName, {
|
|
25701
|
-
...commonEventInfo(eventData, transform, x, y),
|
|
25702
|
-
commandIndex,
|
|
25703
|
-
pointIndex
|
|
25704
|
-
});
|
|
25705
|
-
}
|
|
25706
|
-
return actionPerformed;
|
|
25707
|
-
}
|
|
25708
|
-
const indexFromPrevCommand = previousCommandType => previousCommandType === 'C' ? 5 : previousCommandType === 'Q' ? 3 : 1;
|
|
25709
|
-
class PathPointControl extends Control {
|
|
25710
|
-
constructor(options) {
|
|
25711
|
-
super(options);
|
|
25712
|
-
}
|
|
25713
|
-
render(ctx, left, top, styleOverride, fabricObject) {
|
|
25714
|
-
const overrides = {
|
|
25715
|
-
...styleOverride,
|
|
25716
|
-
cornerColor: this.controlFill,
|
|
25717
|
-
cornerStrokeColor: this.controlStroke,
|
|
25718
|
-
transparentCorners: !this.controlFill
|
|
25719
|
-
};
|
|
25720
|
-
super.render(ctx, left, top, overrides, fabricObject);
|
|
25721
|
-
}
|
|
25722
|
-
}
|
|
25723
|
-
class PathControlPointControl extends PathPointControl {
|
|
25724
|
-
constructor(options) {
|
|
25725
|
-
super(options);
|
|
25726
|
-
}
|
|
25727
|
-
render(ctx, left, top, styleOverride, fabricObject) {
|
|
25728
|
-
const {
|
|
25729
|
-
path
|
|
25730
|
-
} = fabricObject;
|
|
25731
|
-
const {
|
|
25732
|
-
commandIndex,
|
|
25733
|
-
pointIndex,
|
|
25734
|
-
connectToCommandIndex,
|
|
25735
|
-
connectToPointIndex
|
|
25736
|
-
} = this;
|
|
25737
|
-
ctx.save();
|
|
25738
|
-
ctx.strokeStyle = this.controlStroke;
|
|
25739
|
-
if (this.connectionDashArray) {
|
|
25740
|
-
ctx.setLineDash(this.connectionDashArray);
|
|
25741
|
-
}
|
|
25742
|
-
const [commandType] = path[commandIndex];
|
|
25743
|
-
const point = calcPathPointPosition(fabricObject, connectToCommandIndex, connectToPointIndex);
|
|
25744
|
-
if (commandType === 'Q') {
|
|
25745
|
-
// one control point connects to 2 points
|
|
25746
|
-
const point2 = calcPathPointPosition(fabricObject, commandIndex, pointIndex + 2);
|
|
25747
|
-
ctx.moveTo(point2.x, point2.y);
|
|
25748
|
-
ctx.lineTo(left, top);
|
|
25749
|
-
} else {
|
|
25750
|
-
ctx.moveTo(left, top);
|
|
25751
|
-
}
|
|
25752
|
-
ctx.lineTo(point.x, point.y);
|
|
25753
|
-
ctx.stroke();
|
|
25754
|
-
ctx.restore();
|
|
25755
|
-
super.render(ctx, left, top, styleOverride, fabricObject);
|
|
25756
|
-
}
|
|
25757
|
-
}
|
|
25758
|
-
const createControl = (commandIndexPos, pointIndexPos, isControlPoint, options, connectToCommandIndex, connectToPointIndex) => new (isControlPoint ? PathControlPointControl : PathPointControl)({
|
|
25759
|
-
commandIndex: commandIndexPos,
|
|
25760
|
-
pointIndex: pointIndexPos,
|
|
25761
|
-
actionName: ACTION_NAME,
|
|
25762
|
-
positionHandler: pathPositionHandler,
|
|
25763
|
-
actionHandler: pathActionHandler,
|
|
25764
|
-
connectToCommandIndex,
|
|
25765
|
-
connectToPointIndex,
|
|
25766
|
-
...options,
|
|
25767
|
-
...(isControlPoint ? options.controlPointStyle : options.pointStyle)
|
|
25768
|
-
});
|
|
25769
|
-
function createPathControls(path) {
|
|
25770
|
-
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
25771
|
-
const controls = {};
|
|
25772
|
-
let previousCommandType = 'M';
|
|
25773
|
-
path.path.forEach((command, commandIndex) => {
|
|
25774
|
-
const commandType = command[0];
|
|
25775
|
-
if (commandType !== 'Z') {
|
|
25776
|
-
controls[`c_${commandIndex}_${commandType}`] = createControl(commandIndex, command.length - 2, false, options);
|
|
25777
|
-
}
|
|
25778
|
-
switch (commandType) {
|
|
25779
|
-
case 'C':
|
|
25780
|
-
controls[`c_${commandIndex}_C_CP_1`] = createControl(commandIndex, 1, true, options, commandIndex - 1, indexFromPrevCommand(previousCommandType));
|
|
25781
|
-
controls[`c_${commandIndex}_C_CP_2`] = createControl(commandIndex, 3, true, options, commandIndex, 5);
|
|
25782
|
-
break;
|
|
25783
|
-
case 'Q':
|
|
25784
|
-
controls[`c_${commandIndex}_Q_CP_1`] = createControl(commandIndex, 1, true, options, commandIndex, 3);
|
|
25785
|
-
break;
|
|
25786
|
-
}
|
|
25787
|
-
previousCommandType = commandType;
|
|
25788
|
-
});
|
|
25789
|
-
return controls;
|
|
25790
|
-
}
|
|
25791
|
-
|
|
25792
|
-
var index = /*#__PURE__*/Object.freeze({
|
|
25793
|
-
__proto__: null,
|
|
25794
|
-
changeWidth: changeWidth,
|
|
25795
|
-
createObjectDefaultControls: createObjectDefaultControls,
|
|
25796
|
-
createPathControls: createPathControls,
|
|
25797
|
-
createPolyActionHandler: createPolyActionHandler,
|
|
25798
|
-
createPolyControls: createPolyControls,
|
|
25799
|
-
createPolyPositionHandler: createPolyPositionHandler,
|
|
25800
|
-
createResizeControls: createResizeControls,
|
|
25801
|
-
createTextboxDefaultControls: createTextboxDefaultControls,
|
|
25802
|
-
dragHandler: dragHandler,
|
|
25803
|
-
factoryPolyActionHandler: factoryPolyActionHandler,
|
|
25804
|
-
getLocalPoint: getLocalPoint,
|
|
25805
|
-
polyActionHandler: polyActionHandler,
|
|
25806
|
-
renderCircleControl: renderCircleControl,
|
|
25807
|
-
renderSquareControl: renderSquareControl,
|
|
25808
|
-
rotationStyleHandler: rotationStyleHandler,
|
|
25809
|
-
rotationWithSnapping: rotationWithSnapping,
|
|
25810
|
-
scaleCursorStyleHandler: scaleCursorStyleHandler,
|
|
25811
|
-
scaleOrSkewActionName: scaleOrSkewActionName,
|
|
25812
|
-
scaleSkewCursorStyleHandler: scaleSkewCursorStyleHandler,
|
|
25813
|
-
scalingEqually: scalingEqually,
|
|
25814
|
-
scalingX: scalingX,
|
|
25815
|
-
scalingXOrSkewingY: scalingXOrSkewingY,
|
|
25816
|
-
scalingY: scalingY,
|
|
25817
|
-
scalingYOrSkewingX: scalingYOrSkewingX,
|
|
25818
|
-
skewCursorStyleHandler: skewCursorStyleHandler,
|
|
25819
|
-
skewHandlerX: skewHandlerX,
|
|
25820
|
-
skewHandlerY: skewHandlerY,
|
|
25821
|
-
wrapWithFireEvent: wrapWithFireEvent,
|
|
25822
|
-
wrapWithFixedAnchor: wrapWithFixedAnchor
|
|
25823
|
-
});
|
|
25824
|
-
|
|
25825
25916
|
const isWebGLPipelineState = options => {
|
|
25826
25917
|
return options.webgl !== undefined;
|
|
25827
25918
|
};
|