fabric 5.3.0 → 6.0.0-beta3
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/.babelrc +11 -0
- package/.babelrcAlt +19 -0
- package/.browserslistrc +5 -0
- package/.eslintignore +3 -0
- package/.eslintrc.js +43 -0
- package/.eslintrc.json +38 -46
- package/.eslintrc_tests +12 -0
- package/.gitattributes +2 -0
- package/.gitpod.yml +17 -1
- package/.prettierignore +19 -0
- package/.prettierrc +4 -0
- package/CHANGELOG.md +532 -189
- package/CONTRIBUTING.md +224 -59
- package/README.md +200 -235
- package/bower.json +1 -3
- package/dist/fabric.d.ts +42 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +27582 -0
- package/dist/index.js.map +1 -0
- package/dist/index.min.js +1 -0
- package/dist/index.mjs +27519 -0
- package/dist/index.mjs.map +1 -0
- package/dist/index.node.cjs +27663 -0
- package/dist/index.node.cjs.map +1 -0
- package/dist/index.node.d.ts +14 -0
- package/dist/index.node.mjs +27606 -0
- package/dist/index.node.mjs.map +1 -0
- package/dist/src/ClassRegistry.d.ts +13 -0
- package/dist/src/Collection.d.ts +136 -0
- package/dist/src/CommonMethods.d.ts +32 -0
- package/dist/src/EventTypeDefs.d.ts +227 -0
- package/dist/src/Intersection.d.ts +112 -0
- package/dist/src/Observable.d.ts +60 -0
- package/dist/src/Pattern.d.ts +113 -0
- package/dist/src/Point.d.ts +232 -0
- package/dist/src/Shadow.d.ts +97 -0
- package/dist/src/brushes/BaseBrush.d.ts +105 -0
- package/dist/src/brushes/CircleBrush.d.ts +49 -0
- package/dist/src/brushes/PatternBrush.d.ts +23 -0
- package/dist/src/brushes/PencilBrush.d.ts +92 -0
- package/dist/src/brushes/SprayBrush.d.ts +79 -0
- package/dist/src/cache.d.ts +47 -0
- package/dist/src/canvas/Canvas.d.ts +548 -0
- package/dist/src/canvas/SelectableCanvas.d.ts +754 -0
- package/dist/src/canvas/StaticCanvas.d.ts +778 -0
- package/dist/src/canvas/TextEditingManager.d.ts +17 -0
- package/dist/src/canvas/canvas_gestures.mixin.d.ts +2 -0
- package/dist/src/color/Color.d.ts +174 -0
- package/dist/src/color/color_map.d.ts +155 -0
- package/dist/src/color/constants.d.ts +22 -0
- package/dist/src/color/util.d.ts +12 -0
- package/dist/src/config.d.ts +115 -0
- package/dist/src/constants.d.ts +14 -0
- package/dist/src/controls/Control.d.ts +228 -0
- package/dist/src/controls/changeWidth.d.ts +13 -0
- package/dist/src/controls/commonControls.d.ts +28 -0
- package/dist/src/controls/controlRendering.d.ts +29 -0
- package/dist/src/controls/drag.d.ts +12 -0
- package/dist/src/controls/index.d.ts +13 -0
- package/dist/src/controls/polyControl.d.ts +5 -0
- package/dist/src/controls/rotate.d.ts +12 -0
- package/dist/src/controls/scale.d.ts +47 -0
- package/dist/src/controls/scaleSkew.d.ts +39 -0
- package/dist/src/controls/skew.d.ts +33 -0
- package/dist/src/controls/util.d.ts +41 -0
- package/dist/src/controls/wrapWithFireEvent.d.ts +8 -0
- package/dist/src/controls/wrapWithFixedAnchor.d.ts +9 -0
- package/dist/src/env/browser.d.ts +3 -0
- package/dist/src/env/index.d.ts +15 -0
- package/dist/src/env/node.d.ts +5 -0
- package/dist/src/env/types.d.ts +15 -0
- package/dist/src/filters/BaseFilter.d.ts +153 -0
- package/dist/src/filters/BlendColor.d.ts +80 -0
- package/dist/src/filters/BlendImage.d.ts +92 -0
- package/dist/src/filters/Blur.d.ts +51 -0
- package/dist/src/filters/Boilerplate.d.ts +48 -0
- package/dist/src/filters/Brightness.d.ts +47 -0
- package/dist/src/filters/Canvas2dFilterBackend.d.ts +27 -0
- package/dist/src/filters/ColorMatrix.d.ts +63 -0
- package/dist/src/filters/ColorMatrixFilters.d.ts +545 -0
- package/dist/src/filters/Composed.d.ts +45 -0
- package/dist/src/filters/Contrast.d.ts +45 -0
- package/dist/src/filters/Convolute.d.ts +82 -0
- package/dist/src/filters/FilterBackend.d.ts +14 -0
- package/dist/src/filters/GLProbes/GLProbe.d.ts +11 -0
- package/dist/src/filters/GLProbes/NodeGLProbe.d.ts +11 -0
- package/dist/src/filters/GLProbes/WebGLProbe.d.ts +20 -0
- package/dist/src/filters/Gamma.d.ts +54 -0
- package/dist/src/filters/Grayscale.d.ts +46 -0
- package/dist/src/filters/HueRotation.d.ts +24 -0
- package/dist/src/filters/Invert.d.ts +55 -0
- package/dist/src/filters/Noise.d.ts +54 -0
- package/dist/src/filters/Pixelate.d.ts +44 -0
- package/dist/src/filters/RemoveColor.d.ts +63 -0
- package/dist/src/filters/Resize.d.ts +136 -0
- package/dist/src/filters/Saturation.d.ts +48 -0
- package/dist/src/filters/Vibrance.d.ts +48 -0
- package/dist/src/filters/WebGLFilterBackend.d.ts +126 -0
- package/dist/src/filters/filters.d.ts +21 -0
- package/dist/src/filters/index.d.ts +5 -0
- package/dist/src/filters/shaders/baseFilter.d.ts +4 -0
- package/dist/src/filters/shaders/blendColor.d.ts +13 -0
- package/dist/src/filters/shaders/blendImage.d.ts +3 -0
- package/dist/src/filters/shaders/blur.d.ts +2 -0
- package/dist/src/filters/shaders/brightness.d.ts +2 -0
- package/dist/src/filters/shaders/colorMatrix.d.ts +2 -0
- package/dist/src/filters/shaders/constrast.d.ts +2 -0
- package/dist/src/filters/shaders/convolute.d.ts +11 -0
- package/dist/src/filters/shaders/gamma.d.ts +2 -0
- package/dist/src/filters/shaders/grayscale.d.ts +3 -0
- package/dist/src/filters/shaders/invert.d.ts +2 -0
- package/dist/src/filters/shaders/noise.d.ts +2 -0
- package/dist/src/filters/shaders/pixelate.d.ts +2 -0
- package/dist/src/filters/shaders/removeColor.d.ts +2 -0
- package/dist/src/filters/shaders/saturation.d.ts +2 -0
- package/dist/src/filters/shaders/vibrance.d.ts +2 -0
- package/dist/src/filters/typedefs.d.ts +49 -0
- package/dist/src/gradient/Gradient.d.ts +149 -0
- package/dist/src/gradient/constants.d.ts +15 -0
- package/dist/src/gradient/parser/index.d.ts +4 -0
- package/dist/src/gradient/parser/misc.d.ts +4 -0
- package/dist/src/gradient/parser/parseColorStops.d.ts +3 -0
- package/dist/src/gradient/parser/parseCoords.d.ts +17 -0
- package/dist/src/gradient/typedefs.d.ts +93 -0
- package/dist/src/mixins/eraser_brush.mixin.d.ts +2 -0
- package/dist/src/parkinglot/canvas_animation.mixin.d.ts +2 -0
- package/dist/src/parkinglot/straighten.d.ts +2 -0
- package/dist/src/parser/applyViewboxTransform.d.ts +5 -0
- package/dist/src/parser/attributes.d.ts +6 -0
- package/dist/src/parser/constants.d.ts +53 -0
- package/dist/src/parser/doesSomeParentMatch.d.ts +2 -0
- package/dist/src/parser/elementById.d.ts +6 -0
- package/dist/src/parser/elementMatchesRule.d.ts +5 -0
- package/dist/src/parser/elements_parser.d.ts +3 -0
- package/dist/src/parser/getCSSRules.d.ts +7 -0
- package/dist/src/parser/getGlobalStylesForElement.d.ts +5 -0
- package/dist/src/parser/getGradientDefs.d.ts +7 -0
- package/dist/src/parser/getMultipleNodes.d.ts +2 -0
- package/dist/src/parser/getSvgRegex.d.ts +2 -0
- package/dist/src/parser/hasAncestorWithNodeName.d.ts +2 -0
- package/dist/src/parser/index.d.ts +10 -0
- package/dist/src/parser/loadSVGFromString.d.ts +12 -0
- package/dist/src/parser/loadSVGFromURL.d.ts +13 -0
- package/dist/src/parser/normalizeAttr.d.ts +2 -0
- package/dist/src/parser/normalizeValue.d.ts +2 -0
- package/dist/src/parser/parseAttributes.d.ts +9 -0
- package/dist/src/parser/parseElements.d.ts +11 -0
- package/dist/src/parser/parseFontDeclaration.d.ts +10 -0
- package/dist/src/parser/parsePointsAttribute.d.ts +12 -0
- package/dist/src/parser/parseSVGDocument.d.ts +15 -0
- package/dist/src/parser/parseStyleAttribute.d.ts +9 -0
- package/dist/src/parser/parseStyleObject.d.ts +2 -0
- package/dist/src/parser/parseStyleString.d.ts +2 -0
- package/dist/src/parser/parseTransformAttribute.d.ts +10 -0
- package/dist/src/parser/parseUseDirectives.d.ts +2 -0
- package/dist/src/parser/percent.d.ts +9 -0
- package/dist/src/parser/recursivelyParseGradientsXlink.d.ts +2 -0
- package/dist/src/parser/rotateMatrix.d.ts +2 -0
- package/dist/src/parser/scaleMatrix.d.ts +2 -0
- package/dist/src/parser/selectorMatches.d.ts +2 -0
- package/dist/src/parser/setStrokeFillOpacity.d.ts +6 -0
- package/dist/src/parser/skewMatrix.d.ts +2 -0
- package/dist/src/parser/translateMatrix.d.ts +2 -0
- package/dist/src/shapes/ActiveSelection.d.ts +82 -0
- package/dist/src/shapes/Circle.d.ts +99 -0
- package/dist/src/shapes/Ellipse.d.ts +84 -0
- package/dist/src/shapes/Group.d.ts +408 -0
- package/dist/src/shapes/IText/DraggableTextDelegate.d.ts +78 -0
- package/dist/src/shapes/IText/IText.d.ts +335 -0
- package/dist/src/shapes/IText/ITextBehavior.d.ts +287 -0
- package/dist/src/shapes/IText/ITextClickBehavior.d.ts +83 -0
- package/dist/src/shapes/IText/ITextKeyBehavior.d.ts +195 -0
- package/dist/src/shapes/IText/constants.d.ts +13 -0
- package/dist/src/shapes/Image.d.ts +311 -0
- package/dist/src/shapes/Line.d.ts +126 -0
- package/dist/src/shapes/Object/AnimatableObject.d.ts +33 -0
- package/dist/src/shapes/Object/FabricObject.d.ts +11 -0
- package/dist/src/shapes/Object/FabricObjectSVGExportMixin.d.ts +74 -0
- package/dist/src/shapes/Object/InteractiveObject.d.ts +296 -0
- package/dist/src/shapes/Object/Object.d.ts +594 -0
- package/dist/src/shapes/Object/ObjectGeometry.d.ts +327 -0
- package/dist/src/shapes/Object/ObjectOrigin.d.ts +109 -0
- package/dist/src/shapes/Object/StackedObject.d.ts +72 -0
- package/dist/src/shapes/Object/defaultValues.d.ts +76 -0
- package/dist/src/shapes/Object/types/BaseProps.d.ts +84 -0
- package/dist/src/shapes/Object/types/BorderProps.d.ts +37 -0
- package/dist/src/shapes/Object/types/ControlProps.d.ts +62 -0
- package/dist/src/shapes/Object/types/FabricObjectProps.d.ts +96 -0
- package/dist/src/shapes/Object/types/FillStrokeProps.d.ts +80 -0
- package/dist/src/shapes/Object/types/LockInteractionProps.d.ts +51 -0
- package/dist/src/shapes/Object/types/ObjectProps.d.ts +42 -0
- package/dist/src/shapes/Object/types/SerializedObjectProps.d.ts +66 -0
- package/dist/src/shapes/Object/types/index.d.ts +6 -0
- package/dist/src/shapes/Path.d.ts +130 -0
- package/dist/src/shapes/Polygon.d.ts +9 -0
- package/dist/src/shapes/Polyline.d.ts +140 -0
- package/dist/src/shapes/Rect.d.ts +76 -0
- package/dist/src/shapes/Text/StyledText.d.ts +119 -0
- package/dist/src/shapes/Text/Text.d.ts +673 -0
- package/dist/src/shapes/Text/TextSVGExportMixin.d.ts +32 -0
- package/dist/src/shapes/Text/constants.d.ts +7 -0
- package/dist/src/shapes/Textbox.d.ts +185 -0
- package/dist/src/shapes/Triangle.d.ts +25 -0
- package/dist/src/typedefs.d.ts +90 -0
- package/dist/src/util/animation/AnimationBase.d.ts +54 -0
- package/dist/src/util/animation/AnimationFrameProvider.d.ts +3 -0
- package/dist/src/util/animation/AnimationRegistry.d.ts +29 -0
- package/dist/src/util/animation/ArrayAnimation.d.ts +10 -0
- package/dist/src/util/animation/ColorAnimation.d.ts +11 -0
- package/dist/src/util/animation/ValueAnimation.d.ts +10 -0
- package/dist/src/util/animation/animate.d.ts +37 -0
- package/dist/src/util/animation/easing.d.ts +130 -0
- package/dist/src/util/animation/types.d.ts +87 -0
- package/dist/src/util/applyMixins.d.ts +8 -0
- package/dist/src/util/dom_event.d.ts +5 -0
- package/dist/src/util/dom_misc.d.ts +39 -0
- package/dist/src/util/dom_request.d.ts +14 -0
- package/dist/src/util/dom_style.d.ts +7 -0
- package/dist/src/util/fireEvent.d.ts +3 -0
- package/dist/src/util/index.d.ts +35 -0
- package/dist/src/util/internals/cloneDeep.d.ts +2 -0
- package/dist/src/util/internals/getRandomInt.d.ts +8 -0
- package/dist/src/util/internals/ifNaN.d.ts +8 -0
- package/dist/src/util/internals/index.d.ts +4 -0
- package/dist/src/util/internals/removeFromArray.d.ts +9 -0
- package/dist/src/util/internals/uid.d.ts +2 -0
- package/dist/src/util/lang_string.d.ts +22 -0
- package/dist/src/util/misc/boundingBoxFromPoints.d.ts +9 -0
- package/dist/src/util/misc/capValue.d.ts +2 -0
- package/dist/src/util/misc/cos.d.ts +10 -0
- package/dist/src/util/misc/dom.d.ts +28 -0
- package/dist/src/util/misc/findScaleTo.d.ts +29 -0
- package/dist/src/util/misc/groupSVGElements.d.ts +9 -0
- package/dist/src/util/misc/isTransparent.d.ts +11 -0
- package/dist/src/util/misc/matrix.d.ts +92 -0
- package/dist/src/util/misc/mergeClipPaths.d.ts +23 -0
- package/dist/src/util/misc/objectEnlive.d.ts +56 -0
- package/dist/src/util/misc/objectTransforms.d.ts +68 -0
- package/dist/src/util/misc/pick.d.ts +9 -0
- package/dist/src/util/misc/planeChange.d.ts +84 -0
- package/dist/src/util/misc/projectStroke/StrokeLineCapProjections.d.ts +51 -0
- package/dist/src/util/misc/projectStroke/StrokeLineJoinProjections.d.ts +81 -0
- package/dist/src/util/misc/projectStroke/StrokeProjectionsBase.d.ts +25 -0
- package/dist/src/util/misc/projectStroke/index.d.ts +11 -0
- package/dist/src/util/misc/projectStroke/types.d.ts +23 -0
- package/dist/src/util/misc/radiansDegreesConversion.d.ts +14 -0
- package/dist/src/util/misc/resolveOrigin.d.ts +9 -0
- package/dist/src/util/misc/rotatePoint.d.ts +12 -0
- package/dist/src/util/misc/sin.d.ts +10 -0
- package/dist/src/util/misc/svgParsing.d.ts +53 -0
- package/dist/src/util/misc/textStyles.d.ts +32 -0
- package/dist/src/util/misc/toFixed.d.ts +8 -0
- package/dist/src/util/misc/vectors.d.ts +57 -0
- package/dist/src/util/path/index.d.ts +96 -0
- package/dist/src/util/path/regex.d.ts +3 -0
- package/dist/src/util/path/typechecks.d.ts +24 -0
- package/dist/src/util/path/typedefs.d.ts +220 -0
- package/dist/src/util/transform_matrix_removal.d.ts +14 -0
- package/dist/src/util/types.d.ts +19 -0
- package/fabric.ts +51 -0
- package/index.node.ts +37 -0
- package/index.ts +1 -0
- package/package.json +100 -40
- package/publish.js +0 -26
- package/rollup.config.mjs +91 -0
- package/rollup.test.config.js +24 -0
- package/scripts/build.mjs +50 -0
- package/scripts/buildLock.mjs +115 -0
- package/scripts/buildReporter.mjs +15 -0
- package/scripts/buildStats.mjs +139 -0
- package/scripts/dirname.mjs +14 -0
- package/scripts/git.mjs +36 -0
- package/scripts/index.mjs +564 -0
- package/scripts/sandbox.mjs +149 -0
- package/src/ClassRegistry.ts +56 -0
- package/src/Collection.ts +346 -0
- package/src/CommonMethods.ts +63 -0
- package/src/EventTypeDefs.ts +296 -0
- package/src/Intersection.ts +302 -0
- package/src/Observable.ts +181 -0
- package/src/Pattern.ts +227 -0
- package/src/Point.ts +388 -0
- package/src/Shadow.ts +214 -0
- package/src/brushes/{base_brush.class.js → BaseBrush.ts} +65 -42
- package/src/brushes/CircleBrush.ts +145 -0
- package/src/brushes/PatternBrush.ts +70 -0
- package/src/brushes/PencilBrush.ts +300 -0
- package/src/brushes/SprayBrush.ts +219 -0
- package/src/cache.ts +90 -0
- package/src/canvas/Canvas.ts +1607 -0
- package/src/canvas/SelectableCanvas.ts +1608 -0
- package/src/canvas/StaticCanvas.ts +1734 -0
- package/src/canvas/TextEditingManager.ts +48 -0
- package/src/canvas/canvas_gestures.mixin.ts +207 -0
- package/src/color/Color.ts +404 -0
- package/src/color/color_map.ts +154 -0
- package/src/color/constants.ts +26 -0
- package/src/color/util.ts +32 -0
- package/src/config.ts +159 -0
- package/src/constants.ts +20 -0
- package/src/controls/Control.ts +380 -0
- package/src/controls/changeWidth.ts +52 -0
- package/src/controls/commonControls.ts +105 -0
- package/src/controls/controlRendering.ts +138 -0
- package/src/controls/drag.ts +31 -0
- package/src/controls/index.ts +22 -0
- package/src/controls/polyControl.ts +135 -0
- package/src/controls/rotate.ts +87 -0
- package/src/controls/scale.ts +277 -0
- package/src/controls/scaleSkew.ts +92 -0
- package/src/controls/skew.ts +242 -0
- package/src/controls/util.ts +154 -0
- package/src/controls/wrapWithFireEvent.ts +25 -0
- package/src/controls/wrapWithFixedAnchor.ts +20 -0
- package/src/env/browser.ts +32 -0
- package/src/env/index.ts +24 -0
- package/src/env/node.ts +56 -0
- package/src/env/types.ts +15 -0
- package/src/filters/{base_filter.class.js → BaseFilter.ts} +192 -151
- package/src/filters/BlendColor.ts +217 -0
- package/src/filters/BlendImage.ts +228 -0
- package/src/filters/Blur.ts +179 -0
- package/src/filters/Boilerplate.ts +94 -0
- package/src/filters/Brightness.ts +83 -0
- package/src/filters/Canvas2dFilterBackend.ts +65 -0
- package/src/filters/ColorMatrix.ts +145 -0
- package/src/filters/ColorMatrixFilters.ts +77 -0
- package/src/filters/Composed.ts +76 -0
- package/src/filters/Contrast.ts +82 -0
- package/src/filters/Convolute.ts +184 -0
- package/src/filters/FilterBackend.ts +34 -0
- package/src/filters/GLProbes/GLProbe.ts +11 -0
- package/src/filters/GLProbes/NodeGLProbe.ts +15 -0
- package/src/filters/GLProbes/WebGLProbe.ts +46 -0
- package/src/filters/Gamma.ts +110 -0
- package/src/filters/Grayscale.ts +102 -0
- package/src/filters/HueRotation.ts +62 -0
- package/src/filters/Invert.ts +99 -0
- package/src/filters/Noise.ts +94 -0
- package/src/filters/Pixelate.ts +96 -0
- package/src/filters/RemoveColor.ts +135 -0
- package/src/filters/Resize.ts +538 -0
- package/src/filters/Saturation.ts +87 -0
- package/src/filters/Vibrance.ts +88 -0
- package/src/filters/WebGLFilterBackend.ts +430 -0
- package/src/filters/filters.ts +28 -0
- package/src/filters/index.ts +5 -0
- package/src/filters/shaders/baseFilter.ts +19 -0
- package/src/filters/shaders/blendColor.ts +33 -0
- package/src/filters/shaders/blendImage.ts +32 -0
- package/src/filters/shaders/blur.ts +24 -0
- package/src/filters/shaders/brightness.ts +11 -0
- package/src/filters/shaders/colorMatrix.ts +12 -0
- package/src/filters/shaders/constrast.ts +11 -0
- package/src/filters/shaders/convolute.ts +154 -0
- package/src/filters/shaders/gamma.ts +15 -0
- package/src/filters/shaders/grayscale.ts +36 -0
- package/src/filters/shaders/invert.ts +19 -0
- package/src/filters/shaders/noise.ts +16 -0
- package/src/filters/shaders/pixelate.ts +19 -0
- package/src/filters/shaders/removeColor.ts +13 -0
- package/src/filters/shaders/saturation.ts +15 -0
- package/src/filters/shaders/vibrance.ts +16 -0
- package/src/filters/typedefs.ts +65 -0
- package/src/gradient/Gradient.ts +406 -0
- package/src/gradient/constants.ts +12 -0
- package/src/gradient/parser/index.ts +3 -0
- package/src/gradient/parser/misc.ts +13 -0
- package/src/gradient/parser/parseColorStops.ts +56 -0
- package/src/gradient/parser/parseCoords.ts +73 -0
- package/src/gradient/typedefs.ts +104 -0
- package/src/mixins/{eraser_brush.mixin.js → eraser_brush.mixin.ts} +350 -239
- package/src/parkinglot/canvas_animation.mixin.ts +121 -0
- package/src/parkinglot/straighten.ts +58 -0
- package/src/parser/applyViewboxTransform.ts +157 -0
- package/src/parser/attributes.ts +25 -0
- package/src/parser/constants.ts +115 -0
- package/src/parser/doesSomeParentMatch.ts +19 -0
- package/src/parser/elementById.ts +21 -0
- package/src/parser/elementMatchesRule.ts +16 -0
- package/src/parser/elements_parser.ts +191 -0
- package/src/parser/getCSSRules.ts +62 -0
- package/src/parser/getGlobalStylesForElement.ts +19 -0
- package/src/parser/getGradientDefs.ts +31 -0
- package/src/parser/getMultipleNodes.ts +15 -0
- package/src/parser/getSvgRegex.ts +5 -0
- package/src/parser/hasAncestorWithNodeName.ts +14 -0
- package/src/parser/index.ts +9 -0
- package/src/parser/loadSVGFromString.ts +26 -0
- package/src/parser/loadSVGFromURL.ts +40 -0
- package/src/parser/normalizeAttr.ts +10 -0
- package/src/parser/normalizeValue.ts +63 -0
- package/src/parser/parseAttributes.ts +90 -0
- package/src/parser/parseElements.ts +28 -0
- package/src/parser/parseFontDeclaration.ts +44 -0
- package/src/parser/parsePointsAttribute.ts +34 -0
- package/src/parser/parseSVGDocument.ts +93 -0
- package/src/parser/parseStyleAttribute.ts +27 -0
- package/src/parser/parseStyleObject.ts +15 -0
- package/src/parser/parseStyleString.ts +16 -0
- package/src/parser/parseTransformAttribute.ts +155 -0
- package/src/parser/parseUseDirectives.ts +78 -0
- package/src/parser/percent.ts +27 -0
- package/src/parser/recursivelyParseGradientsXlink.ts +42 -0
- package/src/parser/rotateMatrix.ts +21 -0
- package/src/parser/scaleMatrix.ts +9 -0
- package/src/parser/selectorMatches.ts +25 -0
- package/src/parser/setStrokeFillOpacity.ts +40 -0
- package/src/parser/skewMatrix.ts +6 -0
- package/src/parser/translateMatrix.ts +8 -0
- package/src/shapes/ActiveSelection.ts +189 -0
- package/src/shapes/Circle.ts +242 -0
- package/src/shapes/Ellipse.ts +179 -0
- package/src/shapes/Group.ts +1100 -0
- package/src/shapes/IText/DraggableTextDelegate.ts +382 -0
- package/src/shapes/IText/IText.ts +693 -0
- package/src/shapes/IText/ITextBehavior.ts +1064 -0
- package/src/shapes/IText/ITextClickBehavior.ts +325 -0
- package/src/shapes/IText/ITextKeyBehavior.ts +685 -0
- package/src/shapes/IText/constants.ts +47 -0
- package/src/shapes/Image.ts +841 -0
- package/src/shapes/Line.ts +346 -0
- package/src/shapes/Object/AnimatableObject.ts +106 -0
- package/src/shapes/Object/FabricObject.ts +29 -0
- package/src/shapes/Object/FabricObjectSVGExportMixin.ts +277 -0
- package/src/shapes/Object/InteractiveObject.ts +672 -0
- package/src/shapes/Object/Object.ts +1561 -0
- package/src/shapes/Object/ObjectGeometry.ts +813 -0
- package/src/shapes/Object/ObjectOrigin.ts +276 -0
- package/src/shapes/Object/StackedObject.ts +206 -0
- package/src/shapes/Object/defaultValues.ts +108 -0
- package/src/shapes/Object/types/BaseProps.ts +96 -0
- package/src/shapes/Object/types/BorderProps.ts +40 -0
- package/src/shapes/Object/types/ControlProps.ts +69 -0
- package/src/shapes/Object/types/FabricObjectProps.ts +111 -0
- package/src/shapes/Object/types/FillStrokeProps.ts +90 -0
- package/src/shapes/Object/types/LockInteractionProps.ts +57 -0
- package/src/shapes/Object/types/ObjectProps.ts +46 -0
- package/src/shapes/Object/types/SerializedObjectProps.ts +73 -0
- package/src/shapes/Object/types/index.ts +8 -0
- package/src/shapes/Path.ts +416 -0
- package/src/shapes/Polygon.ts +20 -0
- package/src/shapes/Polyline.ts +359 -0
- package/src/shapes/Rect.ts +233 -0
- package/src/shapes/Text/StyledText.ts +329 -0
- package/src/shapes/Text/Text.ts +1884 -0
- package/src/shapes/Text/TextSVGExportMixin.ts +288 -0
- package/src/shapes/Text/constants.ts +91 -0
- package/src/shapes/Textbox.ts +477 -0
- package/src/shapes/Triangle.ts +60 -0
- package/src/typedefs.ts +115 -0
- package/src/util/animation/AnimationBase.ts +166 -0
- package/src/util/animation/AnimationFrameProvider.ts +9 -0
- package/src/util/animation/AnimationRegistry.ts +58 -0
- package/src/util/animation/ArrayAnimation.ts +27 -0
- package/src/util/animation/ColorAnimation.ts +74 -0
- package/src/util/animation/ValueAnimation.ts +29 -0
- package/src/util/animation/animate.ts +74 -0
- package/src/util/animation/easing.ts +327 -0
- package/src/util/animation/types.ts +136 -0
- package/src/util/applyMixins.ts +22 -0
- package/src/util/dom_event.ts +28 -0
- package/src/util/dom_misc.ts +121 -0
- package/src/util/dom_request.ts +64 -0
- package/src/util/dom_style.ts +20 -0
- package/src/util/fireEvent.ts +15 -0
- package/src/util/index.ts +102 -0
- package/src/util/internals/cloneDeep.ts +2 -0
- package/src/util/internals/getRandomInt.ts +8 -0
- package/src/util/internals/ifNaN.ts +9 -0
- package/src/util/internals/index.ts +3 -0
- package/src/util/internals/removeFromArray.ts +14 -0
- package/src/util/internals/uid.ts +3 -0
- package/src/util/lang_string.ts +79 -0
- package/src/util/misc/boundingBoxFromPoints.ts +37 -0
- package/src/util/misc/capValue.ts +2 -0
- package/src/util/misc/cos.ts +24 -0
- package/src/util/misc/dom.ts +50 -0
- package/src/util/misc/findScaleTo.ts +44 -0
- package/src/util/misc/groupSVGElements.ts +15 -0
- package/src/util/misc/isTransparent.ts +28 -0
- package/src/util/misc/matrix.ts +207 -0
- package/src/util/misc/mergeClipPaths.ts +40 -0
- package/src/util/misc/objectEnlive.ts +189 -0
- package/src/util/misc/objectTransforms.ts +129 -0
- package/src/util/misc/pick.ts +29 -0
- package/src/util/misc/planeChange.ts +136 -0
- package/src/util/misc/projectStroke/StrokeLineCapProjections.ts +112 -0
- package/src/util/misc/projectStroke/StrokeLineJoinProjections.ts +226 -0
- package/src/util/misc/projectStroke/StrokeProjectionsBase.ts +75 -0
- package/src/util/misc/projectStroke/index.ts +53 -0
- package/src/util/misc/projectStroke/types.ts +24 -0
- package/src/util/misc/radiansDegreesConversion.ts +18 -0
- package/src/util/misc/resolveOrigin.ts +22 -0
- package/src/util/misc/rotatePoint.ts +15 -0
- package/src/util/misc/sin.ts +26 -0
- package/src/util/misc/svgParsing.ts +181 -0
- package/src/util/misc/textStyles.ts +134 -0
- package/src/util/misc/toFixed.ts +8 -0
- package/src/util/misc/vectors.ts +82 -0
- package/src/util/path/index.ts +1038 -0
- package/src/util/path/regex.ts +41 -0
- package/src/util/path/typechecks.ts +145 -0
- package/src/util/path/typedefs.ts +305 -0
- package/src/util/transform_matrix_removal.ts +60 -0
- package/src/util/types.ts +78 -0
- package/tsconfig.json +106 -0
- package/HEADER.js +0 -203
- package/build.js +0 -287
- package/dist/fabric.js +0 -31187
- package/dist/fabric.min.js +0 -1
- package/old-travis-reference.yml +0 -97
- package/src/brushes/circle_brush.class.js +0 -144
- package/src/brushes/pattern_brush.class.js +0 -61
- package/src/brushes/pencil_brush.class.js +0 -310
- package/src/brushes/spray_brush.class.js +0 -219
- package/src/canvas.class.js +0 -1312
- package/src/color.class.js +0 -636
- package/src/control.class.js +0 -339
- package/src/controls.actions.js +0 -740
- package/src/controls.render.js +0 -99
- package/src/elements_parser.js +0 -152
- package/src/filters/2d_backend.class.js +0 -65
- package/src/filters/blendcolor_filter.class.js +0 -251
- package/src/filters/blendimage_filter.class.js +0 -247
- package/src/filters/blur_filter.class.js +0 -217
- package/src/filters/brightness_filter.class.js +0 -113
- package/src/filters/colormatrix_filter.class.js +0 -159
- package/src/filters/composed_filter.class.js +0 -72
- package/src/filters/contrast_filter.class.js +0 -113
- package/src/filters/convolute_filter.class.js +0 -352
- package/src/filters/filter_boilerplate.js +0 -111
- package/src/filters/filter_generator.js +0 -85
- package/src/filters/gamma_filter.class.js +0 -136
- package/src/filters/grayscale_filter.class.js +0 -154
- package/src/filters/hue_rotation.class.js +0 -107
- package/src/filters/invert_filter.class.js +0 -111
- package/src/filters/noise_filter.class.js +0 -134
- package/src/filters/pixelate_filter.class.js +0 -137
- package/src/filters/removecolor_filter.class.js +0 -173
- package/src/filters/resize_filter.class.js +0 -490
- package/src/filters/saturate_filter.class.js +0 -119
- package/src/filters/vibrance_filter.class.js +0 -122
- package/src/filters/webgl_backend.class.js +0 -396
- package/src/globalFabric.js +0 -4
- package/src/gradient.class.js +0 -490
- package/src/intersection.class.js +0 -172
- package/src/log.js +0 -11
- package/src/mixins/animation.mixin.js +0 -231
- package/src/mixins/canvas_dataurl_exporter.mixin.js +0 -97
- package/src/mixins/canvas_events.mixin.js +0 -974
- package/src/mixins/canvas_gestures.mixin.js +0 -149
- package/src/mixins/canvas_grouping.mixin.js +0 -177
- package/src/mixins/canvas_serialization.mixin.js +0 -228
- package/src/mixins/collection.mixin.js +0 -170
- package/src/mixins/default_controls.js +0 -114
- package/src/mixins/itext.svg_export.js +0 -241
- package/src/mixins/itext_behavior.mixin.js +0 -940
- package/src/mixins/itext_click_behavior.mixin.js +0 -278
- package/src/mixins/itext_key_behavior.mixin.js +0 -694
- package/src/mixins/object.svg_export.js +0 -258
- package/src/mixins/object_geometry.mixin.js +0 -683
- package/src/mixins/object_interactivity.mixin.js +0 -314
- package/src/mixins/object_origin.mixin.js +0 -255
- package/src/mixins/object_stacking.mixin.js +0 -80
- package/src/mixins/object_straightening.mixin.js +0 -80
- package/src/mixins/observable.mixin.js +0 -141
- package/src/mixins/shared_methods.mixin.js +0 -94
- package/src/mixins/stateful.mixin.js +0 -107
- package/src/mixins/text_style.mixin.js +0 -324
- package/src/parser.js +0 -1090
- package/src/pattern.class.js +0 -189
- package/src/point.class.js +0 -337
- package/src/shadow.class.js +0 -195
- package/src/shapes/active_selection.class.js +0 -155
- package/src/shapes/circle.class.js +0 -210
- package/src/shapes/ellipse.class.js +0 -181
- package/src/shapes/group.class.js +0 -593
- package/src/shapes/image.class.js +0 -764
- package/src/shapes/itext.class.js +0 -526
- package/src/shapes/line.class.js +0 -324
- package/src/shapes/object.class.js +0 -2008
- package/src/shapes/path.class.js +0 -384
- package/src/shapes/polygon.class.js +0 -81
- package/src/shapes/polyline.class.js +0 -268
- package/src/shapes/rect.class.js +0 -187
- package/src/shapes/text.class.js +0 -1696
- package/src/shapes/textbox.class.js +0 -461
- package/src/shapes/triangle.class.js +0 -93
- package/src/static_canvas.class.js +0 -1881
- package/src/util/anim_ease.js +0 -398
- package/src/util/animate.js +0 -254
- package/src/util/animate_color.js +0 -74
- package/src/util/dom_event.js +0 -50
- package/src/util/dom_misc.js +0 -300
- package/src/util/dom_request.js +0 -54
- package/src/util/dom_style.js +0 -70
- package/src/util/lang_array.js +0 -94
- package/src/util/lang_class.js +0 -115
- package/src/util/lang_object.js +0 -75
- package/src/util/lang_string.js +0 -110
- package/src/util/misc.js +0 -1330
- package/src/util/named_accessors.mixin.js +0 -428
- package/src/util/path.js +0 -829
|
@@ -0,0 +1,1100 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import type { CollectionEvents, ObjectEvents } from '../EventTypeDefs';
|
|
3
|
+
import { createCollectionMixin } from '../Collection';
|
|
4
|
+
import { resolveOrigin } from '../util/misc/resolveOrigin';
|
|
5
|
+
import { Point } from '../Point';
|
|
6
|
+
import { cos } from '../util/misc/cos';
|
|
7
|
+
import type { TClassProperties, TSVGReviver } from '../typedefs';
|
|
8
|
+
import { makeBoundingBoxFromPoints } from '../util/misc/boundingBoxFromPoints';
|
|
9
|
+
import {
|
|
10
|
+
invertTransform,
|
|
11
|
+
multiplyTransformMatrices,
|
|
12
|
+
transformPoint,
|
|
13
|
+
} from '../util/misc/matrix';
|
|
14
|
+
import {
|
|
15
|
+
enlivenObjectEnlivables,
|
|
16
|
+
enlivenObjects,
|
|
17
|
+
} from '../util/misc/objectEnlive';
|
|
18
|
+
import { applyTransformToObject } from '../util/misc/objectTransforms';
|
|
19
|
+
import { degreesToRadians } from '../util/misc/radiansDegreesConversion';
|
|
20
|
+
import { sin } from '../util/misc/sin';
|
|
21
|
+
import { FabricObject } from './Object/FabricObject';
|
|
22
|
+
import { Rect } from './Rect';
|
|
23
|
+
import { classRegistry } from '../ClassRegistry';
|
|
24
|
+
import {
|
|
25
|
+
FabricObjectProps,
|
|
26
|
+
SerializedObjectProps,
|
|
27
|
+
TProps,
|
|
28
|
+
} from './Object/types';
|
|
29
|
+
|
|
30
|
+
export type LayoutContextType =
|
|
31
|
+
| 'initialization'
|
|
32
|
+
| 'object_modified'
|
|
33
|
+
| 'added'
|
|
34
|
+
| 'removed'
|
|
35
|
+
| 'layout_change'
|
|
36
|
+
| 'imperative';
|
|
37
|
+
|
|
38
|
+
export type LayoutContext = {
|
|
39
|
+
type: LayoutContextType;
|
|
40
|
+
/**
|
|
41
|
+
* array of objects starting from the object that triggered the call to the current one
|
|
42
|
+
*/
|
|
43
|
+
path?: Group[];
|
|
44
|
+
[key: string]: any;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export type GroupEvents = ObjectEvents &
|
|
48
|
+
CollectionEvents & {
|
|
49
|
+
layout: {
|
|
50
|
+
context: LayoutContext;
|
|
51
|
+
result: LayoutResult;
|
|
52
|
+
diff: Point;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export type LayoutStrategy =
|
|
57
|
+
| 'fit-content'
|
|
58
|
+
| 'fit-content-lazy'
|
|
59
|
+
| 'fixed'
|
|
60
|
+
| 'clip-path';
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* positioning and layout data **relative** to instance's parent
|
|
64
|
+
*/
|
|
65
|
+
export type LayoutResult = {
|
|
66
|
+
/**
|
|
67
|
+
* new centerX as measured by the containing plane (same as `left` with `originX` set to `center`)
|
|
68
|
+
*/
|
|
69
|
+
centerX: number;
|
|
70
|
+
/**
|
|
71
|
+
* new centerY as measured by the containing plane (same as `top` with `originY` set to `center`)
|
|
72
|
+
*/
|
|
73
|
+
centerY: number;
|
|
74
|
+
/**
|
|
75
|
+
* correctionX to translate objects by, measured as `centerX`
|
|
76
|
+
*/
|
|
77
|
+
correctionX?: number;
|
|
78
|
+
/**
|
|
79
|
+
* correctionY to translate objects by, measured as `centerY`
|
|
80
|
+
*/
|
|
81
|
+
correctionY?: number;
|
|
82
|
+
width: number;
|
|
83
|
+
height: number;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export interface GroupOwnProps {
|
|
87
|
+
layout: LayoutStrategy;
|
|
88
|
+
subTargetCheck: boolean;
|
|
89
|
+
interactive: boolean;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface SerializedGroupProps
|
|
93
|
+
extends SerializedObjectProps,
|
|
94
|
+
GroupOwnProps {
|
|
95
|
+
objects: SerializedObjectProps[];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface GroupProps extends FabricObjectProps, GroupOwnProps {}
|
|
99
|
+
|
|
100
|
+
export const groupDefaultValues = {
|
|
101
|
+
layout: 'fit-content',
|
|
102
|
+
strokeWidth: 0,
|
|
103
|
+
subTargetCheck: false,
|
|
104
|
+
interactive: false,
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @fires object:added
|
|
109
|
+
* @fires object:removed
|
|
110
|
+
* @fires layout once layout completes
|
|
111
|
+
*/
|
|
112
|
+
export class Group extends createCollectionMixin(
|
|
113
|
+
FabricObject<GroupProps, SerializedGroupProps, GroupEvents>
|
|
114
|
+
) {
|
|
115
|
+
/**
|
|
116
|
+
* Specifies the **layout strategy** for instance
|
|
117
|
+
* Used by `getLayoutStrategyResult` to calculate layout
|
|
118
|
+
* `fit-content`, `fit-content-lazy`, `fixed`, `clip-path` are supported out of the box
|
|
119
|
+
* @default
|
|
120
|
+
*/
|
|
121
|
+
declare layout: LayoutStrategy;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Used to optimize performance
|
|
125
|
+
* set to `false` if you don't need contained objects to be targets of events
|
|
126
|
+
* @default
|
|
127
|
+
* @type boolean
|
|
128
|
+
*/
|
|
129
|
+
declare subTargetCheck: boolean;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Used to allow targeting of object inside groups.
|
|
133
|
+
* set to true if you want to select an object inside a group.\
|
|
134
|
+
* **REQUIRES** `subTargetCheck` set to true
|
|
135
|
+
* @default
|
|
136
|
+
* @type boolean
|
|
137
|
+
*/
|
|
138
|
+
declare interactive: boolean;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Used internally to optimize performance
|
|
142
|
+
* Once an object is selected, instance is rendered without the selected object.
|
|
143
|
+
* This way instance is cached only once for the entire interaction with the selected object.
|
|
144
|
+
* @private
|
|
145
|
+
*/
|
|
146
|
+
protected _activeObjects: FabricObject[] = [];
|
|
147
|
+
|
|
148
|
+
static stateProperties: string[] = [
|
|
149
|
+
...FabricObject.stateProperties,
|
|
150
|
+
'layout',
|
|
151
|
+
];
|
|
152
|
+
|
|
153
|
+
static ownDefaults: Record<string, any> = groupDefaultValues;
|
|
154
|
+
private __objectSelectionTracker: (ev: ObjectEvents['selected']) => void;
|
|
155
|
+
private __objectSelectionDisposer: (ev: ObjectEvents['deselected']) => void;
|
|
156
|
+
private _firstLayoutDone = false;
|
|
157
|
+
|
|
158
|
+
static getDefaults(): Record<string, any> {
|
|
159
|
+
return {
|
|
160
|
+
...super.getDefaults(),
|
|
161
|
+
...Group.ownDefaults,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Constructor
|
|
167
|
+
*
|
|
168
|
+
* @param {FabricObject[]} [objects] instance objects
|
|
169
|
+
* @param {Object} [options] Options object
|
|
170
|
+
* @param {boolean} [objectsRelativeToGroup] true if objects exist in group coordinate plane
|
|
171
|
+
*/
|
|
172
|
+
constructor(
|
|
173
|
+
objects: FabricObject[] = [],
|
|
174
|
+
options: Partial<GroupProps> = {},
|
|
175
|
+
objectsRelativeToGroup?: boolean
|
|
176
|
+
) {
|
|
177
|
+
super();
|
|
178
|
+
this._objects = objects;
|
|
179
|
+
this.__objectMonitor = this.__objectMonitor.bind(this);
|
|
180
|
+
this.__objectSelectionTracker = this.__objectSelectionMonitor.bind(
|
|
181
|
+
this,
|
|
182
|
+
true
|
|
183
|
+
);
|
|
184
|
+
this.__objectSelectionDisposer = this.__objectSelectionMonitor.bind(
|
|
185
|
+
this,
|
|
186
|
+
false
|
|
187
|
+
);
|
|
188
|
+
// setting angle, skewX, skewY must occur after initial layout
|
|
189
|
+
this.set({ ...options, angle: 0, skewX: 0, skewY: 0 });
|
|
190
|
+
this.forEachObject((object) => {
|
|
191
|
+
this.enterGroup(object, false);
|
|
192
|
+
});
|
|
193
|
+
this._applyLayoutStrategy({
|
|
194
|
+
type: 'initialization',
|
|
195
|
+
options,
|
|
196
|
+
objectsRelativeToGroup,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Checks if object can enter group and logs relevant warnings
|
|
202
|
+
* @private
|
|
203
|
+
* @param {FabricObject} object
|
|
204
|
+
* @returns
|
|
205
|
+
*/
|
|
206
|
+
canEnterGroup(object: FabricObject) {
|
|
207
|
+
if (object === this || this.isDescendantOf(object)) {
|
|
208
|
+
// prevent circular object tree
|
|
209
|
+
/* _DEV_MODE_START_ */
|
|
210
|
+
console.error(
|
|
211
|
+
'fabric.Group: circular object trees are not supported, this call has no effect'
|
|
212
|
+
);
|
|
213
|
+
/* _DEV_MODE_END_ */
|
|
214
|
+
return false;
|
|
215
|
+
} else if (this._objects.indexOf(object) !== -1) {
|
|
216
|
+
// is already in the objects array
|
|
217
|
+
/* _DEV_MODE_START_ */
|
|
218
|
+
console.error(
|
|
219
|
+
'fabric.Group: duplicate objects are not supported inside group, this call has no effect'
|
|
220
|
+
);
|
|
221
|
+
/* _DEV_MODE_END_ */
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Override this method to enhance performance (for groups with a lot of objects).
|
|
229
|
+
* If Overriding, be sure not pass illegal objects to group - it will break your app.
|
|
230
|
+
* @private
|
|
231
|
+
*/
|
|
232
|
+
protected _filterObjectsBeforeEnteringGroup(objects: FabricObject[]) {
|
|
233
|
+
return objects.filter((object, index, array) => {
|
|
234
|
+
// can enter AND is the first occurrence of the object in the passed args (to prevent adding duplicates)
|
|
235
|
+
return this.canEnterGroup(object) && array.indexOf(object) === index;
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Add objects
|
|
241
|
+
* @param {...FabricObject[]} objects
|
|
242
|
+
*/
|
|
243
|
+
add(...objects: FabricObject[]) {
|
|
244
|
+
const allowedObjects = this._filterObjectsBeforeEnteringGroup(objects);
|
|
245
|
+
const size = super.add(...allowedObjects);
|
|
246
|
+
this._onAfterObjectsChange('added', allowedObjects);
|
|
247
|
+
return size;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Inserts an object into collection at specified index
|
|
252
|
+
* @param {FabricObject[]} objects Object to insert
|
|
253
|
+
* @param {Number} index Index to insert object at
|
|
254
|
+
*/
|
|
255
|
+
insertAt(index: number, ...objects: FabricObject[]) {
|
|
256
|
+
const allowedObjects = this._filterObjectsBeforeEnteringGroup(objects);
|
|
257
|
+
const size = super.insertAt(index, ...allowedObjects);
|
|
258
|
+
this._onAfterObjectsChange('added', allowedObjects);
|
|
259
|
+
return size;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Remove objects
|
|
264
|
+
* @param {...FabricObject[]} objects
|
|
265
|
+
* @returns {FabricObject[]} removed objects
|
|
266
|
+
*/
|
|
267
|
+
remove(...objects: FabricObject[]) {
|
|
268
|
+
const removed = super.remove(...objects);
|
|
269
|
+
this._onAfterObjectsChange('removed', removed);
|
|
270
|
+
return removed;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
_onObjectAdded(object: FabricObject) {
|
|
274
|
+
this.enterGroup(object, true);
|
|
275
|
+
this.fire('object:added', { target: object });
|
|
276
|
+
object.fire('added', { target: this });
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
_onRelativeObjectAdded(object: FabricObject) {
|
|
280
|
+
this.enterGroup(object, false);
|
|
281
|
+
this.fire('object:added', { target: object });
|
|
282
|
+
object.fire('added', { target: this });
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* @private
|
|
287
|
+
* @param {FabricObject} object
|
|
288
|
+
* @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it
|
|
289
|
+
*/
|
|
290
|
+
_onObjectRemoved(object: FabricObject, removeParentTransform?: boolean) {
|
|
291
|
+
this.exitGroup(object, removeParentTransform);
|
|
292
|
+
this.fire('object:removed', { target: object });
|
|
293
|
+
object.fire('removed', { target: this });
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* @private
|
|
298
|
+
* @param {'added'|'removed'} type
|
|
299
|
+
* @param {FabricObject[]} targets
|
|
300
|
+
*/
|
|
301
|
+
_onAfterObjectsChange(type: 'added' | 'removed', targets: FabricObject[]) {
|
|
302
|
+
this._applyLayoutStrategy({
|
|
303
|
+
type: type,
|
|
304
|
+
targets: targets,
|
|
305
|
+
});
|
|
306
|
+
this._set('dirty', true);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
_onStackOrderChanged() {
|
|
310
|
+
this._set('dirty', true);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* @private
|
|
315
|
+
* @param {string} key
|
|
316
|
+
* @param {*} value
|
|
317
|
+
*/
|
|
318
|
+
_set(key: string, value: any) {
|
|
319
|
+
const prev = this[key];
|
|
320
|
+
super._set(key, value);
|
|
321
|
+
if (key === 'canvas' && prev !== value) {
|
|
322
|
+
this.forEachObject((object) => {
|
|
323
|
+
object._set(key, value);
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
if (key === 'layout' && prev !== value) {
|
|
327
|
+
this._applyLayoutStrategy({
|
|
328
|
+
type: 'layout_change',
|
|
329
|
+
layout: value,
|
|
330
|
+
prevLayout: prev,
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
if (key === 'interactive') {
|
|
334
|
+
this.forEachObject((object) => this._watchObject(value, object));
|
|
335
|
+
}
|
|
336
|
+
return this;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* @private
|
|
341
|
+
*/
|
|
342
|
+
_shouldSetNestedCoords() {
|
|
343
|
+
return this.subTargetCheck;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Remove all objects
|
|
348
|
+
* @returns {FabricObject[]} removed objects
|
|
349
|
+
*/
|
|
350
|
+
removeAll() {
|
|
351
|
+
this._activeObjects = [];
|
|
352
|
+
return this.remove(...this._objects);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* invalidates layout on object modified
|
|
357
|
+
* @private
|
|
358
|
+
*/
|
|
359
|
+
__objectMonitor(ev: ObjectEvents['modified']) {
|
|
360
|
+
this._applyLayoutStrategy({ ...ev, type: 'object_modified' });
|
|
361
|
+
this._set('dirty', true);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* keeps track of the selected objects
|
|
366
|
+
* @private
|
|
367
|
+
*/
|
|
368
|
+
__objectSelectionMonitor<T extends boolean>(
|
|
369
|
+
selected: T,
|
|
370
|
+
{ target: object }: ObjectEvents[T extends true ? 'selected' : 'deselected']
|
|
371
|
+
) {
|
|
372
|
+
if (selected) {
|
|
373
|
+
this._activeObjects.push(object);
|
|
374
|
+
this._set('dirty', true);
|
|
375
|
+
} else if (this._activeObjects.length > 0) {
|
|
376
|
+
const index = this._activeObjects.indexOf(object);
|
|
377
|
+
if (index > -1) {
|
|
378
|
+
this._activeObjects.splice(index, 1);
|
|
379
|
+
this._set('dirty', true);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* @private
|
|
386
|
+
* @param {boolean} watch
|
|
387
|
+
* @param {FabricObject} object
|
|
388
|
+
*/
|
|
389
|
+
_watchObject(watch: boolean, object: FabricObject) {
|
|
390
|
+
const directive = watch ? 'on' : 'off';
|
|
391
|
+
// make sure we listen only once
|
|
392
|
+
watch && this._watchObject(false, object);
|
|
393
|
+
object[directive]('changed', this.__objectMonitor);
|
|
394
|
+
object[directive]('modified', this.__objectMonitor);
|
|
395
|
+
object[directive]('selected', this.__objectSelectionTracker);
|
|
396
|
+
object[directive]('deselected', this.__objectSelectionDisposer);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* @private
|
|
401
|
+
* @param {FabricObject} object
|
|
402
|
+
* @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane
|
|
403
|
+
* @returns {boolean} true if object entered group
|
|
404
|
+
*/
|
|
405
|
+
enterGroup(object: FabricObject, removeParentTransform?: boolean) {
|
|
406
|
+
if (object.group) {
|
|
407
|
+
object.group.remove(object);
|
|
408
|
+
}
|
|
409
|
+
this._enterGroup(object, removeParentTransform);
|
|
410
|
+
return true;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* @private
|
|
415
|
+
* @param {FabricObject} object
|
|
416
|
+
* @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane
|
|
417
|
+
*/
|
|
418
|
+
_enterGroup(object: FabricObject, removeParentTransform?: boolean) {
|
|
419
|
+
if (removeParentTransform) {
|
|
420
|
+
// can this be converted to utils (sendObjectToPlane)?
|
|
421
|
+
applyTransformToObject(
|
|
422
|
+
object,
|
|
423
|
+
multiplyTransformMatrices(
|
|
424
|
+
invertTransform(this.calcTransformMatrix()),
|
|
425
|
+
object.calcTransformMatrix()
|
|
426
|
+
)
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
this._shouldSetNestedCoords() && object.setCoords();
|
|
430
|
+
object._set('group', this);
|
|
431
|
+
object._set('canvas', this.canvas);
|
|
432
|
+
this.interactive && this._watchObject(true, object);
|
|
433
|
+
const activeObject =
|
|
434
|
+
this.canvas &&
|
|
435
|
+
this.canvas.getActiveObject &&
|
|
436
|
+
this.canvas.getActiveObject();
|
|
437
|
+
// if we are adding the activeObject in a group
|
|
438
|
+
if (
|
|
439
|
+
activeObject &&
|
|
440
|
+
(activeObject === object || object.isDescendantOf(activeObject))
|
|
441
|
+
) {
|
|
442
|
+
this._activeObjects.push(object);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* @private
|
|
448
|
+
* @param {FabricObject} object
|
|
449
|
+
* @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it
|
|
450
|
+
*/
|
|
451
|
+
exitGroup(object: FabricObject, removeParentTransform?: boolean) {
|
|
452
|
+
this._exitGroup(object, removeParentTransform);
|
|
453
|
+
object._set('canvas', undefined);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* @private
|
|
458
|
+
* @param {FabricObject} object
|
|
459
|
+
* @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it
|
|
460
|
+
*/
|
|
461
|
+
_exitGroup(object: FabricObject, removeParentTransform?: boolean) {
|
|
462
|
+
object._set('group', undefined);
|
|
463
|
+
if (!removeParentTransform) {
|
|
464
|
+
applyTransformToObject(
|
|
465
|
+
object,
|
|
466
|
+
multiplyTransformMatrices(
|
|
467
|
+
this.calcTransformMatrix(),
|
|
468
|
+
object.calcTransformMatrix()
|
|
469
|
+
)
|
|
470
|
+
);
|
|
471
|
+
object.setCoords();
|
|
472
|
+
}
|
|
473
|
+
this._watchObject(false, object);
|
|
474
|
+
const index =
|
|
475
|
+
this._activeObjects.length > 0 ? this._activeObjects.indexOf(object) : -1;
|
|
476
|
+
if (index > -1) {
|
|
477
|
+
this._activeObjects.splice(index, 1);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Decide if the object should cache or not. Create its own cache level
|
|
483
|
+
* needsItsOwnCache should be used when the object drawing method requires
|
|
484
|
+
* a cache step. None of the fabric classes requires it.
|
|
485
|
+
* Generally you do not cache objects in groups because the group is already cached.
|
|
486
|
+
* @return {Boolean}
|
|
487
|
+
*/
|
|
488
|
+
shouldCache() {
|
|
489
|
+
const ownCache = FabricObject.prototype.shouldCache.call(this);
|
|
490
|
+
if (ownCache) {
|
|
491
|
+
for (let i = 0; i < this._objects.length; i++) {
|
|
492
|
+
if (this._objects[i].willDrawShadow()) {
|
|
493
|
+
this.ownCaching = false;
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
return ownCache;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Check if this object or a child object will cast a shadow
|
|
503
|
+
* @return {Boolean}
|
|
504
|
+
*/
|
|
505
|
+
willDrawShadow() {
|
|
506
|
+
if (FabricObject.prototype.willDrawShadow.call(this)) {
|
|
507
|
+
return true;
|
|
508
|
+
}
|
|
509
|
+
for (let i = 0; i < this._objects.length; i++) {
|
|
510
|
+
if (this._objects[i].willDrawShadow()) {
|
|
511
|
+
return true;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
return false;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Check if instance or its group are caching, recursively up
|
|
519
|
+
* @return {Boolean}
|
|
520
|
+
*/
|
|
521
|
+
isOnACache(): boolean {
|
|
522
|
+
return this.ownCaching || (!!this.group && this.group.isOnACache());
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Execute the drawing operation for an object on a specified context
|
|
527
|
+
* @param {CanvasRenderingContext2D} ctx Context to render on
|
|
528
|
+
*/
|
|
529
|
+
drawObject(ctx: CanvasRenderingContext2D) {
|
|
530
|
+
this._renderBackground(ctx);
|
|
531
|
+
for (let i = 0; i < this._objects.length; i++) {
|
|
532
|
+
// TODO: handle rendering edge case somehow
|
|
533
|
+
if (
|
|
534
|
+
this.canvas?.preserveObjectStacking &&
|
|
535
|
+
this._objects[i].group !== this
|
|
536
|
+
) {
|
|
537
|
+
ctx.save();
|
|
538
|
+
ctx.transform(...invertTransform(this.calcTransformMatrix()));
|
|
539
|
+
this._objects[i].render(ctx);
|
|
540
|
+
ctx.restore();
|
|
541
|
+
} else if (this._objects[i].group === this) {
|
|
542
|
+
this._objects[i].render(ctx);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
this._drawClipPath(ctx, this.clipPath);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* @override
|
|
550
|
+
* @return {Boolean}
|
|
551
|
+
*/
|
|
552
|
+
setCoords() {
|
|
553
|
+
super.setCoords();
|
|
554
|
+
this._shouldSetNestedCoords() &&
|
|
555
|
+
this.forEachObject((object) => object.setCoords());
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Renders instance on a given context
|
|
560
|
+
* @param {CanvasRenderingContext2D} ctx context to render instance on
|
|
561
|
+
*/
|
|
562
|
+
render(ctx: CanvasRenderingContext2D) {
|
|
563
|
+
this._transformDone = true;
|
|
564
|
+
super.render(ctx);
|
|
565
|
+
this._transformDone = false;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* @public
|
|
570
|
+
* @param {Partial<LayoutResult> & { layout?: string }} [context] pass values to use for layout calculations
|
|
571
|
+
*/
|
|
572
|
+
triggerLayout<T extends this['layout']>(
|
|
573
|
+
context?: Partial<LayoutResult> & { layout?: T }
|
|
574
|
+
) {
|
|
575
|
+
if (context && context.layout) {
|
|
576
|
+
context.prevLayout = this.layout;
|
|
577
|
+
this.layout = context.layout;
|
|
578
|
+
}
|
|
579
|
+
this._applyLayoutStrategy({ type: 'imperative', context });
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* @private
|
|
584
|
+
* @param {FabricObject} object
|
|
585
|
+
* @param {Point} diff
|
|
586
|
+
*/
|
|
587
|
+
_adjustObjectPosition(object: FabricObject, diff: Point) {
|
|
588
|
+
object.set({
|
|
589
|
+
left: object.left + diff.x,
|
|
590
|
+
top: object.top + diff.y,
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* initial layout logic:
|
|
596
|
+
* calculate bbox of objects (if necessary) and translate it according to options received from the constructor (left, top, width, height)
|
|
597
|
+
* so it is placed in the center of the bbox received from the constructor
|
|
598
|
+
*
|
|
599
|
+
* @private
|
|
600
|
+
* @param {LayoutContext} context
|
|
601
|
+
*/
|
|
602
|
+
_applyLayoutStrategy(context: LayoutContext) {
|
|
603
|
+
const isFirstLayout = context.type === 'initialization';
|
|
604
|
+
if (!isFirstLayout && !this._firstLayoutDone) {
|
|
605
|
+
// reject layout requests before initialization layout
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
const options = isFirstLayout && context.options;
|
|
609
|
+
const initialTransform = options && {
|
|
610
|
+
angle: options.angle || 0,
|
|
611
|
+
skewX: options.skewX || 0,
|
|
612
|
+
skewY: options.skewY || 0,
|
|
613
|
+
};
|
|
614
|
+
const center = this.getRelativeCenterPoint();
|
|
615
|
+
let result = this.getLayoutStrategyResult(
|
|
616
|
+
this.layout,
|
|
617
|
+
[...this._objects],
|
|
618
|
+
context
|
|
619
|
+
);
|
|
620
|
+
let diff: Point;
|
|
621
|
+
if (result) {
|
|
622
|
+
// handle positioning
|
|
623
|
+
const newCenter = new Point(result.centerX, result.centerY);
|
|
624
|
+
const vector = center
|
|
625
|
+
.subtract(newCenter)
|
|
626
|
+
.add(new Point(result.correctionX || 0, result.correctionY || 0));
|
|
627
|
+
diff = vector.transform(invertTransform(this.calcOwnMatrix()), true);
|
|
628
|
+
// set dimensions
|
|
629
|
+
this.set({ width: result.width, height: result.height });
|
|
630
|
+
// adjust objects to account for new center
|
|
631
|
+
!context.objectsRelativeToGroup &&
|
|
632
|
+
this.forEachObject((object) => {
|
|
633
|
+
object.group === this && this._adjustObjectPosition(object, diff);
|
|
634
|
+
});
|
|
635
|
+
// clip path as well
|
|
636
|
+
!isFirstLayout &&
|
|
637
|
+
this.layout !== 'clip-path' &&
|
|
638
|
+
this.clipPath &&
|
|
639
|
+
!this.clipPath.absolutePositioned &&
|
|
640
|
+
this._adjustObjectPosition(this.clipPath, diff);
|
|
641
|
+
if (!newCenter.eq(center) || initialTransform) {
|
|
642
|
+
// set position
|
|
643
|
+
this.setPositionByOrigin(newCenter, 'center', 'center');
|
|
644
|
+
initialTransform && this.set(initialTransform);
|
|
645
|
+
this.setCoords();
|
|
646
|
+
}
|
|
647
|
+
} else if (isFirstLayout) {
|
|
648
|
+
// fill `result` with initial values for the layout hook
|
|
649
|
+
result = {
|
|
650
|
+
centerX: center.x,
|
|
651
|
+
centerY: center.y,
|
|
652
|
+
width: this.width,
|
|
653
|
+
height: this.height,
|
|
654
|
+
};
|
|
655
|
+
initialTransform && this.set(initialTransform);
|
|
656
|
+
diff = new Point();
|
|
657
|
+
} else {
|
|
658
|
+
// no `result` so we return
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
// flag for next layouts
|
|
662
|
+
this._firstLayoutDone = true;
|
|
663
|
+
// fire layout hook and event (event will fire only for layouts after initialization layout)
|
|
664
|
+
this.onLayout(context, result);
|
|
665
|
+
this.fire('layout', {
|
|
666
|
+
context,
|
|
667
|
+
result,
|
|
668
|
+
diff,
|
|
669
|
+
});
|
|
670
|
+
// recursive up
|
|
671
|
+
if (this.group && this.group._applyLayoutStrategy) {
|
|
672
|
+
// append the path recursion to context
|
|
673
|
+
if (!context.path) {
|
|
674
|
+
context.path = [];
|
|
675
|
+
}
|
|
676
|
+
context.path.push(this);
|
|
677
|
+
// all parents should invalidate their layout
|
|
678
|
+
this.group._applyLayoutStrategy(context);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* Override this method to customize layout.
|
|
684
|
+
* If you need to run logic once layout completes use `onLayout`
|
|
685
|
+
* @public
|
|
686
|
+
* @param {string} layoutDirective
|
|
687
|
+
* @param {FabricObject[]} objects
|
|
688
|
+
* @param {LayoutContext} context
|
|
689
|
+
* @returns {LayoutResult | undefined}
|
|
690
|
+
*/
|
|
691
|
+
getLayoutStrategyResult<T extends this['layout']>(
|
|
692
|
+
layoutDirective: T,
|
|
693
|
+
objects: FabricObject[],
|
|
694
|
+
context: LayoutContext
|
|
695
|
+
) {
|
|
696
|
+
if (
|
|
697
|
+
layoutDirective === 'fit-content-lazy' &&
|
|
698
|
+
context.type === 'added' &&
|
|
699
|
+
objects.length > context.targets.length
|
|
700
|
+
) {
|
|
701
|
+
// calculate added objects' bbox with existing bbox
|
|
702
|
+
const addedObjects = context.targets.concat(this);
|
|
703
|
+
return this.prepareBoundingBox(layoutDirective, addedObjects, context);
|
|
704
|
+
} else if (
|
|
705
|
+
layoutDirective === 'fit-content' ||
|
|
706
|
+
layoutDirective === 'fit-content-lazy' ||
|
|
707
|
+
(layoutDirective === 'fixed' &&
|
|
708
|
+
(context.type === 'initialization' || context.type === 'imperative'))
|
|
709
|
+
) {
|
|
710
|
+
return this.prepareBoundingBox(layoutDirective, objects, context);
|
|
711
|
+
} else if (layoutDirective === 'clip-path' && this.clipPath) {
|
|
712
|
+
const clipPath = this.clipPath;
|
|
713
|
+
const clipPathSizeAfter = clipPath._getTransformedDimensions();
|
|
714
|
+
if (
|
|
715
|
+
clipPath.absolutePositioned &&
|
|
716
|
+
(context.type === 'initialization' || context.type === 'layout_change')
|
|
717
|
+
) {
|
|
718
|
+
// we want the center point to exist in group's containing plane
|
|
719
|
+
let clipPathCenter = clipPath.getCenterPoint();
|
|
720
|
+
if (this.group) {
|
|
721
|
+
// send point from canvas plane to group's containing plane
|
|
722
|
+
const inv = invertTransform(this.group.calcTransformMatrix());
|
|
723
|
+
clipPathCenter = transformPoint(clipPathCenter, inv);
|
|
724
|
+
}
|
|
725
|
+
return {
|
|
726
|
+
centerX: clipPathCenter.x,
|
|
727
|
+
centerY: clipPathCenter.y,
|
|
728
|
+
width: clipPathSizeAfter.x,
|
|
729
|
+
height: clipPathSizeAfter.y,
|
|
730
|
+
};
|
|
731
|
+
} else if (!clipPath.absolutePositioned) {
|
|
732
|
+
let center;
|
|
733
|
+
const clipPathRelativeCenter = clipPath.getRelativeCenterPoint(),
|
|
734
|
+
// we want the center point to exist in group's containing plane, so we send it upwards
|
|
735
|
+
clipPathCenter = transformPoint(
|
|
736
|
+
clipPathRelativeCenter,
|
|
737
|
+
this.calcOwnMatrix(),
|
|
738
|
+
true
|
|
739
|
+
);
|
|
740
|
+
if (
|
|
741
|
+
context.type === 'initialization' ||
|
|
742
|
+
context.type === 'layout_change'
|
|
743
|
+
) {
|
|
744
|
+
const bbox =
|
|
745
|
+
this.prepareBoundingBox(layoutDirective, objects, context) || {};
|
|
746
|
+
center = new Point(bbox.centerX || 0, bbox.centerY || 0);
|
|
747
|
+
return {
|
|
748
|
+
centerX: center.x + clipPathCenter.x,
|
|
749
|
+
centerY: center.y + clipPathCenter.y,
|
|
750
|
+
correctionX: bbox.correctionX - clipPathCenter.x,
|
|
751
|
+
correctionY: bbox.correctionY - clipPathCenter.y,
|
|
752
|
+
width: clipPath.width,
|
|
753
|
+
height: clipPath.height,
|
|
754
|
+
};
|
|
755
|
+
} else {
|
|
756
|
+
center = this.getRelativeCenterPoint();
|
|
757
|
+
return {
|
|
758
|
+
centerX: center.x + clipPathCenter.x,
|
|
759
|
+
centerY: center.y + clipPathCenter.y,
|
|
760
|
+
width: clipPathSizeAfter.x,
|
|
761
|
+
height: clipPathSizeAfter.y,
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* Override this method to customize layout.
|
|
770
|
+
* A wrapper around {@link Group#getObjectsBoundingBox}
|
|
771
|
+
* @public
|
|
772
|
+
* @param {string} layoutDirective
|
|
773
|
+
* @param {FabricObject[]} objects
|
|
774
|
+
* @param {LayoutContext} context
|
|
775
|
+
* @returns {LayoutResult | undefined}
|
|
776
|
+
*/
|
|
777
|
+
prepareBoundingBox<T extends this['layout']>(
|
|
778
|
+
layoutDirective: T,
|
|
779
|
+
objects: FabricObject[],
|
|
780
|
+
context: LayoutContext
|
|
781
|
+
) {
|
|
782
|
+
if (context.type === 'initialization') {
|
|
783
|
+
return this.prepareInitialBoundingBox(layoutDirective, objects, context);
|
|
784
|
+
} else if (context.type === 'imperative' && context.context) {
|
|
785
|
+
return {
|
|
786
|
+
...(this.getObjectsBoundingBox(objects) || {}),
|
|
787
|
+
...context.context,
|
|
788
|
+
};
|
|
789
|
+
} else {
|
|
790
|
+
return this.getObjectsBoundingBox(objects);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* Calculates center taking into account originX, originY while not being sure that width/height are initialized
|
|
796
|
+
* @public
|
|
797
|
+
* @param {string} layoutDirective
|
|
798
|
+
* @param {FabricObject[]} objects
|
|
799
|
+
* @param {LayoutContext} context
|
|
800
|
+
* @returns {LayoutResult | undefined}
|
|
801
|
+
*/
|
|
802
|
+
prepareInitialBoundingBox<T extends this['layout']>(
|
|
803
|
+
layoutDirective: T,
|
|
804
|
+
objects: FabricObject[],
|
|
805
|
+
context: LayoutContext
|
|
806
|
+
) {
|
|
807
|
+
const options = context.options || {},
|
|
808
|
+
hasX = typeof options.left === 'number',
|
|
809
|
+
hasY = typeof options.top === 'number',
|
|
810
|
+
hasWidth = typeof options.width === 'number',
|
|
811
|
+
hasHeight = typeof options.height === 'number';
|
|
812
|
+
|
|
813
|
+
// performance enhancement
|
|
814
|
+
// skip layout calculation if bbox is defined
|
|
815
|
+
if (
|
|
816
|
+
(hasX &&
|
|
817
|
+
hasY &&
|
|
818
|
+
hasWidth &&
|
|
819
|
+
hasHeight &&
|
|
820
|
+
context.objectsRelativeToGroup) ||
|
|
821
|
+
objects.length === 0
|
|
822
|
+
) {
|
|
823
|
+
// return nothing to skip layout
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
const bbox = this.getObjectsBoundingBox(objects) || ({} as LayoutResult);
|
|
828
|
+
const { centerX = 0, centerY = 0, width: w = 0, height: h = 0 } = bbox;
|
|
829
|
+
const width = hasWidth ? this.width : w,
|
|
830
|
+
height = hasHeight ? this.height : h,
|
|
831
|
+
calculatedCenter = new Point(centerX, centerY),
|
|
832
|
+
origin = new Point(
|
|
833
|
+
resolveOrigin(this.originX),
|
|
834
|
+
resolveOrigin(this.originY)
|
|
835
|
+
),
|
|
836
|
+
size = new Point(width, height),
|
|
837
|
+
strokeWidthVector = this._getTransformedDimensions({
|
|
838
|
+
width: 0,
|
|
839
|
+
height: 0,
|
|
840
|
+
}),
|
|
841
|
+
sizeAfter = this._getTransformedDimensions({
|
|
842
|
+
width: width,
|
|
843
|
+
height: height,
|
|
844
|
+
strokeWidth: 0,
|
|
845
|
+
}),
|
|
846
|
+
bboxSizeAfter = this._getTransformedDimensions({
|
|
847
|
+
width: bbox.width,
|
|
848
|
+
height: bbox.height,
|
|
849
|
+
strokeWidth: 0,
|
|
850
|
+
}),
|
|
851
|
+
rotationCorrection = new Point(0, 0);
|
|
852
|
+
|
|
853
|
+
// calculate center and correction
|
|
854
|
+
const originT = origin.scalarAdd(0.5);
|
|
855
|
+
const originCorrection = sizeAfter.multiply(originT);
|
|
856
|
+
const centerCorrection = new Point(
|
|
857
|
+
hasWidth ? bboxSizeAfter.x / 2 : originCorrection.x,
|
|
858
|
+
hasHeight ? bboxSizeAfter.y / 2 : originCorrection.y
|
|
859
|
+
);
|
|
860
|
+
const center = new Point(
|
|
861
|
+
hasX
|
|
862
|
+
? this.left - (sizeAfter.x + strokeWidthVector.x) * origin.x
|
|
863
|
+
: calculatedCenter.x - centerCorrection.x,
|
|
864
|
+
hasY
|
|
865
|
+
? this.top - (sizeAfter.y + strokeWidthVector.y) * origin.y
|
|
866
|
+
: calculatedCenter.y - centerCorrection.y
|
|
867
|
+
);
|
|
868
|
+
const offsetCorrection = new Point(
|
|
869
|
+
hasX
|
|
870
|
+
? center.x - calculatedCenter.x + bboxSizeAfter.x * (hasWidth ? 0.5 : 0)
|
|
871
|
+
: -(hasWidth
|
|
872
|
+
? (sizeAfter.x - strokeWidthVector.x) * 0.5
|
|
873
|
+
: sizeAfter.x * originT.x),
|
|
874
|
+
hasY
|
|
875
|
+
? center.y -
|
|
876
|
+
calculatedCenter.y +
|
|
877
|
+
bboxSizeAfter.y * (hasHeight ? 0.5 : 0)
|
|
878
|
+
: -(hasHeight
|
|
879
|
+
? (sizeAfter.y - strokeWidthVector.y) * 0.5
|
|
880
|
+
: sizeAfter.y * originT.y)
|
|
881
|
+
).add(rotationCorrection);
|
|
882
|
+
const correction = new Point(
|
|
883
|
+
hasWidth ? -sizeAfter.x / 2 : 0,
|
|
884
|
+
hasHeight ? -sizeAfter.y / 2 : 0
|
|
885
|
+
).add(offsetCorrection);
|
|
886
|
+
|
|
887
|
+
return {
|
|
888
|
+
centerX: center.x,
|
|
889
|
+
centerY: center.y,
|
|
890
|
+
correctionX: correction.x,
|
|
891
|
+
correctionY: correction.y,
|
|
892
|
+
width: size.x,
|
|
893
|
+
height: size.y,
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
* Calculate the bbox of objects relative to instance's containing plane
|
|
899
|
+
* @public
|
|
900
|
+
* @param {FabricObject[]} objects
|
|
901
|
+
* @returns {LayoutResult | null} bounding box
|
|
902
|
+
*/
|
|
903
|
+
getObjectsBoundingBox(
|
|
904
|
+
objects: FabricObject[],
|
|
905
|
+
ignoreOffset?: boolean
|
|
906
|
+
): LayoutResult | null {
|
|
907
|
+
if (objects.length === 0) {
|
|
908
|
+
return null;
|
|
909
|
+
}
|
|
910
|
+
const objectBounds: Point[] = [];
|
|
911
|
+
objects.forEach((object) => {
|
|
912
|
+
const objCenter = object.getRelativeCenterPoint();
|
|
913
|
+
let sizeVector = object._getTransformedDimensions().scalarDivide(2);
|
|
914
|
+
if (object.angle) {
|
|
915
|
+
const rad = degreesToRadians(object.angle),
|
|
916
|
+
sine = Math.abs(sin(rad)),
|
|
917
|
+
cosine = Math.abs(cos(rad)),
|
|
918
|
+
rx = sizeVector.x * cosine + sizeVector.y * sine,
|
|
919
|
+
ry = sizeVector.x * sine + sizeVector.y * cosine;
|
|
920
|
+
sizeVector = new Point(rx, ry);
|
|
921
|
+
}
|
|
922
|
+
objectBounds.push(
|
|
923
|
+
objCenter.subtract(sizeVector),
|
|
924
|
+
objCenter.add(sizeVector)
|
|
925
|
+
);
|
|
926
|
+
});
|
|
927
|
+
const { left, top, width, height } =
|
|
928
|
+
makeBoundingBoxFromPoints(objectBounds);
|
|
929
|
+
|
|
930
|
+
const size = new Point(width, height),
|
|
931
|
+
relativeCenter = (!ignoreOffset ? new Point(left, top) : new Point()).add(
|
|
932
|
+
size.scalarDivide(2)
|
|
933
|
+
),
|
|
934
|
+
// we send `relativeCenter` up to group's containing plane
|
|
935
|
+
center = relativeCenter.transform(this.calcOwnMatrix());
|
|
936
|
+
|
|
937
|
+
return {
|
|
938
|
+
centerX: center.x,
|
|
939
|
+
centerY: center.y,
|
|
940
|
+
width: size.x,
|
|
941
|
+
height: size.y,
|
|
942
|
+
};
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
/**
|
|
946
|
+
* Hook that is called once layout has completed.
|
|
947
|
+
* Provided for layout customization, override if necessary.
|
|
948
|
+
* Complements `getLayoutStrategyResult`, which is called at the beginning of layout.
|
|
949
|
+
* @public
|
|
950
|
+
* @param {LayoutContext} context layout context
|
|
951
|
+
* @param {LayoutResult} result layout result
|
|
952
|
+
*/
|
|
953
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
|
|
954
|
+
onLayout(context: LayoutContext, result: LayoutResult) {}
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
*
|
|
958
|
+
* @private
|
|
959
|
+
* @param {'toObject'|'toDatalessObject'} [method]
|
|
960
|
+
* @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output
|
|
961
|
+
* @returns {FabricObject[]} serialized objects
|
|
962
|
+
*/
|
|
963
|
+
__serializeObjects(
|
|
964
|
+
method: 'toObject' | 'toDatalessObject',
|
|
965
|
+
propertiesToInclude?: string[]
|
|
966
|
+
) {
|
|
967
|
+
const _includeDefaultValues = this.includeDefaultValues;
|
|
968
|
+
return this._objects
|
|
969
|
+
.filter(function (obj) {
|
|
970
|
+
return !obj.excludeFromExport;
|
|
971
|
+
})
|
|
972
|
+
.map(function (obj) {
|
|
973
|
+
const originalDefaults = obj.includeDefaultValues;
|
|
974
|
+
obj.includeDefaultValues = _includeDefaultValues;
|
|
975
|
+
const data = obj[method || 'toObject'](propertiesToInclude);
|
|
976
|
+
obj.includeDefaultValues = originalDefaults;
|
|
977
|
+
//delete data.version;
|
|
978
|
+
return data;
|
|
979
|
+
});
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
/**
|
|
983
|
+
* Returns object representation of an instance
|
|
984
|
+
* @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output
|
|
985
|
+
* @return {Object} object representation of an instance
|
|
986
|
+
*/
|
|
987
|
+
toObject<
|
|
988
|
+
T extends Omit<
|
|
989
|
+
GroupProps & TClassProperties<this>,
|
|
990
|
+
keyof SerializedGroupProps
|
|
991
|
+
>,
|
|
992
|
+
K extends keyof T = never
|
|
993
|
+
>(propertiesToInclude: K[] = []): Pick<T, K> & SerializedGroupProps {
|
|
994
|
+
return {
|
|
995
|
+
...super.toObject([
|
|
996
|
+
'layout',
|
|
997
|
+
'subTargetCheck',
|
|
998
|
+
'interactive',
|
|
999
|
+
...propertiesToInclude,
|
|
1000
|
+
]),
|
|
1001
|
+
objects: this.__serializeObjects('toObject', propertiesToInclude),
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
toString() {
|
|
1006
|
+
return `#<Group: (${this.complexity()})>`;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
dispose() {
|
|
1010
|
+
this._activeObjects = [];
|
|
1011
|
+
this.forEachObject((object) => {
|
|
1012
|
+
this._watchObject(false, object);
|
|
1013
|
+
object.dispose();
|
|
1014
|
+
});
|
|
1015
|
+
super.dispose();
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
/**
|
|
1019
|
+
* @private
|
|
1020
|
+
*/
|
|
1021
|
+
_createSVGBgRect(reviver?: TSVGReviver) {
|
|
1022
|
+
if (!this.backgroundColor) {
|
|
1023
|
+
return '';
|
|
1024
|
+
}
|
|
1025
|
+
const fillStroke = Rect.prototype._toSVG.call(this);
|
|
1026
|
+
const commons = fillStroke.indexOf('COMMON_PARTS');
|
|
1027
|
+
fillStroke[commons] = 'for="group" ';
|
|
1028
|
+
const markup = fillStroke.join('');
|
|
1029
|
+
return reviver ? reviver(markup) : markup;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
/**
|
|
1033
|
+
* Returns svg representation of an instance
|
|
1034
|
+
* @param {TSVGReviver} [reviver] Method for further parsing of svg representation.
|
|
1035
|
+
* @return {String} svg representation of an instance
|
|
1036
|
+
*/
|
|
1037
|
+
_toSVG(reviver?: TSVGReviver) {
|
|
1038
|
+
const svgString = ['<g ', 'COMMON_PARTS', ' >\n'];
|
|
1039
|
+
const bg = this._createSVGBgRect(reviver);
|
|
1040
|
+
bg && svgString.push('\t\t', bg);
|
|
1041
|
+
for (let i = 0; i < this._objects.length; i++) {
|
|
1042
|
+
svgString.push('\t\t', this._objects[i].toSVG(reviver));
|
|
1043
|
+
}
|
|
1044
|
+
svgString.push('</g>\n');
|
|
1045
|
+
return svgString;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
/**
|
|
1049
|
+
* Returns styles-string for svg-export, specific version for group
|
|
1050
|
+
* @return {String}
|
|
1051
|
+
*/
|
|
1052
|
+
getSvgStyles() {
|
|
1053
|
+
const opacity =
|
|
1054
|
+
typeof this.opacity !== 'undefined' && this.opacity !== 1
|
|
1055
|
+
? `opacity: ${this.opacity};`
|
|
1056
|
+
: '',
|
|
1057
|
+
visibility = this.visible ? '' : ' visibility: hidden;';
|
|
1058
|
+
return [opacity, this.getSvgFilter(), visibility].join('');
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
/**
|
|
1062
|
+
* Returns svg clipPath representation of an instance
|
|
1063
|
+
* @param {Function} [reviver] Method for further parsing of svg representation.
|
|
1064
|
+
* @return {String} svg representation of an instance
|
|
1065
|
+
*/
|
|
1066
|
+
toClipPathSVG(reviver?: TSVGReviver) {
|
|
1067
|
+
const svgString = [];
|
|
1068
|
+
const bg = this._createSVGBgRect(reviver);
|
|
1069
|
+
bg && svgString.push('\t', bg);
|
|
1070
|
+
for (let i = 0; i < this._objects.length; i++) {
|
|
1071
|
+
svgString.push('\t', this._objects[i].toClipPathSVG(reviver));
|
|
1072
|
+
}
|
|
1073
|
+
return this._createBaseClipPathSVGMarkup(svgString, {
|
|
1074
|
+
reviver,
|
|
1075
|
+
});
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
/**
|
|
1079
|
+
* @todo support loading from svg
|
|
1080
|
+
* @private
|
|
1081
|
+
* @static
|
|
1082
|
+
* @memberOf Group
|
|
1083
|
+
* @param {Object} object Object to create a group from
|
|
1084
|
+
* @returns {Promise<Group>}
|
|
1085
|
+
*/
|
|
1086
|
+
static fromObject<T extends TProps<SerializedGroupProps>>({
|
|
1087
|
+
objects = [],
|
|
1088
|
+
...options
|
|
1089
|
+
}: T) {
|
|
1090
|
+
return Promise.all([
|
|
1091
|
+
enlivenObjects(objects),
|
|
1092
|
+
enlivenObjectEnlivables(options),
|
|
1093
|
+
]).then(
|
|
1094
|
+
([objects, hydratedOptions]) =>
|
|
1095
|
+
new this(objects, { ...options, ...hydratedOptions }, true)
|
|
1096
|
+
);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
classRegistry.setClass(Group);
|