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
|
@@ -1,1881 +0,0 @@
|
|
|
1
|
-
(function () {
|
|
2
|
-
|
|
3
|
-
'use strict';
|
|
4
|
-
|
|
5
|
-
if (fabric.StaticCanvas) {
|
|
6
|
-
fabric.warn('fabric.StaticCanvas is already defined.');
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
// aliases for faster resolution
|
|
11
|
-
var extend = fabric.util.object.extend,
|
|
12
|
-
getElementOffset = fabric.util.getElementOffset,
|
|
13
|
-
removeFromArray = fabric.util.removeFromArray,
|
|
14
|
-
toFixed = fabric.util.toFixed,
|
|
15
|
-
transformPoint = fabric.util.transformPoint,
|
|
16
|
-
invertTransform = fabric.util.invertTransform,
|
|
17
|
-
getNodeCanvas = fabric.util.getNodeCanvas,
|
|
18
|
-
createCanvasElement = fabric.util.createCanvasElement,
|
|
19
|
-
|
|
20
|
-
CANVAS_INIT_ERROR = new Error('Could not initialize `canvas` element');
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Static canvas class
|
|
24
|
-
* @class fabric.StaticCanvas
|
|
25
|
-
* @mixes fabric.Collection
|
|
26
|
-
* @mixes fabric.Observable
|
|
27
|
-
* @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo}
|
|
28
|
-
* @see {@link fabric.StaticCanvas#initialize} for constructor definition
|
|
29
|
-
* @fires before:render
|
|
30
|
-
* @fires after:render
|
|
31
|
-
* @fires canvas:cleared
|
|
32
|
-
* @fires object:added
|
|
33
|
-
* @fires object:removed
|
|
34
|
-
*/
|
|
35
|
-
fabric.StaticCanvas = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.StaticCanvas.prototype */ {
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Constructor
|
|
39
|
-
* @param {HTMLElement | String} el <canvas> element to initialize instance on
|
|
40
|
-
* @param {Object} [options] Options object
|
|
41
|
-
* @return {Object} thisArg
|
|
42
|
-
*/
|
|
43
|
-
initialize: function(el, options) {
|
|
44
|
-
options || (options = { });
|
|
45
|
-
this.renderAndResetBound = this.renderAndReset.bind(this);
|
|
46
|
-
this.requestRenderAllBound = this.requestRenderAll.bind(this);
|
|
47
|
-
this._initStatic(el, options);
|
|
48
|
-
},
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Background color of canvas instance.
|
|
52
|
-
* Should be set via {@link fabric.StaticCanvas#setBackgroundColor}.
|
|
53
|
-
* @type {(String|fabric.Pattern)}
|
|
54
|
-
* @default
|
|
55
|
-
*/
|
|
56
|
-
backgroundColor: '',
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Background image of canvas instance.
|
|
60
|
-
* since 2.4.0 image caching is active, please when putting an image as background, add to the
|
|
61
|
-
* canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom
|
|
62
|
-
* vale. As an alternative you can disable image objectCaching
|
|
63
|
-
* @type fabric.Image
|
|
64
|
-
* @default
|
|
65
|
-
*/
|
|
66
|
-
backgroundImage: null,
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Overlay color of canvas instance.
|
|
70
|
-
* Should be set via {@link fabric.StaticCanvas#setOverlayColor}
|
|
71
|
-
* @since 1.3.9
|
|
72
|
-
* @type {(String|fabric.Pattern)}
|
|
73
|
-
* @default
|
|
74
|
-
*/
|
|
75
|
-
overlayColor: '',
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Overlay image of canvas instance.
|
|
79
|
-
* since 2.4.0 image caching is active, please when putting an image as overlay, add to the
|
|
80
|
-
* canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom
|
|
81
|
-
* vale. As an alternative you can disable image objectCaching
|
|
82
|
-
* @type fabric.Image
|
|
83
|
-
* @default
|
|
84
|
-
*/
|
|
85
|
-
overlayImage: null,
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Indicates whether toObject/toDatalessObject should include default values
|
|
89
|
-
* if set to false, takes precedence over the object value.
|
|
90
|
-
* @type Boolean
|
|
91
|
-
* @default
|
|
92
|
-
*/
|
|
93
|
-
includeDefaultValues: true,
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Indicates whether objects' state should be saved
|
|
97
|
-
* @type Boolean
|
|
98
|
-
* @default
|
|
99
|
-
*/
|
|
100
|
-
stateful: false,
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Indicates whether {@link fabric.Collection.add}, {@link fabric.Collection.insertAt} and {@link fabric.Collection.remove},
|
|
104
|
-
* {@link fabric.StaticCanvas.moveTo}, {@link fabric.StaticCanvas.clear} and many more, should also re-render canvas.
|
|
105
|
-
* Disabling this option will not give a performance boost when adding/removing a lot of objects to/from canvas at once
|
|
106
|
-
* since the renders are quequed and executed one per frame.
|
|
107
|
-
* Disabling is suggested anyway and managing the renders of the app manually is not a big effort ( canvas.requestRenderAll() )
|
|
108
|
-
* Left default to true to do not break documentation and old app, fiddles.
|
|
109
|
-
* @type Boolean
|
|
110
|
-
* @default
|
|
111
|
-
*/
|
|
112
|
-
renderOnAddRemove: true,
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Indicates whether object controls (borders/controls) are rendered above overlay image
|
|
116
|
-
* @type Boolean
|
|
117
|
-
* @default
|
|
118
|
-
*/
|
|
119
|
-
controlsAboveOverlay: false,
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Indicates whether the browser can be scrolled when using a touchscreen and dragging on the canvas
|
|
123
|
-
* @type Boolean
|
|
124
|
-
* @default
|
|
125
|
-
*/
|
|
126
|
-
allowTouchScrolling: false,
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Indicates whether this canvas will use image smoothing, this is on by default in browsers
|
|
130
|
-
* @type Boolean
|
|
131
|
-
* @default
|
|
132
|
-
*/
|
|
133
|
-
imageSmoothingEnabled: true,
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* The transformation (a Canvas 2D API transform matrix) which focuses the viewport
|
|
137
|
-
* @type Array
|
|
138
|
-
* @example <caption>Default transform</caption>
|
|
139
|
-
* canvas.viewportTransform = [1, 0, 0, 1, 0, 0];
|
|
140
|
-
* @example <caption>Scale by 70% and translate toward bottom-right by 50, without skewing</caption>
|
|
141
|
-
* canvas.viewportTransform = [0.7, 0, 0, 0.7, 50, 50];
|
|
142
|
-
* @default
|
|
143
|
-
*/
|
|
144
|
-
viewportTransform: fabric.iMatrix.concat(),
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* if set to false background image is not affected by viewport transform
|
|
148
|
-
* @since 1.6.3
|
|
149
|
-
* @type Boolean
|
|
150
|
-
* @default
|
|
151
|
-
*/
|
|
152
|
-
backgroundVpt: true,
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* if set to false overlya image is not affected by viewport transform
|
|
156
|
-
* @since 1.6.3
|
|
157
|
-
* @type Boolean
|
|
158
|
-
* @default
|
|
159
|
-
*/
|
|
160
|
-
overlayVpt: true,
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* When true, canvas is scaled by devicePixelRatio for better rendering on retina screens
|
|
164
|
-
* @type Boolean
|
|
165
|
-
* @default
|
|
166
|
-
*/
|
|
167
|
-
enableRetinaScaling: true,
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Describe canvas element extension over design
|
|
171
|
-
* properties are tl,tr,bl,br.
|
|
172
|
-
* if canvas is not zoomed/panned those points are the four corner of canvas
|
|
173
|
-
* if canvas is viewportTransformed you those points indicate the extension
|
|
174
|
-
* of canvas element in plain untrasformed coordinates
|
|
175
|
-
* The coordinates get updated with @method calcViewportBoundaries.
|
|
176
|
-
* @memberOf fabric.StaticCanvas.prototype
|
|
177
|
-
*/
|
|
178
|
-
vptCoords: { },
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Based on vptCoords and object.aCoords, skip rendering of objects that
|
|
182
|
-
* are not included in current viewport.
|
|
183
|
-
* May greatly help in applications with crowded canvas and use of zoom/pan
|
|
184
|
-
* If One of the corner of the bounding box of the object is on the canvas
|
|
185
|
-
* the objects get rendered.
|
|
186
|
-
* @memberOf fabric.StaticCanvas.prototype
|
|
187
|
-
* @type Boolean
|
|
188
|
-
* @default
|
|
189
|
-
*/
|
|
190
|
-
skipOffscreen: true,
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* a fabricObject that, without stroke define a clipping area with their shape. filled in black
|
|
194
|
-
* the clipPath object gets used when the canvas has rendered, and the context is placed in the
|
|
195
|
-
* top left corner of the canvas.
|
|
196
|
-
* clipPath will clip away controls, if you do not want this to happen use controlsAboveOverlay = true
|
|
197
|
-
* @type fabric.Object
|
|
198
|
-
*/
|
|
199
|
-
clipPath: undefined,
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* @private
|
|
203
|
-
* @param {HTMLElement | String} el <canvas> element to initialize instance on
|
|
204
|
-
* @param {Object} [options] Options object
|
|
205
|
-
*/
|
|
206
|
-
_initStatic: function(el, options) {
|
|
207
|
-
var cb = this.requestRenderAllBound;
|
|
208
|
-
this._objects = [];
|
|
209
|
-
this._createLowerCanvas(el);
|
|
210
|
-
this._initOptions(options);
|
|
211
|
-
// only initialize retina scaling once
|
|
212
|
-
if (!this.interactive) {
|
|
213
|
-
this._initRetinaScaling();
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
if (options.overlayImage) {
|
|
217
|
-
this.setOverlayImage(options.overlayImage, cb);
|
|
218
|
-
}
|
|
219
|
-
if (options.backgroundImage) {
|
|
220
|
-
this.setBackgroundImage(options.backgroundImage, cb);
|
|
221
|
-
}
|
|
222
|
-
if (options.backgroundColor) {
|
|
223
|
-
this.setBackgroundColor(options.backgroundColor, cb);
|
|
224
|
-
}
|
|
225
|
-
if (options.overlayColor) {
|
|
226
|
-
this.setOverlayColor(options.overlayColor, cb);
|
|
227
|
-
}
|
|
228
|
-
this.calcOffset();
|
|
229
|
-
},
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* @private
|
|
233
|
-
*/
|
|
234
|
-
_isRetinaScaling: function() {
|
|
235
|
-
return (fabric.devicePixelRatio > 1 && this.enableRetinaScaling);
|
|
236
|
-
},
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* @private
|
|
240
|
-
* @return {Number} retinaScaling if applied, otherwise 1;
|
|
241
|
-
*/
|
|
242
|
-
getRetinaScaling: function() {
|
|
243
|
-
return this._isRetinaScaling() ? Math.max(1, fabric.devicePixelRatio) : 1;
|
|
244
|
-
},
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* @private
|
|
248
|
-
*/
|
|
249
|
-
_initRetinaScaling: function() {
|
|
250
|
-
if (!this._isRetinaScaling()) {
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
var scaleRatio = fabric.devicePixelRatio;
|
|
254
|
-
this.__initRetinaScaling(scaleRatio, this.lowerCanvasEl, this.contextContainer);
|
|
255
|
-
if (this.upperCanvasEl) {
|
|
256
|
-
this.__initRetinaScaling(scaleRatio, this.upperCanvasEl, this.contextTop);
|
|
257
|
-
}
|
|
258
|
-
},
|
|
259
|
-
|
|
260
|
-
__initRetinaScaling: function(scaleRatio, canvas, context) {
|
|
261
|
-
canvas.setAttribute('width', this.width * scaleRatio);
|
|
262
|
-
canvas.setAttribute('height', this.height * scaleRatio);
|
|
263
|
-
context.scale(scaleRatio, scaleRatio);
|
|
264
|
-
},
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Calculates canvas element offset relative to the document
|
|
269
|
-
* This method is also attached as "resize" event handler of window
|
|
270
|
-
* @return {fabric.Canvas} instance
|
|
271
|
-
* @chainable
|
|
272
|
-
*/
|
|
273
|
-
calcOffset: function () {
|
|
274
|
-
this._offset = getElementOffset(this.lowerCanvasEl);
|
|
275
|
-
return this;
|
|
276
|
-
},
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* Sets {@link fabric.StaticCanvas#overlayImage|overlay image} for this canvas
|
|
280
|
-
* @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set overlay to
|
|
281
|
-
* @param {Function} callback callback to invoke when image is loaded and set as an overlay
|
|
282
|
-
* @param {Object} [options] Optional options to set for the {@link fabric.Image|overlay image}.
|
|
283
|
-
* @return {fabric.Canvas} thisArg
|
|
284
|
-
* @chainable
|
|
285
|
-
* @see {@link http://jsfiddle.net/fabricjs/MnzHT/|jsFiddle demo}
|
|
286
|
-
* @example <caption>Normal overlayImage with left/top = 0</caption>
|
|
287
|
-
* canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {
|
|
288
|
-
* // Needed to position overlayImage at 0/0
|
|
289
|
-
* originX: 'left',
|
|
290
|
-
* originY: 'top'
|
|
291
|
-
* });
|
|
292
|
-
* @example <caption>overlayImage with different properties</caption>
|
|
293
|
-
* canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {
|
|
294
|
-
* opacity: 0.5,
|
|
295
|
-
* angle: 45,
|
|
296
|
-
* left: 400,
|
|
297
|
-
* top: 400,
|
|
298
|
-
* originX: 'left',
|
|
299
|
-
* originY: 'top'
|
|
300
|
-
* });
|
|
301
|
-
* @example <caption>Stretched overlayImage #1 - width/height correspond to canvas width/height</caption>
|
|
302
|
-
* fabric.Image.fromURL('http://fabricjs.com/assets/jail_cell_bars.png', function(img, isError) {
|
|
303
|
-
* img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'});
|
|
304
|
-
* canvas.setOverlayImage(img, canvas.renderAll.bind(canvas));
|
|
305
|
-
* });
|
|
306
|
-
* @example <caption>Stretched overlayImage #2 - width/height correspond to canvas width/height</caption>
|
|
307
|
-
* canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {
|
|
308
|
-
* width: canvas.width,
|
|
309
|
-
* height: canvas.height,
|
|
310
|
-
* // Needed to position overlayImage at 0/0
|
|
311
|
-
* originX: 'left',
|
|
312
|
-
* originY: 'top'
|
|
313
|
-
* });
|
|
314
|
-
* @example <caption>overlayImage loaded from cross-origin</caption>
|
|
315
|
-
* canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {
|
|
316
|
-
* opacity: 0.5,
|
|
317
|
-
* angle: 45,
|
|
318
|
-
* left: 400,
|
|
319
|
-
* top: 400,
|
|
320
|
-
* originX: 'left',
|
|
321
|
-
* originY: 'top',
|
|
322
|
-
* crossOrigin: 'anonymous'
|
|
323
|
-
* });
|
|
324
|
-
*/
|
|
325
|
-
setOverlayImage: function (image, callback, options) {
|
|
326
|
-
return this.__setBgOverlayImage('overlayImage', image, callback, options);
|
|
327
|
-
},
|
|
328
|
-
|
|
329
|
-
/**
|
|
330
|
-
* Sets {@link fabric.StaticCanvas#backgroundImage|background image} for this canvas
|
|
331
|
-
* @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set background to
|
|
332
|
-
* @param {Function} callback Callback to invoke when image is loaded and set as background
|
|
333
|
-
* @param {Object} [options] Optional options to set for the {@link fabric.Image|background image}.
|
|
334
|
-
* @return {fabric.Canvas} thisArg
|
|
335
|
-
* @chainable
|
|
336
|
-
* @see {@link http://jsfiddle.net/djnr8o7a/28/|jsFiddle demo}
|
|
337
|
-
* @example <caption>Normal backgroundImage with left/top = 0</caption>
|
|
338
|
-
* canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {
|
|
339
|
-
* // Needed to position backgroundImage at 0/0
|
|
340
|
-
* originX: 'left',
|
|
341
|
-
* originY: 'top'
|
|
342
|
-
* });
|
|
343
|
-
* @example <caption>backgroundImage with different properties</caption>
|
|
344
|
-
* canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {
|
|
345
|
-
* opacity: 0.5,
|
|
346
|
-
* angle: 45,
|
|
347
|
-
* left: 400,
|
|
348
|
-
* top: 400,
|
|
349
|
-
* originX: 'left',
|
|
350
|
-
* originY: 'top'
|
|
351
|
-
* });
|
|
352
|
-
* @example <caption>Stretched backgroundImage #1 - width/height correspond to canvas width/height</caption>
|
|
353
|
-
* fabric.Image.fromURL('http://fabricjs.com/assets/honey_im_subtle.png', function(img, isError) {
|
|
354
|
-
* img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'});
|
|
355
|
-
* canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas));
|
|
356
|
-
* });
|
|
357
|
-
* @example <caption>Stretched backgroundImage #2 - width/height correspond to canvas width/height</caption>
|
|
358
|
-
* canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {
|
|
359
|
-
* width: canvas.width,
|
|
360
|
-
* height: canvas.height,
|
|
361
|
-
* // Needed to position backgroundImage at 0/0
|
|
362
|
-
* originX: 'left',
|
|
363
|
-
* originY: 'top'
|
|
364
|
-
* });
|
|
365
|
-
* @example <caption>backgroundImage loaded from cross-origin</caption>
|
|
366
|
-
* canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {
|
|
367
|
-
* opacity: 0.5,
|
|
368
|
-
* angle: 45,
|
|
369
|
-
* left: 400,
|
|
370
|
-
* top: 400,
|
|
371
|
-
* originX: 'left',
|
|
372
|
-
* originY: 'top',
|
|
373
|
-
* crossOrigin: 'anonymous'
|
|
374
|
-
* });
|
|
375
|
-
*/
|
|
376
|
-
// TODO: fix stretched examples
|
|
377
|
-
setBackgroundImage: function (image, callback, options) {
|
|
378
|
-
return this.__setBgOverlayImage('backgroundImage', image, callback, options);
|
|
379
|
-
},
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
* Sets {@link fabric.StaticCanvas#overlayColor|foreground color} for this canvas
|
|
383
|
-
* @param {(String|fabric.Pattern)} overlayColor Color or pattern to set foreground color to
|
|
384
|
-
* @param {Function} callback Callback to invoke when foreground color is set
|
|
385
|
-
* @return {fabric.Canvas} thisArg
|
|
386
|
-
* @chainable
|
|
387
|
-
* @see {@link http://jsfiddle.net/fabricjs/pB55h/|jsFiddle demo}
|
|
388
|
-
* @example <caption>Normal overlayColor - color value</caption>
|
|
389
|
-
* canvas.setOverlayColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas));
|
|
390
|
-
* @example <caption>fabric.Pattern used as overlayColor</caption>
|
|
391
|
-
* canvas.setOverlayColor({
|
|
392
|
-
* source: 'http://fabricjs.com/assets/escheresque_ste.png'
|
|
393
|
-
* }, canvas.renderAll.bind(canvas));
|
|
394
|
-
* @example <caption>fabric.Pattern used as overlayColor with repeat and offset</caption>
|
|
395
|
-
* canvas.setOverlayColor({
|
|
396
|
-
* source: 'http://fabricjs.com/assets/escheresque_ste.png',
|
|
397
|
-
* repeat: 'repeat',
|
|
398
|
-
* offsetX: 200,
|
|
399
|
-
* offsetY: 100
|
|
400
|
-
* }, canvas.renderAll.bind(canvas));
|
|
401
|
-
*/
|
|
402
|
-
setOverlayColor: function(overlayColor, callback) {
|
|
403
|
-
return this.__setBgOverlayColor('overlayColor', overlayColor, callback);
|
|
404
|
-
},
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* Sets {@link fabric.StaticCanvas#backgroundColor|background color} for this canvas
|
|
408
|
-
* @param {(String|fabric.Pattern)} backgroundColor Color or pattern to set background color to
|
|
409
|
-
* @param {Function} callback Callback to invoke when background color is set
|
|
410
|
-
* @return {fabric.Canvas} thisArg
|
|
411
|
-
* @chainable
|
|
412
|
-
* @see {@link http://jsfiddle.net/fabricjs/hXzvk/|jsFiddle demo}
|
|
413
|
-
* @example <caption>Normal backgroundColor - color value</caption>
|
|
414
|
-
* canvas.setBackgroundColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas));
|
|
415
|
-
* @example <caption>fabric.Pattern used as backgroundColor</caption>
|
|
416
|
-
* canvas.setBackgroundColor({
|
|
417
|
-
* source: 'http://fabricjs.com/assets/escheresque_ste.png'
|
|
418
|
-
* }, canvas.renderAll.bind(canvas));
|
|
419
|
-
* @example <caption>fabric.Pattern used as backgroundColor with repeat and offset</caption>
|
|
420
|
-
* canvas.setBackgroundColor({
|
|
421
|
-
* source: 'http://fabricjs.com/assets/escheresque_ste.png',
|
|
422
|
-
* repeat: 'repeat',
|
|
423
|
-
* offsetX: 200,
|
|
424
|
-
* offsetY: 100
|
|
425
|
-
* }, canvas.renderAll.bind(canvas));
|
|
426
|
-
*/
|
|
427
|
-
setBackgroundColor: function(backgroundColor, callback) {
|
|
428
|
-
return this.__setBgOverlayColor('backgroundColor', backgroundColor, callback);
|
|
429
|
-
},
|
|
430
|
-
|
|
431
|
-
/**
|
|
432
|
-
* @private
|
|
433
|
-
* @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundImage|backgroundImage}
|
|
434
|
-
* or {@link fabric.StaticCanvas#overlayImage|overlayImage})
|
|
435
|
-
* @param {(fabric.Image|String|null)} image fabric.Image instance, URL of an image or null to set background or overlay to
|
|
436
|
-
* @param {Function} callback Callback to invoke when image is loaded and set as background or overlay. The first argument is the created image, the second argument is a flag indicating whether an error occurred or not.
|
|
437
|
-
* @param {Object} [options] Optional options to set for the {@link fabric.Image|image}.
|
|
438
|
-
*/
|
|
439
|
-
__setBgOverlayImage: function(property, image, callback, options) {
|
|
440
|
-
if (typeof image === 'string') {
|
|
441
|
-
fabric.util.loadImage(image, function(img, isError) {
|
|
442
|
-
if (img) {
|
|
443
|
-
var instance = new fabric.Image(img, options);
|
|
444
|
-
this[property] = instance;
|
|
445
|
-
instance.canvas = this;
|
|
446
|
-
}
|
|
447
|
-
callback && callback(img, isError);
|
|
448
|
-
}, this, options && options.crossOrigin);
|
|
449
|
-
}
|
|
450
|
-
else {
|
|
451
|
-
options && image.setOptions(options);
|
|
452
|
-
this[property] = image;
|
|
453
|
-
image && (image.canvas = this);
|
|
454
|
-
callback && callback(image, false);
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
return this;
|
|
458
|
-
},
|
|
459
|
-
|
|
460
|
-
/**
|
|
461
|
-
* @private
|
|
462
|
-
* @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundColor|backgroundColor}
|
|
463
|
-
* or {@link fabric.StaticCanvas#overlayColor|overlayColor})
|
|
464
|
-
* @param {(Object|String|null)} color Object with pattern information, color value or null
|
|
465
|
-
* @param {Function} [callback] Callback is invoked when color is set
|
|
466
|
-
*/
|
|
467
|
-
__setBgOverlayColor: function(property, color, callback) {
|
|
468
|
-
this[property] = color;
|
|
469
|
-
this._initGradient(color, property);
|
|
470
|
-
this._initPattern(color, property, callback);
|
|
471
|
-
return this;
|
|
472
|
-
},
|
|
473
|
-
|
|
474
|
-
/**
|
|
475
|
-
* @private
|
|
476
|
-
*/
|
|
477
|
-
_createCanvasElement: function() {
|
|
478
|
-
var element = createCanvasElement();
|
|
479
|
-
if (!element) {
|
|
480
|
-
throw CANVAS_INIT_ERROR;
|
|
481
|
-
}
|
|
482
|
-
if (!element.style) {
|
|
483
|
-
element.style = { };
|
|
484
|
-
}
|
|
485
|
-
if (typeof element.getContext === 'undefined') {
|
|
486
|
-
throw CANVAS_INIT_ERROR;
|
|
487
|
-
}
|
|
488
|
-
return element;
|
|
489
|
-
},
|
|
490
|
-
|
|
491
|
-
/**
|
|
492
|
-
* @private
|
|
493
|
-
* @param {Object} [options] Options object
|
|
494
|
-
*/
|
|
495
|
-
_initOptions: function (options) {
|
|
496
|
-
var lowerCanvasEl = this.lowerCanvasEl;
|
|
497
|
-
this._setOptions(options);
|
|
498
|
-
|
|
499
|
-
this.width = this.width || parseInt(lowerCanvasEl.width, 10) || 0;
|
|
500
|
-
this.height = this.height || parseInt(lowerCanvasEl.height, 10) || 0;
|
|
501
|
-
|
|
502
|
-
if (!this.lowerCanvasEl.style) {
|
|
503
|
-
return;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
lowerCanvasEl.width = this.width;
|
|
507
|
-
lowerCanvasEl.height = this.height;
|
|
508
|
-
|
|
509
|
-
lowerCanvasEl.style.width = this.width + 'px';
|
|
510
|
-
lowerCanvasEl.style.height = this.height + 'px';
|
|
511
|
-
|
|
512
|
-
this.viewportTransform = this.viewportTransform.slice();
|
|
513
|
-
},
|
|
514
|
-
|
|
515
|
-
/**
|
|
516
|
-
* Creates a bottom canvas
|
|
517
|
-
* @private
|
|
518
|
-
* @param {HTMLElement} [canvasEl]
|
|
519
|
-
*/
|
|
520
|
-
_createLowerCanvas: function (canvasEl) {
|
|
521
|
-
// canvasEl === 'HTMLCanvasElement' does not work on jsdom/node
|
|
522
|
-
if (canvasEl && canvasEl.getContext) {
|
|
523
|
-
this.lowerCanvasEl = canvasEl;
|
|
524
|
-
}
|
|
525
|
-
else {
|
|
526
|
-
this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement();
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
fabric.util.addClass(this.lowerCanvasEl, 'lower-canvas');
|
|
530
|
-
this._originalCanvasStyle = this.lowerCanvasEl.style;
|
|
531
|
-
if (this.interactive) {
|
|
532
|
-
this._applyCanvasStyle(this.lowerCanvasEl);
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
this.contextContainer = this.lowerCanvasEl.getContext('2d');
|
|
536
|
-
},
|
|
537
|
-
|
|
538
|
-
/**
|
|
539
|
-
* Returns canvas width (in px)
|
|
540
|
-
* @return {Number}
|
|
541
|
-
*/
|
|
542
|
-
getWidth: function () {
|
|
543
|
-
return this.width;
|
|
544
|
-
},
|
|
545
|
-
|
|
546
|
-
/**
|
|
547
|
-
* Returns canvas height (in px)
|
|
548
|
-
* @return {Number}
|
|
549
|
-
*/
|
|
550
|
-
getHeight: function () {
|
|
551
|
-
return this.height;
|
|
552
|
-
},
|
|
553
|
-
|
|
554
|
-
/**
|
|
555
|
-
* Sets width of this canvas instance
|
|
556
|
-
* @param {Number|String} value Value to set width to
|
|
557
|
-
* @param {Object} [options] Options object
|
|
558
|
-
* @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions
|
|
559
|
-
* @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions
|
|
560
|
-
* @return {fabric.Canvas} instance
|
|
561
|
-
* @chainable true
|
|
562
|
-
*/
|
|
563
|
-
setWidth: function (value, options) {
|
|
564
|
-
return this.setDimensions({ width: value }, options);
|
|
565
|
-
},
|
|
566
|
-
|
|
567
|
-
/**
|
|
568
|
-
* Sets height of this canvas instance
|
|
569
|
-
* @param {Number|String} value Value to set height to
|
|
570
|
-
* @param {Object} [options] Options object
|
|
571
|
-
* @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions
|
|
572
|
-
* @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions
|
|
573
|
-
* @return {fabric.Canvas} instance
|
|
574
|
-
* @chainable true
|
|
575
|
-
*/
|
|
576
|
-
setHeight: function (value, options) {
|
|
577
|
-
return this.setDimensions({ height: value }, options);
|
|
578
|
-
},
|
|
579
|
-
|
|
580
|
-
/**
|
|
581
|
-
* Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em)
|
|
582
|
-
* @param {Object} dimensions Object with width/height properties
|
|
583
|
-
* @param {Number|String} [dimensions.width] Width of canvas element
|
|
584
|
-
* @param {Number|String} [dimensions.height] Height of canvas element
|
|
585
|
-
* @param {Object} [options] Options object
|
|
586
|
-
* @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions
|
|
587
|
-
* @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions
|
|
588
|
-
* @return {fabric.Canvas} thisArg
|
|
589
|
-
* @chainable
|
|
590
|
-
*/
|
|
591
|
-
setDimensions: function (dimensions, options) {
|
|
592
|
-
var cssValue;
|
|
593
|
-
|
|
594
|
-
options = options || {};
|
|
595
|
-
|
|
596
|
-
for (var prop in dimensions) {
|
|
597
|
-
cssValue = dimensions[prop];
|
|
598
|
-
|
|
599
|
-
if (!options.cssOnly) {
|
|
600
|
-
this._setBackstoreDimension(prop, dimensions[prop]);
|
|
601
|
-
cssValue += 'px';
|
|
602
|
-
this.hasLostContext = true;
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
if (!options.backstoreOnly) {
|
|
606
|
-
this._setCssDimension(prop, cssValue);
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
if (this._isCurrentlyDrawing) {
|
|
610
|
-
this.freeDrawingBrush && this.freeDrawingBrush._setBrushStyles(this.contextTop);
|
|
611
|
-
}
|
|
612
|
-
this._initRetinaScaling();
|
|
613
|
-
this.calcOffset();
|
|
614
|
-
|
|
615
|
-
if (!options.cssOnly) {
|
|
616
|
-
this.requestRenderAll();
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
return this;
|
|
620
|
-
},
|
|
621
|
-
|
|
622
|
-
/**
|
|
623
|
-
* Helper for setting width/height
|
|
624
|
-
* @private
|
|
625
|
-
* @param {String} prop property (width|height)
|
|
626
|
-
* @param {Number} value value to set property to
|
|
627
|
-
* @return {fabric.Canvas} instance
|
|
628
|
-
* @chainable true
|
|
629
|
-
*/
|
|
630
|
-
_setBackstoreDimension: function (prop, value) {
|
|
631
|
-
this.lowerCanvasEl[prop] = value;
|
|
632
|
-
|
|
633
|
-
if (this.upperCanvasEl) {
|
|
634
|
-
this.upperCanvasEl[prop] = value;
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
if (this.cacheCanvasEl) {
|
|
638
|
-
this.cacheCanvasEl[prop] = value;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
this[prop] = value;
|
|
642
|
-
|
|
643
|
-
return this;
|
|
644
|
-
},
|
|
645
|
-
|
|
646
|
-
/**
|
|
647
|
-
* Helper for setting css width/height
|
|
648
|
-
* @private
|
|
649
|
-
* @param {String} prop property (width|height)
|
|
650
|
-
* @param {String} value value to set property to
|
|
651
|
-
* @return {fabric.Canvas} instance
|
|
652
|
-
* @chainable true
|
|
653
|
-
*/
|
|
654
|
-
_setCssDimension: function (prop, value) {
|
|
655
|
-
this.lowerCanvasEl.style[prop] = value;
|
|
656
|
-
|
|
657
|
-
if (this.upperCanvasEl) {
|
|
658
|
-
this.upperCanvasEl.style[prop] = value;
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
if (this.wrapperEl) {
|
|
662
|
-
this.wrapperEl.style[prop] = value;
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
return this;
|
|
666
|
-
},
|
|
667
|
-
|
|
668
|
-
/**
|
|
669
|
-
* Returns canvas zoom level
|
|
670
|
-
* @return {Number}
|
|
671
|
-
*/
|
|
672
|
-
getZoom: function () {
|
|
673
|
-
return this.viewportTransform[0];
|
|
674
|
-
},
|
|
675
|
-
|
|
676
|
-
/**
|
|
677
|
-
* Sets viewport transformation of this canvas instance
|
|
678
|
-
* @param {Array} vpt a Canvas 2D API transform matrix
|
|
679
|
-
* @return {fabric.Canvas} instance
|
|
680
|
-
* @chainable true
|
|
681
|
-
*/
|
|
682
|
-
setViewportTransform: function (vpt) {
|
|
683
|
-
var activeObject = this._activeObject,
|
|
684
|
-
backgroundObject = this.backgroundImage,
|
|
685
|
-
overlayObject = this.overlayImage,
|
|
686
|
-
object, i, len;
|
|
687
|
-
this.viewportTransform = vpt;
|
|
688
|
-
for (i = 0, len = this._objects.length; i < len; i++) {
|
|
689
|
-
object = this._objects[i];
|
|
690
|
-
object.group || object.setCoords(true);
|
|
691
|
-
}
|
|
692
|
-
if (activeObject) {
|
|
693
|
-
activeObject.setCoords();
|
|
694
|
-
}
|
|
695
|
-
if (backgroundObject) {
|
|
696
|
-
backgroundObject.setCoords(true);
|
|
697
|
-
}
|
|
698
|
-
if (overlayObject) {
|
|
699
|
-
overlayObject.setCoords(true);
|
|
700
|
-
}
|
|
701
|
-
this.calcViewportBoundaries();
|
|
702
|
-
this.renderOnAddRemove && this.requestRenderAll();
|
|
703
|
-
return this;
|
|
704
|
-
},
|
|
705
|
-
|
|
706
|
-
/**
|
|
707
|
-
* Sets zoom level of this canvas instance, the zoom centered around point
|
|
708
|
-
* meaning that following zoom to point with the same point will have the visual
|
|
709
|
-
* effect of the zoom originating from that point. The point won't move.
|
|
710
|
-
* It has nothing to do with canvas center or visual center of the viewport.
|
|
711
|
-
* @param {fabric.Point} point to zoom with respect to
|
|
712
|
-
* @param {Number} value to set zoom to, less than 1 zooms out
|
|
713
|
-
* @return {fabric.Canvas} instance
|
|
714
|
-
* @chainable true
|
|
715
|
-
*/
|
|
716
|
-
zoomToPoint: function (point, value) {
|
|
717
|
-
// TODO: just change the scale, preserve other transformations
|
|
718
|
-
var before = point, vpt = this.viewportTransform.slice(0);
|
|
719
|
-
point = transformPoint(point, invertTransform(this.viewportTransform));
|
|
720
|
-
vpt[0] = value;
|
|
721
|
-
vpt[3] = value;
|
|
722
|
-
var after = transformPoint(point, vpt);
|
|
723
|
-
vpt[4] += before.x - after.x;
|
|
724
|
-
vpt[5] += before.y - after.y;
|
|
725
|
-
return this.setViewportTransform(vpt);
|
|
726
|
-
},
|
|
727
|
-
|
|
728
|
-
/**
|
|
729
|
-
* Sets zoom level of this canvas instance
|
|
730
|
-
* @param {Number} value to set zoom to, less than 1 zooms out
|
|
731
|
-
* @return {fabric.Canvas} instance
|
|
732
|
-
* @chainable true
|
|
733
|
-
*/
|
|
734
|
-
setZoom: function (value) {
|
|
735
|
-
this.zoomToPoint(new fabric.Point(0, 0), value);
|
|
736
|
-
return this;
|
|
737
|
-
},
|
|
738
|
-
|
|
739
|
-
/**
|
|
740
|
-
* Pan viewport so as to place point at top left corner of canvas
|
|
741
|
-
* @param {fabric.Point} point to move to
|
|
742
|
-
* @return {fabric.Canvas} instance
|
|
743
|
-
* @chainable true
|
|
744
|
-
*/
|
|
745
|
-
absolutePan: function (point) {
|
|
746
|
-
var vpt = this.viewportTransform.slice(0);
|
|
747
|
-
vpt[4] = -point.x;
|
|
748
|
-
vpt[5] = -point.y;
|
|
749
|
-
return this.setViewportTransform(vpt);
|
|
750
|
-
},
|
|
751
|
-
|
|
752
|
-
/**
|
|
753
|
-
* Pans viewpoint relatively
|
|
754
|
-
* @param {fabric.Point} point (position vector) to move by
|
|
755
|
-
* @return {fabric.Canvas} instance
|
|
756
|
-
* @chainable true
|
|
757
|
-
*/
|
|
758
|
-
relativePan: function (point) {
|
|
759
|
-
return this.absolutePan(new fabric.Point(
|
|
760
|
-
-point.x - this.viewportTransform[4],
|
|
761
|
-
-point.y - this.viewportTransform[5]
|
|
762
|
-
));
|
|
763
|
-
},
|
|
764
|
-
|
|
765
|
-
/**
|
|
766
|
-
* Returns <canvas> element corresponding to this instance
|
|
767
|
-
* @return {HTMLCanvasElement}
|
|
768
|
-
*/
|
|
769
|
-
getElement: function () {
|
|
770
|
-
return this.lowerCanvasEl;
|
|
771
|
-
},
|
|
772
|
-
|
|
773
|
-
/**
|
|
774
|
-
* @private
|
|
775
|
-
* @param {fabric.Object} obj Object that was added
|
|
776
|
-
*/
|
|
777
|
-
_onObjectAdded: function(obj) {
|
|
778
|
-
this.stateful && obj.setupState();
|
|
779
|
-
obj._set('canvas', this);
|
|
780
|
-
obj.setCoords();
|
|
781
|
-
this.fire('object:added', { target: obj });
|
|
782
|
-
obj.fire('added');
|
|
783
|
-
},
|
|
784
|
-
|
|
785
|
-
/**
|
|
786
|
-
* @private
|
|
787
|
-
* @param {fabric.Object} obj Object that was removed
|
|
788
|
-
*/
|
|
789
|
-
_onObjectRemoved: function(obj) {
|
|
790
|
-
this.fire('object:removed', { target: obj });
|
|
791
|
-
obj.fire('removed');
|
|
792
|
-
delete obj.canvas;
|
|
793
|
-
},
|
|
794
|
-
|
|
795
|
-
/**
|
|
796
|
-
* Clears specified context of canvas element
|
|
797
|
-
* @param {CanvasRenderingContext2D} ctx Context to clear
|
|
798
|
-
* @return {fabric.Canvas} thisArg
|
|
799
|
-
* @chainable
|
|
800
|
-
*/
|
|
801
|
-
clearContext: function(ctx) {
|
|
802
|
-
ctx.clearRect(0, 0, this.width, this.height);
|
|
803
|
-
return this;
|
|
804
|
-
},
|
|
805
|
-
|
|
806
|
-
/**
|
|
807
|
-
* Returns context of canvas where objects are drawn
|
|
808
|
-
* @return {CanvasRenderingContext2D}
|
|
809
|
-
*/
|
|
810
|
-
getContext: function () {
|
|
811
|
-
return this.contextContainer;
|
|
812
|
-
},
|
|
813
|
-
|
|
814
|
-
/**
|
|
815
|
-
* Clears all contexts (background, main, top) of an instance
|
|
816
|
-
* @return {fabric.Canvas} thisArg
|
|
817
|
-
* @chainable
|
|
818
|
-
*/
|
|
819
|
-
clear: function () {
|
|
820
|
-
this.remove.apply(this, this.getObjects());
|
|
821
|
-
this.backgroundImage = null;
|
|
822
|
-
this.overlayImage = null;
|
|
823
|
-
this.backgroundColor = '';
|
|
824
|
-
this.overlayColor = '';
|
|
825
|
-
if (this._hasITextHandlers) {
|
|
826
|
-
this.off('mouse:up', this._mouseUpITextHandler);
|
|
827
|
-
this._iTextInstances = null;
|
|
828
|
-
this._hasITextHandlers = false;
|
|
829
|
-
}
|
|
830
|
-
this.clearContext(this.contextContainer);
|
|
831
|
-
this.fire('canvas:cleared');
|
|
832
|
-
this.renderOnAddRemove && this.requestRenderAll();
|
|
833
|
-
return this;
|
|
834
|
-
},
|
|
835
|
-
|
|
836
|
-
/**
|
|
837
|
-
* Renders the canvas
|
|
838
|
-
* @return {fabric.Canvas} instance
|
|
839
|
-
* @chainable
|
|
840
|
-
*/
|
|
841
|
-
renderAll: function () {
|
|
842
|
-
var canvasToDrawOn = this.contextContainer;
|
|
843
|
-
this.renderCanvas(canvasToDrawOn, this._objects);
|
|
844
|
-
return this;
|
|
845
|
-
},
|
|
846
|
-
|
|
847
|
-
/**
|
|
848
|
-
* Function created to be instance bound at initialization
|
|
849
|
-
* used in requestAnimationFrame rendering
|
|
850
|
-
* Let the fabricJS call it. If you call it manually you could have more
|
|
851
|
-
* animationFrame stacking on to of each other
|
|
852
|
-
* for an imperative rendering, use canvas.renderAll
|
|
853
|
-
* @private
|
|
854
|
-
* @return {fabric.Canvas} instance
|
|
855
|
-
* @chainable
|
|
856
|
-
*/
|
|
857
|
-
renderAndReset: function() {
|
|
858
|
-
this.isRendering = 0;
|
|
859
|
-
this.renderAll();
|
|
860
|
-
},
|
|
861
|
-
|
|
862
|
-
/**
|
|
863
|
-
* Append a renderAll request to next animation frame.
|
|
864
|
-
* unless one is already in progress, in that case nothing is done
|
|
865
|
-
* a boolean flag will avoid appending more.
|
|
866
|
-
* @return {fabric.Canvas} instance
|
|
867
|
-
* @chainable
|
|
868
|
-
*/
|
|
869
|
-
requestRenderAll: function () {
|
|
870
|
-
if (!this.isRendering) {
|
|
871
|
-
this.isRendering = fabric.util.requestAnimFrame(this.renderAndResetBound);
|
|
872
|
-
}
|
|
873
|
-
return this;
|
|
874
|
-
},
|
|
875
|
-
|
|
876
|
-
/**
|
|
877
|
-
* Calculate the position of the 4 corner of canvas with current viewportTransform.
|
|
878
|
-
* helps to determinate when an object is in the current rendering viewport using
|
|
879
|
-
* object absolute coordinates ( aCoords )
|
|
880
|
-
* @return {Object} points.tl
|
|
881
|
-
* @chainable
|
|
882
|
-
*/
|
|
883
|
-
calcViewportBoundaries: function() {
|
|
884
|
-
var points = { }, width = this.width, height = this.height,
|
|
885
|
-
iVpt = invertTransform(this.viewportTransform);
|
|
886
|
-
points.tl = transformPoint({ x: 0, y: 0 }, iVpt);
|
|
887
|
-
points.br = transformPoint({ x: width, y: height }, iVpt);
|
|
888
|
-
points.tr = new fabric.Point(points.br.x, points.tl.y);
|
|
889
|
-
points.bl = new fabric.Point(points.tl.x, points.br.y);
|
|
890
|
-
this.vptCoords = points;
|
|
891
|
-
return points;
|
|
892
|
-
},
|
|
893
|
-
|
|
894
|
-
cancelRequestedRender: function() {
|
|
895
|
-
if (this.isRendering) {
|
|
896
|
-
fabric.util.cancelAnimFrame(this.isRendering);
|
|
897
|
-
this.isRendering = 0;
|
|
898
|
-
}
|
|
899
|
-
},
|
|
900
|
-
|
|
901
|
-
/**
|
|
902
|
-
* Renders background, objects, overlay and controls.
|
|
903
|
-
* @param {CanvasRenderingContext2D} ctx
|
|
904
|
-
* @param {Array} objects to render
|
|
905
|
-
* @return {fabric.Canvas} instance
|
|
906
|
-
* @chainable
|
|
907
|
-
*/
|
|
908
|
-
renderCanvas: function(ctx, objects) {
|
|
909
|
-
var v = this.viewportTransform, path = this.clipPath;
|
|
910
|
-
this.cancelRequestedRender();
|
|
911
|
-
this.calcViewportBoundaries();
|
|
912
|
-
this.clearContext(ctx);
|
|
913
|
-
fabric.util.setImageSmoothing(ctx, this.imageSmoothingEnabled);
|
|
914
|
-
this.fire('before:render', { ctx: ctx, });
|
|
915
|
-
this._renderBackground(ctx);
|
|
916
|
-
|
|
917
|
-
ctx.save();
|
|
918
|
-
//apply viewport transform once for all rendering process
|
|
919
|
-
ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
|
|
920
|
-
this._renderObjects(ctx, objects);
|
|
921
|
-
ctx.restore();
|
|
922
|
-
if (!this.controlsAboveOverlay && this.interactive) {
|
|
923
|
-
this.drawControls(ctx);
|
|
924
|
-
}
|
|
925
|
-
if (path) {
|
|
926
|
-
path.canvas = this;
|
|
927
|
-
// needed to setup a couple of variables
|
|
928
|
-
path.shouldCache();
|
|
929
|
-
path._transformDone = true;
|
|
930
|
-
path.renderCache({ forClipping: true });
|
|
931
|
-
this.drawClipPathOnCanvas(ctx);
|
|
932
|
-
}
|
|
933
|
-
this._renderOverlay(ctx);
|
|
934
|
-
if (this.controlsAboveOverlay && this.interactive) {
|
|
935
|
-
this.drawControls(ctx);
|
|
936
|
-
}
|
|
937
|
-
this.fire('after:render', { ctx: ctx, });
|
|
938
|
-
},
|
|
939
|
-
|
|
940
|
-
/**
|
|
941
|
-
* Paint the cached clipPath on the lowerCanvasEl
|
|
942
|
-
* @param {CanvasRenderingContext2D} ctx Context to render on
|
|
943
|
-
*/
|
|
944
|
-
drawClipPathOnCanvas: function(ctx) {
|
|
945
|
-
var v = this.viewportTransform, path = this.clipPath;
|
|
946
|
-
ctx.save();
|
|
947
|
-
ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
|
|
948
|
-
// DEBUG: uncomment this line, comment the following
|
|
949
|
-
// ctx.globalAlpha = 0.4;
|
|
950
|
-
ctx.globalCompositeOperation = 'destination-in';
|
|
951
|
-
path.transform(ctx);
|
|
952
|
-
ctx.scale(1 / path.zoomX, 1 / path.zoomY);
|
|
953
|
-
ctx.drawImage(path._cacheCanvas, -path.cacheTranslationX, -path.cacheTranslationY);
|
|
954
|
-
ctx.restore();
|
|
955
|
-
},
|
|
956
|
-
|
|
957
|
-
/**
|
|
958
|
-
* @private
|
|
959
|
-
* @param {CanvasRenderingContext2D} ctx Context to render on
|
|
960
|
-
* @param {Array} objects to render
|
|
961
|
-
*/
|
|
962
|
-
_renderObjects: function(ctx, objects) {
|
|
963
|
-
var i, len;
|
|
964
|
-
for (i = 0, len = objects.length; i < len; ++i) {
|
|
965
|
-
objects[i] && objects[i].render(ctx);
|
|
966
|
-
}
|
|
967
|
-
},
|
|
968
|
-
|
|
969
|
-
/**
|
|
970
|
-
* @private
|
|
971
|
-
* @param {CanvasRenderingContext2D} ctx Context to render on
|
|
972
|
-
* @param {string} property 'background' or 'overlay'
|
|
973
|
-
*/
|
|
974
|
-
_renderBackgroundOrOverlay: function(ctx, property) {
|
|
975
|
-
var fill = this[property + 'Color'], object = this[property + 'Image'],
|
|
976
|
-
v = this.viewportTransform, needsVpt = this[property + 'Vpt'];
|
|
977
|
-
if (!fill && !object) {
|
|
978
|
-
return;
|
|
979
|
-
}
|
|
980
|
-
if (fill) {
|
|
981
|
-
ctx.save();
|
|
982
|
-
ctx.beginPath();
|
|
983
|
-
ctx.moveTo(0, 0);
|
|
984
|
-
ctx.lineTo(this.width, 0);
|
|
985
|
-
ctx.lineTo(this.width, this.height);
|
|
986
|
-
ctx.lineTo(0, this.height);
|
|
987
|
-
ctx.closePath();
|
|
988
|
-
ctx.fillStyle = fill.toLive
|
|
989
|
-
? fill.toLive(ctx, this)
|
|
990
|
-
: fill;
|
|
991
|
-
if (needsVpt) {
|
|
992
|
-
ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
|
|
993
|
-
}
|
|
994
|
-
ctx.transform(1, 0, 0, 1, fill.offsetX || 0, fill.offsetY || 0);
|
|
995
|
-
var m = fill.gradientTransform || fill.patternTransform;
|
|
996
|
-
m && ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
|
997
|
-
ctx.fill();
|
|
998
|
-
ctx.restore();
|
|
999
|
-
}
|
|
1000
|
-
if (object) {
|
|
1001
|
-
ctx.save();
|
|
1002
|
-
if (needsVpt) {
|
|
1003
|
-
ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
|
|
1004
|
-
}
|
|
1005
|
-
object.render(ctx);
|
|
1006
|
-
ctx.restore();
|
|
1007
|
-
}
|
|
1008
|
-
},
|
|
1009
|
-
|
|
1010
|
-
/**
|
|
1011
|
-
* @private
|
|
1012
|
-
* @param {CanvasRenderingContext2D} ctx Context to render on
|
|
1013
|
-
*/
|
|
1014
|
-
_renderBackground: function(ctx) {
|
|
1015
|
-
this._renderBackgroundOrOverlay(ctx, 'background');
|
|
1016
|
-
},
|
|
1017
|
-
|
|
1018
|
-
/**
|
|
1019
|
-
* @private
|
|
1020
|
-
* @param {CanvasRenderingContext2D} ctx Context to render on
|
|
1021
|
-
*/
|
|
1022
|
-
_renderOverlay: function(ctx) {
|
|
1023
|
-
this._renderBackgroundOrOverlay(ctx, 'overlay');
|
|
1024
|
-
},
|
|
1025
|
-
|
|
1026
|
-
/**
|
|
1027
|
-
* Returns coordinates of a center of canvas.
|
|
1028
|
-
* Returned value is an object with top and left properties
|
|
1029
|
-
* @return {Object} object with "top" and "left" number values
|
|
1030
|
-
* @deprecated migrate to `getCenterPoint`
|
|
1031
|
-
*/
|
|
1032
|
-
getCenter: function () {
|
|
1033
|
-
return {
|
|
1034
|
-
top: this.height / 2,
|
|
1035
|
-
left: this.width / 2
|
|
1036
|
-
};
|
|
1037
|
-
},
|
|
1038
|
-
|
|
1039
|
-
/**
|
|
1040
|
-
* Returns coordinates of a center of canvas.
|
|
1041
|
-
* @return {fabric.Point}
|
|
1042
|
-
*/
|
|
1043
|
-
getCenterPoint: function () {
|
|
1044
|
-
return new fabric.Point(this.width / 2, this.height / 2);
|
|
1045
|
-
},
|
|
1046
|
-
|
|
1047
|
-
/**
|
|
1048
|
-
* Centers object horizontally in the canvas
|
|
1049
|
-
* @param {fabric.Object} object Object to center horizontally
|
|
1050
|
-
* @return {fabric.Canvas} thisArg
|
|
1051
|
-
*/
|
|
1052
|
-
centerObjectH: function (object) {
|
|
1053
|
-
return this._centerObject(object, new fabric.Point(this.getCenterPoint().x, object.getCenterPoint().y));
|
|
1054
|
-
},
|
|
1055
|
-
|
|
1056
|
-
/**
|
|
1057
|
-
* Centers object vertically in the canvas
|
|
1058
|
-
* @param {fabric.Object} object Object to center vertically
|
|
1059
|
-
* @return {fabric.Canvas} thisArg
|
|
1060
|
-
* @chainable
|
|
1061
|
-
*/
|
|
1062
|
-
centerObjectV: function (object) {
|
|
1063
|
-
return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, this.getCenterPoint().y));
|
|
1064
|
-
},
|
|
1065
|
-
|
|
1066
|
-
/**
|
|
1067
|
-
* Centers object vertically and horizontally in the canvas
|
|
1068
|
-
* @param {fabric.Object} object Object to center vertically and horizontally
|
|
1069
|
-
* @return {fabric.Canvas} thisArg
|
|
1070
|
-
* @chainable
|
|
1071
|
-
*/
|
|
1072
|
-
centerObject: function(object) {
|
|
1073
|
-
var center = this.getCenterPoint();
|
|
1074
|
-
return this._centerObject(object, center);
|
|
1075
|
-
},
|
|
1076
|
-
|
|
1077
|
-
/**
|
|
1078
|
-
* Centers object vertically and horizontally in the viewport
|
|
1079
|
-
* @param {fabric.Object} object Object to center vertically and horizontally
|
|
1080
|
-
* @return {fabric.Canvas} thisArg
|
|
1081
|
-
* @chainable
|
|
1082
|
-
*/
|
|
1083
|
-
viewportCenterObject: function(object) {
|
|
1084
|
-
var vpCenter = this.getVpCenter();
|
|
1085
|
-
return this._centerObject(object, vpCenter);
|
|
1086
|
-
},
|
|
1087
|
-
|
|
1088
|
-
/**
|
|
1089
|
-
* Centers object horizontally in the viewport, object.top is unchanged
|
|
1090
|
-
* @param {fabric.Object} object Object to center vertically and horizontally
|
|
1091
|
-
* @return {fabric.Canvas} thisArg
|
|
1092
|
-
* @chainable
|
|
1093
|
-
*/
|
|
1094
|
-
viewportCenterObjectH: function(object) {
|
|
1095
|
-
var vpCenter = this.getVpCenter();
|
|
1096
|
-
this._centerObject(object, new fabric.Point(vpCenter.x, object.getCenterPoint().y));
|
|
1097
|
-
return this;
|
|
1098
|
-
},
|
|
1099
|
-
|
|
1100
|
-
/**
|
|
1101
|
-
* Centers object Vertically in the viewport, object.top is unchanged
|
|
1102
|
-
* @param {fabric.Object} object Object to center vertically and horizontally
|
|
1103
|
-
* @return {fabric.Canvas} thisArg
|
|
1104
|
-
* @chainable
|
|
1105
|
-
*/
|
|
1106
|
-
viewportCenterObjectV: function(object) {
|
|
1107
|
-
var vpCenter = this.getVpCenter();
|
|
1108
|
-
|
|
1109
|
-
return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, vpCenter.y));
|
|
1110
|
-
},
|
|
1111
|
-
|
|
1112
|
-
/**
|
|
1113
|
-
* Calculate the point in canvas that correspond to the center of actual viewport.
|
|
1114
|
-
* @return {fabric.Point} vpCenter, viewport center
|
|
1115
|
-
* @chainable
|
|
1116
|
-
*/
|
|
1117
|
-
getVpCenter: function() {
|
|
1118
|
-
var center = this.getCenterPoint(),
|
|
1119
|
-
iVpt = invertTransform(this.viewportTransform);
|
|
1120
|
-
return transformPoint(center, iVpt);
|
|
1121
|
-
},
|
|
1122
|
-
|
|
1123
|
-
/**
|
|
1124
|
-
* @private
|
|
1125
|
-
* @param {fabric.Object} object Object to center
|
|
1126
|
-
* @param {fabric.Point} center Center point
|
|
1127
|
-
* @return {fabric.Canvas} thisArg
|
|
1128
|
-
* @chainable
|
|
1129
|
-
*/
|
|
1130
|
-
_centerObject: function(object, center) {
|
|
1131
|
-
object.setPositionByOrigin(center, 'center', 'center');
|
|
1132
|
-
object.setCoords();
|
|
1133
|
-
this.renderOnAddRemove && this.requestRenderAll();
|
|
1134
|
-
return this;
|
|
1135
|
-
},
|
|
1136
|
-
|
|
1137
|
-
/**
|
|
1138
|
-
* Returns dataless JSON representation of canvas
|
|
1139
|
-
* @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
|
|
1140
|
-
* @return {String} json string
|
|
1141
|
-
*/
|
|
1142
|
-
toDatalessJSON: function (propertiesToInclude) {
|
|
1143
|
-
return this.toDatalessObject(propertiesToInclude);
|
|
1144
|
-
},
|
|
1145
|
-
|
|
1146
|
-
/**
|
|
1147
|
-
* Returns object representation of canvas
|
|
1148
|
-
* @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
|
|
1149
|
-
* @return {Object} object representation of an instance
|
|
1150
|
-
*/
|
|
1151
|
-
toObject: function (propertiesToInclude) {
|
|
1152
|
-
return this._toObjectMethod('toObject', propertiesToInclude);
|
|
1153
|
-
},
|
|
1154
|
-
|
|
1155
|
-
/**
|
|
1156
|
-
* Returns dataless object representation of canvas
|
|
1157
|
-
* @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
|
|
1158
|
-
* @return {Object} object representation of an instance
|
|
1159
|
-
*/
|
|
1160
|
-
toDatalessObject: function (propertiesToInclude) {
|
|
1161
|
-
return this._toObjectMethod('toDatalessObject', propertiesToInclude);
|
|
1162
|
-
},
|
|
1163
|
-
|
|
1164
|
-
/**
|
|
1165
|
-
* @private
|
|
1166
|
-
*/
|
|
1167
|
-
_toObjectMethod: function (methodName, propertiesToInclude) {
|
|
1168
|
-
|
|
1169
|
-
var clipPath = this.clipPath, data = {
|
|
1170
|
-
version: fabric.version,
|
|
1171
|
-
objects: this._toObjects(methodName, propertiesToInclude),
|
|
1172
|
-
};
|
|
1173
|
-
if (clipPath && !clipPath.excludeFromExport) {
|
|
1174
|
-
data.clipPath = this._toObject(this.clipPath, methodName, propertiesToInclude);
|
|
1175
|
-
}
|
|
1176
|
-
extend(data, this.__serializeBgOverlay(methodName, propertiesToInclude));
|
|
1177
|
-
|
|
1178
|
-
fabric.util.populateWithProperties(this, data, propertiesToInclude);
|
|
1179
|
-
|
|
1180
|
-
return data;
|
|
1181
|
-
},
|
|
1182
|
-
|
|
1183
|
-
/**
|
|
1184
|
-
* @private
|
|
1185
|
-
*/
|
|
1186
|
-
_toObjects: function(methodName, propertiesToInclude) {
|
|
1187
|
-
return this._objects.filter(function(object) {
|
|
1188
|
-
return !object.excludeFromExport;
|
|
1189
|
-
}).map(function(instance) {
|
|
1190
|
-
return this._toObject(instance, methodName, propertiesToInclude);
|
|
1191
|
-
}, this);
|
|
1192
|
-
},
|
|
1193
|
-
|
|
1194
|
-
/**
|
|
1195
|
-
* @private
|
|
1196
|
-
*/
|
|
1197
|
-
_toObject: function(instance, methodName, propertiesToInclude) {
|
|
1198
|
-
var originalValue;
|
|
1199
|
-
|
|
1200
|
-
if (!this.includeDefaultValues) {
|
|
1201
|
-
originalValue = instance.includeDefaultValues;
|
|
1202
|
-
instance.includeDefaultValues = false;
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
|
-
var object = instance[methodName](propertiesToInclude);
|
|
1206
|
-
if (!this.includeDefaultValues) {
|
|
1207
|
-
instance.includeDefaultValues = originalValue;
|
|
1208
|
-
}
|
|
1209
|
-
return object;
|
|
1210
|
-
},
|
|
1211
|
-
|
|
1212
|
-
/**
|
|
1213
|
-
* @private
|
|
1214
|
-
*/
|
|
1215
|
-
__serializeBgOverlay: function(methodName, propertiesToInclude) {
|
|
1216
|
-
var data = {}, bgImage = this.backgroundImage, overlayImage = this.overlayImage,
|
|
1217
|
-
bgColor = this.backgroundColor, overlayColor = this.overlayColor;
|
|
1218
|
-
|
|
1219
|
-
if (bgColor && bgColor.toObject) {
|
|
1220
|
-
if (!bgColor.excludeFromExport) {
|
|
1221
|
-
data.background = bgColor.toObject(propertiesToInclude);
|
|
1222
|
-
}
|
|
1223
|
-
}
|
|
1224
|
-
else if (bgColor) {
|
|
1225
|
-
data.background = bgColor;
|
|
1226
|
-
}
|
|
1227
|
-
|
|
1228
|
-
if (overlayColor && overlayColor.toObject) {
|
|
1229
|
-
if (!overlayColor.excludeFromExport) {
|
|
1230
|
-
data.overlay = overlayColor.toObject(propertiesToInclude);
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
else if (overlayColor) {
|
|
1234
|
-
data.overlay = overlayColor;
|
|
1235
|
-
}
|
|
1236
|
-
|
|
1237
|
-
if (bgImage && !bgImage.excludeFromExport) {
|
|
1238
|
-
data.backgroundImage = this._toObject(bgImage, methodName, propertiesToInclude);
|
|
1239
|
-
}
|
|
1240
|
-
if (overlayImage && !overlayImage.excludeFromExport) {
|
|
1241
|
-
data.overlayImage = this._toObject(overlayImage, methodName, propertiesToInclude);
|
|
1242
|
-
}
|
|
1243
|
-
|
|
1244
|
-
return data;
|
|
1245
|
-
},
|
|
1246
|
-
|
|
1247
|
-
/* _TO_SVG_START_ */
|
|
1248
|
-
/**
|
|
1249
|
-
* When true, getSvgTransform() will apply the StaticCanvas.viewportTransform to the SVG transformation. When true,
|
|
1250
|
-
* a zoomed canvas will then produce zoomed SVG output.
|
|
1251
|
-
* @type Boolean
|
|
1252
|
-
* @default
|
|
1253
|
-
*/
|
|
1254
|
-
svgViewportTransformation: true,
|
|
1255
|
-
|
|
1256
|
-
/**
|
|
1257
|
-
* Returns SVG representation of canvas
|
|
1258
|
-
* @function
|
|
1259
|
-
* @param {Object} [options] Options object for SVG output
|
|
1260
|
-
* @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included
|
|
1261
|
-
* @param {Object} [options.viewBox] SVG viewbox object
|
|
1262
|
-
* @param {Number} [options.viewBox.x] x-coordinate of viewbox
|
|
1263
|
-
* @param {Number} [options.viewBox.y] y-coordinate of viewbox
|
|
1264
|
-
* @param {Number} [options.viewBox.width] Width of viewbox
|
|
1265
|
-
* @param {Number} [options.viewBox.height] Height of viewbox
|
|
1266
|
-
* @param {String} [options.encoding=UTF-8] Encoding of SVG output
|
|
1267
|
-
* @param {String} [options.width] desired width of svg with or without units
|
|
1268
|
-
* @param {String} [options.height] desired height of svg with or without units
|
|
1269
|
-
* @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation.
|
|
1270
|
-
* @return {String} SVG string
|
|
1271
|
-
* @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}
|
|
1272
|
-
* @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo}
|
|
1273
|
-
* @example <caption>Normal SVG output</caption>
|
|
1274
|
-
* var svg = canvas.toSVG();
|
|
1275
|
-
* @example <caption>SVG output without preamble (without <?xml ../>)</caption>
|
|
1276
|
-
* var svg = canvas.toSVG({suppressPreamble: true});
|
|
1277
|
-
* @example <caption>SVG output with viewBox attribute</caption>
|
|
1278
|
-
* var svg = canvas.toSVG({
|
|
1279
|
-
* viewBox: {
|
|
1280
|
-
* x: 100,
|
|
1281
|
-
* y: 100,
|
|
1282
|
-
* width: 200,
|
|
1283
|
-
* height: 300
|
|
1284
|
-
* }
|
|
1285
|
-
* });
|
|
1286
|
-
* @example <caption>SVG output with different encoding (default: UTF-8)</caption>
|
|
1287
|
-
* var svg = canvas.toSVG({encoding: 'ISO-8859-1'});
|
|
1288
|
-
* @example <caption>Modify SVG output with reviver function</caption>
|
|
1289
|
-
* var svg = canvas.toSVG(null, function(svg) {
|
|
1290
|
-
* return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', '');
|
|
1291
|
-
* });
|
|
1292
|
-
*/
|
|
1293
|
-
toSVG: function(options, reviver) {
|
|
1294
|
-
options || (options = { });
|
|
1295
|
-
options.reviver = reviver;
|
|
1296
|
-
var markup = [];
|
|
1297
|
-
|
|
1298
|
-
this._setSVGPreamble(markup, options);
|
|
1299
|
-
this._setSVGHeader(markup, options);
|
|
1300
|
-
if (this.clipPath) {
|
|
1301
|
-
markup.push('<g clip-path="url(#' + this.clipPath.clipPathId + ')" >\n');
|
|
1302
|
-
}
|
|
1303
|
-
this._setSVGBgOverlayColor(markup, 'background');
|
|
1304
|
-
this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver);
|
|
1305
|
-
this._setSVGObjects(markup, reviver);
|
|
1306
|
-
if (this.clipPath) {
|
|
1307
|
-
markup.push('</g>\n');
|
|
1308
|
-
}
|
|
1309
|
-
this._setSVGBgOverlayColor(markup, 'overlay');
|
|
1310
|
-
this._setSVGBgOverlayImage(markup, 'overlayImage', reviver);
|
|
1311
|
-
|
|
1312
|
-
markup.push('</svg>');
|
|
1313
|
-
|
|
1314
|
-
return markup.join('');
|
|
1315
|
-
},
|
|
1316
|
-
|
|
1317
|
-
/**
|
|
1318
|
-
* @private
|
|
1319
|
-
*/
|
|
1320
|
-
_setSVGPreamble: function(markup, options) {
|
|
1321
|
-
if (options.suppressPreamble) {
|
|
1322
|
-
return;
|
|
1323
|
-
}
|
|
1324
|
-
markup.push(
|
|
1325
|
-
'<?xml version="1.0" encoding="', (options.encoding || 'UTF-8'), '" standalone="no" ?>\n',
|
|
1326
|
-
'<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" ',
|
|
1327
|
-
'"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n'
|
|
1328
|
-
);
|
|
1329
|
-
},
|
|
1330
|
-
|
|
1331
|
-
/**
|
|
1332
|
-
* @private
|
|
1333
|
-
*/
|
|
1334
|
-
_setSVGHeader: function(markup, options) {
|
|
1335
|
-
var width = options.width || this.width,
|
|
1336
|
-
height = options.height || this.height,
|
|
1337
|
-
vpt, viewBox = 'viewBox="0 0 ' + this.width + ' ' + this.height + '" ',
|
|
1338
|
-
NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;
|
|
1339
|
-
|
|
1340
|
-
if (options.viewBox) {
|
|
1341
|
-
viewBox = 'viewBox="' +
|
|
1342
|
-
options.viewBox.x + ' ' +
|
|
1343
|
-
options.viewBox.y + ' ' +
|
|
1344
|
-
options.viewBox.width + ' ' +
|
|
1345
|
-
options.viewBox.height + '" ';
|
|
1346
|
-
}
|
|
1347
|
-
else {
|
|
1348
|
-
if (this.svgViewportTransformation) {
|
|
1349
|
-
vpt = this.viewportTransform;
|
|
1350
|
-
viewBox = 'viewBox="' +
|
|
1351
|
-
toFixed(-vpt[4] / vpt[0], NUM_FRACTION_DIGITS) + ' ' +
|
|
1352
|
-
toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS) + ' ' +
|
|
1353
|
-
toFixed(this.width / vpt[0], NUM_FRACTION_DIGITS) + ' ' +
|
|
1354
|
-
toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS) + '" ';
|
|
1355
|
-
}
|
|
1356
|
-
}
|
|
1357
|
-
|
|
1358
|
-
markup.push(
|
|
1359
|
-
'<svg ',
|
|
1360
|
-
'xmlns="http://www.w3.org/2000/svg" ',
|
|
1361
|
-
'xmlns:xlink="http://www.w3.org/1999/xlink" ',
|
|
1362
|
-
'version="1.1" ',
|
|
1363
|
-
'width="', width, '" ',
|
|
1364
|
-
'height="', height, '" ',
|
|
1365
|
-
viewBox,
|
|
1366
|
-
'xml:space="preserve">\n',
|
|
1367
|
-
'<desc>Created with Fabric.js ', fabric.version, '</desc>\n',
|
|
1368
|
-
'<defs>\n',
|
|
1369
|
-
this.createSVGFontFacesMarkup(),
|
|
1370
|
-
this.createSVGRefElementsMarkup(),
|
|
1371
|
-
this.createSVGClipPathMarkup(options),
|
|
1372
|
-
'</defs>\n'
|
|
1373
|
-
);
|
|
1374
|
-
},
|
|
1375
|
-
|
|
1376
|
-
createSVGClipPathMarkup: function(options) {
|
|
1377
|
-
var clipPath = this.clipPath;
|
|
1378
|
-
if (clipPath) {
|
|
1379
|
-
clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++;
|
|
1380
|
-
return '<clipPath id="' + clipPath.clipPathId + '" >\n' +
|
|
1381
|
-
this.clipPath.toClipPathSVG(options.reviver) +
|
|
1382
|
-
'</clipPath>\n';
|
|
1383
|
-
}
|
|
1384
|
-
return '';
|
|
1385
|
-
},
|
|
1386
|
-
|
|
1387
|
-
/**
|
|
1388
|
-
* Creates markup containing SVG referenced elements like patterns, gradients etc.
|
|
1389
|
-
* @return {String}
|
|
1390
|
-
*/
|
|
1391
|
-
createSVGRefElementsMarkup: function() {
|
|
1392
|
-
var _this = this,
|
|
1393
|
-
markup = ['background', 'overlay'].map(function(prop) {
|
|
1394
|
-
var fill = _this[prop + 'Color'];
|
|
1395
|
-
if (fill && fill.toLive) {
|
|
1396
|
-
var shouldTransform = _this[prop + 'Vpt'], vpt = _this.viewportTransform,
|
|
1397
|
-
object = {
|
|
1398
|
-
width: _this.width / (shouldTransform ? vpt[0] : 1),
|
|
1399
|
-
height: _this.height / (shouldTransform ? vpt[3] : 1)
|
|
1400
|
-
};
|
|
1401
|
-
return fill.toSVG(
|
|
1402
|
-
object,
|
|
1403
|
-
{ additionalTransform: shouldTransform ? fabric.util.matrixToSVG(vpt) : '' }
|
|
1404
|
-
);
|
|
1405
|
-
}
|
|
1406
|
-
});
|
|
1407
|
-
return markup.join('');
|
|
1408
|
-
},
|
|
1409
|
-
|
|
1410
|
-
/**
|
|
1411
|
-
* Creates markup containing SVG font faces,
|
|
1412
|
-
* font URLs for font faces must be collected by developers
|
|
1413
|
-
* and are not extracted from the DOM by fabricjs
|
|
1414
|
-
* @param {Array} objects Array of fabric objects
|
|
1415
|
-
* @return {String}
|
|
1416
|
-
*/
|
|
1417
|
-
createSVGFontFacesMarkup: function() {
|
|
1418
|
-
var markup = '', fontList = { }, obj, fontFamily,
|
|
1419
|
-
style, row, rowIndex, _char, charIndex, i, len,
|
|
1420
|
-
fontPaths = fabric.fontPaths, objects = [];
|
|
1421
|
-
|
|
1422
|
-
this._objects.forEach(function add(object) {
|
|
1423
|
-
objects.push(object);
|
|
1424
|
-
if (object._objects) {
|
|
1425
|
-
object._objects.forEach(add);
|
|
1426
|
-
}
|
|
1427
|
-
});
|
|
1428
|
-
|
|
1429
|
-
for (i = 0, len = objects.length; i < len; i++) {
|
|
1430
|
-
obj = objects[i];
|
|
1431
|
-
fontFamily = obj.fontFamily;
|
|
1432
|
-
if (obj.type.indexOf('text') === -1 || fontList[fontFamily] || !fontPaths[fontFamily]) {
|
|
1433
|
-
continue;
|
|
1434
|
-
}
|
|
1435
|
-
fontList[fontFamily] = true;
|
|
1436
|
-
if (!obj.styles) {
|
|
1437
|
-
continue;
|
|
1438
|
-
}
|
|
1439
|
-
style = obj.styles;
|
|
1440
|
-
for (rowIndex in style) {
|
|
1441
|
-
row = style[rowIndex];
|
|
1442
|
-
for (charIndex in row) {
|
|
1443
|
-
_char = row[charIndex];
|
|
1444
|
-
fontFamily = _char.fontFamily;
|
|
1445
|
-
if (!fontList[fontFamily] && fontPaths[fontFamily]) {
|
|
1446
|
-
fontList[fontFamily] = true;
|
|
1447
|
-
}
|
|
1448
|
-
}
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
|
|
1452
|
-
for (var j in fontList) {
|
|
1453
|
-
markup += [
|
|
1454
|
-
'\t\t@font-face {\n',
|
|
1455
|
-
'\t\t\tfont-family: \'', j, '\';\n',
|
|
1456
|
-
'\t\t\tsrc: url(\'', fontPaths[j], '\');\n',
|
|
1457
|
-
'\t\t}\n'
|
|
1458
|
-
].join('');
|
|
1459
|
-
}
|
|
1460
|
-
|
|
1461
|
-
if (markup) {
|
|
1462
|
-
markup = [
|
|
1463
|
-
'\t<style type="text/css">',
|
|
1464
|
-
'<![CDATA[\n',
|
|
1465
|
-
markup,
|
|
1466
|
-
']]>',
|
|
1467
|
-
'</style>\n'
|
|
1468
|
-
].join('');
|
|
1469
|
-
}
|
|
1470
|
-
|
|
1471
|
-
return markup;
|
|
1472
|
-
},
|
|
1473
|
-
|
|
1474
|
-
/**
|
|
1475
|
-
* @private
|
|
1476
|
-
*/
|
|
1477
|
-
_setSVGObjects: function(markup, reviver) {
|
|
1478
|
-
var instance, i, len, objects = this._objects;
|
|
1479
|
-
for (i = 0, len = objects.length; i < len; i++) {
|
|
1480
|
-
instance = objects[i];
|
|
1481
|
-
if (instance.excludeFromExport) {
|
|
1482
|
-
continue;
|
|
1483
|
-
}
|
|
1484
|
-
this._setSVGObject(markup, instance, reviver);
|
|
1485
|
-
}
|
|
1486
|
-
},
|
|
1487
|
-
|
|
1488
|
-
/**
|
|
1489
|
-
* @private
|
|
1490
|
-
*/
|
|
1491
|
-
_setSVGObject: function(markup, instance, reviver) {
|
|
1492
|
-
markup.push(instance.toSVG(reviver));
|
|
1493
|
-
},
|
|
1494
|
-
|
|
1495
|
-
/**
|
|
1496
|
-
* @private
|
|
1497
|
-
*/
|
|
1498
|
-
_setSVGBgOverlayImage: function(markup, property, reviver) {
|
|
1499
|
-
if (this[property] && !this[property].excludeFromExport && this[property].toSVG) {
|
|
1500
|
-
markup.push(this[property].toSVG(reviver));
|
|
1501
|
-
}
|
|
1502
|
-
},
|
|
1503
|
-
|
|
1504
|
-
/**
|
|
1505
|
-
* @private
|
|
1506
|
-
*/
|
|
1507
|
-
_setSVGBgOverlayColor: function(markup, property) {
|
|
1508
|
-
var filler = this[property + 'Color'], vpt = this.viewportTransform, finalWidth = this.width,
|
|
1509
|
-
finalHeight = this.height;
|
|
1510
|
-
if (!filler) {
|
|
1511
|
-
return;
|
|
1512
|
-
}
|
|
1513
|
-
if (filler.toLive) {
|
|
1514
|
-
var repeat = filler.repeat, iVpt = fabric.util.invertTransform(vpt), shouldInvert = this[property + 'Vpt'],
|
|
1515
|
-
additionalTransform = shouldInvert ? fabric.util.matrixToSVG(iVpt) : '';
|
|
1516
|
-
markup.push(
|
|
1517
|
-
'<rect transform="' + additionalTransform + ' translate(', finalWidth / 2, ',', finalHeight / 2, ')"',
|
|
1518
|
-
' x="', filler.offsetX - finalWidth / 2,
|
|
1519
|
-
'" y="', filler.offsetY - finalHeight / 2, '" ',
|
|
1520
|
-
'width="',
|
|
1521
|
-
(repeat === 'repeat-y' || repeat === 'no-repeat'
|
|
1522
|
-
? filler.source.width
|
|
1523
|
-
: finalWidth ),
|
|
1524
|
-
'" height="',
|
|
1525
|
-
(repeat === 'repeat-x' || repeat === 'no-repeat'
|
|
1526
|
-
? filler.source.height
|
|
1527
|
-
: finalHeight),
|
|
1528
|
-
'" fill="url(#SVGID_' + filler.id + ')"',
|
|
1529
|
-
'></rect>\n'
|
|
1530
|
-
);
|
|
1531
|
-
}
|
|
1532
|
-
else {
|
|
1533
|
-
markup.push(
|
|
1534
|
-
'<rect x="0" y="0" width="100%" height="100%" ',
|
|
1535
|
-
'fill="', filler, '"',
|
|
1536
|
-
'></rect>\n'
|
|
1537
|
-
);
|
|
1538
|
-
}
|
|
1539
|
-
},
|
|
1540
|
-
/* _TO_SVG_END_ */
|
|
1541
|
-
|
|
1542
|
-
/**
|
|
1543
|
-
* Moves an object or the objects of a multiple selection
|
|
1544
|
-
* to the bottom of the stack of drawn objects
|
|
1545
|
-
* @param {fabric.Object} object Object to send to back
|
|
1546
|
-
* @return {fabric.Canvas} thisArg
|
|
1547
|
-
* @chainable
|
|
1548
|
-
*/
|
|
1549
|
-
sendToBack: function (object) {
|
|
1550
|
-
if (!object) {
|
|
1551
|
-
return this;
|
|
1552
|
-
}
|
|
1553
|
-
var activeSelection = this._activeObject,
|
|
1554
|
-
i, obj, objs;
|
|
1555
|
-
if (object === activeSelection && object.type === 'activeSelection') {
|
|
1556
|
-
objs = activeSelection._objects;
|
|
1557
|
-
for (i = objs.length; i--;) {
|
|
1558
|
-
obj = objs[i];
|
|
1559
|
-
removeFromArray(this._objects, obj);
|
|
1560
|
-
this._objects.unshift(obj);
|
|
1561
|
-
}
|
|
1562
|
-
}
|
|
1563
|
-
else {
|
|
1564
|
-
removeFromArray(this._objects, object);
|
|
1565
|
-
this._objects.unshift(object);
|
|
1566
|
-
}
|
|
1567
|
-
this.renderOnAddRemove && this.requestRenderAll();
|
|
1568
|
-
return this;
|
|
1569
|
-
},
|
|
1570
|
-
|
|
1571
|
-
/**
|
|
1572
|
-
* Moves an object or the objects of a multiple selection
|
|
1573
|
-
* to the top of the stack of drawn objects
|
|
1574
|
-
* @param {fabric.Object} object Object to send
|
|
1575
|
-
* @return {fabric.Canvas} thisArg
|
|
1576
|
-
* @chainable
|
|
1577
|
-
*/
|
|
1578
|
-
bringToFront: function (object) {
|
|
1579
|
-
if (!object) {
|
|
1580
|
-
return this;
|
|
1581
|
-
}
|
|
1582
|
-
var activeSelection = this._activeObject,
|
|
1583
|
-
i, obj, objs;
|
|
1584
|
-
if (object === activeSelection && object.type === 'activeSelection') {
|
|
1585
|
-
objs = activeSelection._objects;
|
|
1586
|
-
for (i = 0; i < objs.length; i++) {
|
|
1587
|
-
obj = objs[i];
|
|
1588
|
-
removeFromArray(this._objects, obj);
|
|
1589
|
-
this._objects.push(obj);
|
|
1590
|
-
}
|
|
1591
|
-
}
|
|
1592
|
-
else {
|
|
1593
|
-
removeFromArray(this._objects, object);
|
|
1594
|
-
this._objects.push(object);
|
|
1595
|
-
}
|
|
1596
|
-
this.renderOnAddRemove && this.requestRenderAll();
|
|
1597
|
-
return this;
|
|
1598
|
-
},
|
|
1599
|
-
|
|
1600
|
-
/**
|
|
1601
|
-
* Moves an object or a selection down in stack of drawn objects
|
|
1602
|
-
* An optional parameter, intersecting allows to move the object in behind
|
|
1603
|
-
* the first intersecting object. Where intersection is calculated with
|
|
1604
|
-
* bounding box. If no intersection is found, there will not be change in the
|
|
1605
|
-
* stack.
|
|
1606
|
-
* @param {fabric.Object} object Object to send
|
|
1607
|
-
* @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object
|
|
1608
|
-
* @return {fabric.Canvas} thisArg
|
|
1609
|
-
* @chainable
|
|
1610
|
-
*/
|
|
1611
|
-
sendBackwards: function (object, intersecting) {
|
|
1612
|
-
if (!object) {
|
|
1613
|
-
return this;
|
|
1614
|
-
}
|
|
1615
|
-
var activeSelection = this._activeObject,
|
|
1616
|
-
i, obj, idx, newIdx, objs, objsMoved = 0;
|
|
1617
|
-
|
|
1618
|
-
if (object === activeSelection && object.type === 'activeSelection') {
|
|
1619
|
-
objs = activeSelection._objects;
|
|
1620
|
-
for (i = 0; i < objs.length; i++) {
|
|
1621
|
-
obj = objs[i];
|
|
1622
|
-
idx = this._objects.indexOf(obj);
|
|
1623
|
-
if (idx > 0 + objsMoved) {
|
|
1624
|
-
newIdx = idx - 1;
|
|
1625
|
-
removeFromArray(this._objects, obj);
|
|
1626
|
-
this._objects.splice(newIdx, 0, obj);
|
|
1627
|
-
}
|
|
1628
|
-
objsMoved++;
|
|
1629
|
-
}
|
|
1630
|
-
}
|
|
1631
|
-
else {
|
|
1632
|
-
idx = this._objects.indexOf(object);
|
|
1633
|
-
if (idx !== 0) {
|
|
1634
|
-
// if object is not on the bottom of stack
|
|
1635
|
-
newIdx = this._findNewLowerIndex(object, idx, intersecting);
|
|
1636
|
-
removeFromArray(this._objects, object);
|
|
1637
|
-
this._objects.splice(newIdx, 0, object);
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
|
-
this.renderOnAddRemove && this.requestRenderAll();
|
|
1641
|
-
return this;
|
|
1642
|
-
},
|
|
1643
|
-
|
|
1644
|
-
/**
|
|
1645
|
-
* @private
|
|
1646
|
-
*/
|
|
1647
|
-
_findNewLowerIndex: function(object, idx, intersecting) {
|
|
1648
|
-
var newIdx, i;
|
|
1649
|
-
|
|
1650
|
-
if (intersecting) {
|
|
1651
|
-
newIdx = idx;
|
|
1652
|
-
|
|
1653
|
-
// traverse down the stack looking for the nearest intersecting object
|
|
1654
|
-
for (i = idx - 1; i >= 0; --i) {
|
|
1655
|
-
|
|
1656
|
-
var isIntersecting = object.intersectsWithObject(this._objects[i]) ||
|
|
1657
|
-
object.isContainedWithinObject(this._objects[i]) ||
|
|
1658
|
-
this._objects[i].isContainedWithinObject(object);
|
|
1659
|
-
|
|
1660
|
-
if (isIntersecting) {
|
|
1661
|
-
newIdx = i;
|
|
1662
|
-
break;
|
|
1663
|
-
}
|
|
1664
|
-
}
|
|
1665
|
-
}
|
|
1666
|
-
else {
|
|
1667
|
-
newIdx = idx - 1;
|
|
1668
|
-
}
|
|
1669
|
-
|
|
1670
|
-
return newIdx;
|
|
1671
|
-
},
|
|
1672
|
-
|
|
1673
|
-
/**
|
|
1674
|
-
* Moves an object or a selection up in stack of drawn objects
|
|
1675
|
-
* An optional parameter, intersecting allows to move the object in front
|
|
1676
|
-
* of the first intersecting object. Where intersection is calculated with
|
|
1677
|
-
* bounding box. If no intersection is found, there will not be change in the
|
|
1678
|
-
* stack.
|
|
1679
|
-
* @param {fabric.Object} object Object to send
|
|
1680
|
-
* @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object
|
|
1681
|
-
* @return {fabric.Canvas} thisArg
|
|
1682
|
-
* @chainable
|
|
1683
|
-
*/
|
|
1684
|
-
bringForward: function (object, intersecting) {
|
|
1685
|
-
if (!object) {
|
|
1686
|
-
return this;
|
|
1687
|
-
}
|
|
1688
|
-
var activeSelection = this._activeObject,
|
|
1689
|
-
i, obj, idx, newIdx, objs, objsMoved = 0;
|
|
1690
|
-
|
|
1691
|
-
if (object === activeSelection && object.type === 'activeSelection') {
|
|
1692
|
-
objs = activeSelection._objects;
|
|
1693
|
-
for (i = objs.length; i--;) {
|
|
1694
|
-
obj = objs[i];
|
|
1695
|
-
idx = this._objects.indexOf(obj);
|
|
1696
|
-
if (idx < this._objects.length - 1 - objsMoved) {
|
|
1697
|
-
newIdx = idx + 1;
|
|
1698
|
-
removeFromArray(this._objects, obj);
|
|
1699
|
-
this._objects.splice(newIdx, 0, obj);
|
|
1700
|
-
}
|
|
1701
|
-
objsMoved++;
|
|
1702
|
-
}
|
|
1703
|
-
}
|
|
1704
|
-
else {
|
|
1705
|
-
idx = this._objects.indexOf(object);
|
|
1706
|
-
if (idx !== this._objects.length - 1) {
|
|
1707
|
-
// if object is not on top of stack (last item in an array)
|
|
1708
|
-
newIdx = this._findNewUpperIndex(object, idx, intersecting);
|
|
1709
|
-
removeFromArray(this._objects, object);
|
|
1710
|
-
this._objects.splice(newIdx, 0, object);
|
|
1711
|
-
}
|
|
1712
|
-
}
|
|
1713
|
-
this.renderOnAddRemove && this.requestRenderAll();
|
|
1714
|
-
return this;
|
|
1715
|
-
},
|
|
1716
|
-
|
|
1717
|
-
/**
|
|
1718
|
-
* @private
|
|
1719
|
-
*/
|
|
1720
|
-
_findNewUpperIndex: function(object, idx, intersecting) {
|
|
1721
|
-
var newIdx, i, len;
|
|
1722
|
-
|
|
1723
|
-
if (intersecting) {
|
|
1724
|
-
newIdx = idx;
|
|
1725
|
-
|
|
1726
|
-
// traverse up the stack looking for the nearest intersecting object
|
|
1727
|
-
for (i = idx + 1, len = this._objects.length; i < len; ++i) {
|
|
1728
|
-
|
|
1729
|
-
var isIntersecting = object.intersectsWithObject(this._objects[i]) ||
|
|
1730
|
-
object.isContainedWithinObject(this._objects[i]) ||
|
|
1731
|
-
this._objects[i].isContainedWithinObject(object);
|
|
1732
|
-
|
|
1733
|
-
if (isIntersecting) {
|
|
1734
|
-
newIdx = i;
|
|
1735
|
-
break;
|
|
1736
|
-
}
|
|
1737
|
-
}
|
|
1738
|
-
}
|
|
1739
|
-
else {
|
|
1740
|
-
newIdx = idx + 1;
|
|
1741
|
-
}
|
|
1742
|
-
|
|
1743
|
-
return newIdx;
|
|
1744
|
-
},
|
|
1745
|
-
|
|
1746
|
-
/**
|
|
1747
|
-
* Moves an object to specified level in stack of drawn objects
|
|
1748
|
-
* @param {fabric.Object} object Object to send
|
|
1749
|
-
* @param {Number} index Position to move to
|
|
1750
|
-
* @return {fabric.Canvas} thisArg
|
|
1751
|
-
* @chainable
|
|
1752
|
-
*/
|
|
1753
|
-
moveTo: function (object, index) {
|
|
1754
|
-
removeFromArray(this._objects, object);
|
|
1755
|
-
this._objects.splice(index, 0, object);
|
|
1756
|
-
return this.renderOnAddRemove && this.requestRenderAll();
|
|
1757
|
-
},
|
|
1758
|
-
|
|
1759
|
-
/**
|
|
1760
|
-
* Clears a canvas element and dispose objects
|
|
1761
|
-
* @return {fabric.Canvas} thisArg
|
|
1762
|
-
* @chainable
|
|
1763
|
-
*/
|
|
1764
|
-
dispose: function () {
|
|
1765
|
-
// cancel eventually ongoing renders
|
|
1766
|
-
if (this.isRendering) {
|
|
1767
|
-
fabric.util.cancelAnimFrame(this.isRendering);
|
|
1768
|
-
this.isRendering = 0;
|
|
1769
|
-
}
|
|
1770
|
-
this.forEachObject(function(object) {
|
|
1771
|
-
object.dispose && object.dispose();
|
|
1772
|
-
});
|
|
1773
|
-
this._objects = [];
|
|
1774
|
-
if (this.backgroundImage && this.backgroundImage.dispose) {
|
|
1775
|
-
this.backgroundImage.dispose();
|
|
1776
|
-
}
|
|
1777
|
-
this.backgroundImage = null;
|
|
1778
|
-
if (this.overlayImage && this.overlayImage.dispose) {
|
|
1779
|
-
this.overlayImage.dispose();
|
|
1780
|
-
}
|
|
1781
|
-
this.overlayImage = null;
|
|
1782
|
-
this._iTextInstances = null;
|
|
1783
|
-
this.contextContainer = null;
|
|
1784
|
-
// restore canvas style
|
|
1785
|
-
this.lowerCanvasEl.classList.remove('lower-canvas');
|
|
1786
|
-
fabric.util.setStyle(this.lowerCanvasEl, this._originalCanvasStyle);
|
|
1787
|
-
delete this._originalCanvasStyle;
|
|
1788
|
-
// restore canvas size to original size in case retina scaling was applied
|
|
1789
|
-
this.lowerCanvasEl.setAttribute('width', this.width);
|
|
1790
|
-
this.lowerCanvasEl.setAttribute('height', this.height);
|
|
1791
|
-
fabric.util.cleanUpJsdomNode(this.lowerCanvasEl);
|
|
1792
|
-
this.lowerCanvasEl = undefined;
|
|
1793
|
-
return this;
|
|
1794
|
-
},
|
|
1795
|
-
|
|
1796
|
-
/**
|
|
1797
|
-
* Returns a string representation of an instance
|
|
1798
|
-
* @return {String} string representation of an instance
|
|
1799
|
-
*/
|
|
1800
|
-
toString: function () {
|
|
1801
|
-
return '#<fabric.Canvas (' + this.complexity() + '): ' +
|
|
1802
|
-
'{ objects: ' + this._objects.length + ' }>';
|
|
1803
|
-
}
|
|
1804
|
-
});
|
|
1805
|
-
|
|
1806
|
-
extend(fabric.StaticCanvas.prototype, fabric.Observable);
|
|
1807
|
-
extend(fabric.StaticCanvas.prototype, fabric.Collection);
|
|
1808
|
-
extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter);
|
|
1809
|
-
|
|
1810
|
-
extend(fabric.StaticCanvas, /** @lends fabric.StaticCanvas */ {
|
|
1811
|
-
|
|
1812
|
-
/**
|
|
1813
|
-
* @static
|
|
1814
|
-
* @type String
|
|
1815
|
-
* @default
|
|
1816
|
-
*/
|
|
1817
|
-
EMPTY_JSON: '{"objects": [], "background": "white"}',
|
|
1818
|
-
|
|
1819
|
-
/**
|
|
1820
|
-
* Provides a way to check support of some of the canvas methods
|
|
1821
|
-
* (either those of HTMLCanvasElement itself, or rendering context)
|
|
1822
|
-
*
|
|
1823
|
-
* @param {String} methodName Method to check support for;
|
|
1824
|
-
* Could be one of "setLineDash"
|
|
1825
|
-
* @return {Boolean | null} `true` if method is supported (or at least exists),
|
|
1826
|
-
* `null` if canvas element or context can not be initialized
|
|
1827
|
-
*/
|
|
1828
|
-
supports: function (methodName) {
|
|
1829
|
-
var el = createCanvasElement();
|
|
1830
|
-
|
|
1831
|
-
if (!el || !el.getContext) {
|
|
1832
|
-
return null;
|
|
1833
|
-
}
|
|
1834
|
-
|
|
1835
|
-
var ctx = el.getContext('2d');
|
|
1836
|
-
if (!ctx) {
|
|
1837
|
-
return null;
|
|
1838
|
-
}
|
|
1839
|
-
|
|
1840
|
-
switch (methodName) {
|
|
1841
|
-
|
|
1842
|
-
case 'setLineDash':
|
|
1843
|
-
return typeof ctx.setLineDash !== 'undefined';
|
|
1844
|
-
|
|
1845
|
-
default:
|
|
1846
|
-
return null;
|
|
1847
|
-
}
|
|
1848
|
-
}
|
|
1849
|
-
});
|
|
1850
|
-
|
|
1851
|
-
/**
|
|
1852
|
-
* Returns Object representation of canvas
|
|
1853
|
-
* this alias is provided because if you call JSON.stringify on an instance,
|
|
1854
|
-
* the toJSON object will be invoked if it exists.
|
|
1855
|
-
* Having a toJSON method means you can do JSON.stringify(myCanvas)
|
|
1856
|
-
* @function
|
|
1857
|
-
* @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
|
|
1858
|
-
* @return {Object} JSON compatible object
|
|
1859
|
-
* @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}
|
|
1860
|
-
* @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo}
|
|
1861
|
-
* @example <caption>JSON without additional properties</caption>
|
|
1862
|
-
* var json = canvas.toJSON();
|
|
1863
|
-
* @example <caption>JSON with additional properties included</caption>
|
|
1864
|
-
* var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY']);
|
|
1865
|
-
* @example <caption>JSON without default values</caption>
|
|
1866
|
-
* canvas.includeDefaultValues = false;
|
|
1867
|
-
* var json = canvas.toJSON();
|
|
1868
|
-
*/
|
|
1869
|
-
fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject;
|
|
1870
|
-
|
|
1871
|
-
if (fabric.isLikelyNode) {
|
|
1872
|
-
fabric.StaticCanvas.prototype.createPNGStream = function() {
|
|
1873
|
-
var impl = getNodeCanvas(this.lowerCanvasEl);
|
|
1874
|
-
return impl && impl.createPNGStream();
|
|
1875
|
-
};
|
|
1876
|
-
fabric.StaticCanvas.prototype.createJPEGStream = function(opts) {
|
|
1877
|
-
var impl = getNodeCanvas(this.lowerCanvasEl);
|
|
1878
|
-
return impl && impl.createJPEGStream(opts);
|
|
1879
|
-
};
|
|
1880
|
-
}
|
|
1881
|
-
})();
|