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.
Files changed (604) hide show
  1. package/.babelrc +11 -0
  2. package/.babelrcAlt +19 -0
  3. package/.browserslistrc +5 -0
  4. package/.eslintignore +3 -0
  5. package/.eslintrc.js +43 -0
  6. package/.eslintrc.json +38 -46
  7. package/.eslintrc_tests +12 -0
  8. package/.gitattributes +2 -0
  9. package/.gitpod.yml +17 -1
  10. package/.prettierignore +19 -0
  11. package/.prettierrc +4 -0
  12. package/CHANGELOG.md +532 -189
  13. package/CONTRIBUTING.md +224 -59
  14. package/README.md +200 -235
  15. package/bower.json +1 -3
  16. package/dist/fabric.d.ts +42 -0
  17. package/dist/index.d.ts +2 -0
  18. package/dist/index.js +27582 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/index.min.js +1 -0
  21. package/dist/index.mjs +27519 -0
  22. package/dist/index.mjs.map +1 -0
  23. package/dist/index.node.cjs +27663 -0
  24. package/dist/index.node.cjs.map +1 -0
  25. package/dist/index.node.d.ts +14 -0
  26. package/dist/index.node.mjs +27606 -0
  27. package/dist/index.node.mjs.map +1 -0
  28. package/dist/src/ClassRegistry.d.ts +13 -0
  29. package/dist/src/Collection.d.ts +136 -0
  30. package/dist/src/CommonMethods.d.ts +32 -0
  31. package/dist/src/EventTypeDefs.d.ts +227 -0
  32. package/dist/src/Intersection.d.ts +112 -0
  33. package/dist/src/Observable.d.ts +60 -0
  34. package/dist/src/Pattern.d.ts +113 -0
  35. package/dist/src/Point.d.ts +232 -0
  36. package/dist/src/Shadow.d.ts +97 -0
  37. package/dist/src/brushes/BaseBrush.d.ts +105 -0
  38. package/dist/src/brushes/CircleBrush.d.ts +49 -0
  39. package/dist/src/brushes/PatternBrush.d.ts +23 -0
  40. package/dist/src/brushes/PencilBrush.d.ts +92 -0
  41. package/dist/src/brushes/SprayBrush.d.ts +79 -0
  42. package/dist/src/cache.d.ts +47 -0
  43. package/dist/src/canvas/Canvas.d.ts +548 -0
  44. package/dist/src/canvas/SelectableCanvas.d.ts +754 -0
  45. package/dist/src/canvas/StaticCanvas.d.ts +778 -0
  46. package/dist/src/canvas/TextEditingManager.d.ts +17 -0
  47. package/dist/src/canvas/canvas_gestures.mixin.d.ts +2 -0
  48. package/dist/src/color/Color.d.ts +174 -0
  49. package/dist/src/color/color_map.d.ts +155 -0
  50. package/dist/src/color/constants.d.ts +22 -0
  51. package/dist/src/color/util.d.ts +12 -0
  52. package/dist/src/config.d.ts +115 -0
  53. package/dist/src/constants.d.ts +14 -0
  54. package/dist/src/controls/Control.d.ts +228 -0
  55. package/dist/src/controls/changeWidth.d.ts +13 -0
  56. package/dist/src/controls/commonControls.d.ts +28 -0
  57. package/dist/src/controls/controlRendering.d.ts +29 -0
  58. package/dist/src/controls/drag.d.ts +12 -0
  59. package/dist/src/controls/index.d.ts +13 -0
  60. package/dist/src/controls/polyControl.d.ts +5 -0
  61. package/dist/src/controls/rotate.d.ts +12 -0
  62. package/dist/src/controls/scale.d.ts +47 -0
  63. package/dist/src/controls/scaleSkew.d.ts +39 -0
  64. package/dist/src/controls/skew.d.ts +33 -0
  65. package/dist/src/controls/util.d.ts +41 -0
  66. package/dist/src/controls/wrapWithFireEvent.d.ts +8 -0
  67. package/dist/src/controls/wrapWithFixedAnchor.d.ts +9 -0
  68. package/dist/src/env/browser.d.ts +3 -0
  69. package/dist/src/env/index.d.ts +15 -0
  70. package/dist/src/env/node.d.ts +5 -0
  71. package/dist/src/env/types.d.ts +15 -0
  72. package/dist/src/filters/BaseFilter.d.ts +153 -0
  73. package/dist/src/filters/BlendColor.d.ts +80 -0
  74. package/dist/src/filters/BlendImage.d.ts +92 -0
  75. package/dist/src/filters/Blur.d.ts +51 -0
  76. package/dist/src/filters/Boilerplate.d.ts +48 -0
  77. package/dist/src/filters/Brightness.d.ts +47 -0
  78. package/dist/src/filters/Canvas2dFilterBackend.d.ts +27 -0
  79. package/dist/src/filters/ColorMatrix.d.ts +63 -0
  80. package/dist/src/filters/ColorMatrixFilters.d.ts +545 -0
  81. package/dist/src/filters/Composed.d.ts +45 -0
  82. package/dist/src/filters/Contrast.d.ts +45 -0
  83. package/dist/src/filters/Convolute.d.ts +82 -0
  84. package/dist/src/filters/FilterBackend.d.ts +14 -0
  85. package/dist/src/filters/GLProbes/GLProbe.d.ts +11 -0
  86. package/dist/src/filters/GLProbes/NodeGLProbe.d.ts +11 -0
  87. package/dist/src/filters/GLProbes/WebGLProbe.d.ts +20 -0
  88. package/dist/src/filters/Gamma.d.ts +54 -0
  89. package/dist/src/filters/Grayscale.d.ts +46 -0
  90. package/dist/src/filters/HueRotation.d.ts +24 -0
  91. package/dist/src/filters/Invert.d.ts +55 -0
  92. package/dist/src/filters/Noise.d.ts +54 -0
  93. package/dist/src/filters/Pixelate.d.ts +44 -0
  94. package/dist/src/filters/RemoveColor.d.ts +63 -0
  95. package/dist/src/filters/Resize.d.ts +136 -0
  96. package/dist/src/filters/Saturation.d.ts +48 -0
  97. package/dist/src/filters/Vibrance.d.ts +48 -0
  98. package/dist/src/filters/WebGLFilterBackend.d.ts +126 -0
  99. package/dist/src/filters/filters.d.ts +21 -0
  100. package/dist/src/filters/index.d.ts +5 -0
  101. package/dist/src/filters/shaders/baseFilter.d.ts +4 -0
  102. package/dist/src/filters/shaders/blendColor.d.ts +13 -0
  103. package/dist/src/filters/shaders/blendImage.d.ts +3 -0
  104. package/dist/src/filters/shaders/blur.d.ts +2 -0
  105. package/dist/src/filters/shaders/brightness.d.ts +2 -0
  106. package/dist/src/filters/shaders/colorMatrix.d.ts +2 -0
  107. package/dist/src/filters/shaders/constrast.d.ts +2 -0
  108. package/dist/src/filters/shaders/convolute.d.ts +11 -0
  109. package/dist/src/filters/shaders/gamma.d.ts +2 -0
  110. package/dist/src/filters/shaders/grayscale.d.ts +3 -0
  111. package/dist/src/filters/shaders/invert.d.ts +2 -0
  112. package/dist/src/filters/shaders/noise.d.ts +2 -0
  113. package/dist/src/filters/shaders/pixelate.d.ts +2 -0
  114. package/dist/src/filters/shaders/removeColor.d.ts +2 -0
  115. package/dist/src/filters/shaders/saturation.d.ts +2 -0
  116. package/dist/src/filters/shaders/vibrance.d.ts +2 -0
  117. package/dist/src/filters/typedefs.d.ts +49 -0
  118. package/dist/src/gradient/Gradient.d.ts +149 -0
  119. package/dist/src/gradient/constants.d.ts +15 -0
  120. package/dist/src/gradient/parser/index.d.ts +4 -0
  121. package/dist/src/gradient/parser/misc.d.ts +4 -0
  122. package/dist/src/gradient/parser/parseColorStops.d.ts +3 -0
  123. package/dist/src/gradient/parser/parseCoords.d.ts +17 -0
  124. package/dist/src/gradient/typedefs.d.ts +93 -0
  125. package/dist/src/mixins/eraser_brush.mixin.d.ts +2 -0
  126. package/dist/src/parkinglot/canvas_animation.mixin.d.ts +2 -0
  127. package/dist/src/parkinglot/straighten.d.ts +2 -0
  128. package/dist/src/parser/applyViewboxTransform.d.ts +5 -0
  129. package/dist/src/parser/attributes.d.ts +6 -0
  130. package/dist/src/parser/constants.d.ts +53 -0
  131. package/dist/src/parser/doesSomeParentMatch.d.ts +2 -0
  132. package/dist/src/parser/elementById.d.ts +6 -0
  133. package/dist/src/parser/elementMatchesRule.d.ts +5 -0
  134. package/dist/src/parser/elements_parser.d.ts +3 -0
  135. package/dist/src/parser/getCSSRules.d.ts +7 -0
  136. package/dist/src/parser/getGlobalStylesForElement.d.ts +5 -0
  137. package/dist/src/parser/getGradientDefs.d.ts +7 -0
  138. package/dist/src/parser/getMultipleNodes.d.ts +2 -0
  139. package/dist/src/parser/getSvgRegex.d.ts +2 -0
  140. package/dist/src/parser/hasAncestorWithNodeName.d.ts +2 -0
  141. package/dist/src/parser/index.d.ts +10 -0
  142. package/dist/src/parser/loadSVGFromString.d.ts +12 -0
  143. package/dist/src/parser/loadSVGFromURL.d.ts +13 -0
  144. package/dist/src/parser/normalizeAttr.d.ts +2 -0
  145. package/dist/src/parser/normalizeValue.d.ts +2 -0
  146. package/dist/src/parser/parseAttributes.d.ts +9 -0
  147. package/dist/src/parser/parseElements.d.ts +11 -0
  148. package/dist/src/parser/parseFontDeclaration.d.ts +10 -0
  149. package/dist/src/parser/parsePointsAttribute.d.ts +12 -0
  150. package/dist/src/parser/parseSVGDocument.d.ts +15 -0
  151. package/dist/src/parser/parseStyleAttribute.d.ts +9 -0
  152. package/dist/src/parser/parseStyleObject.d.ts +2 -0
  153. package/dist/src/parser/parseStyleString.d.ts +2 -0
  154. package/dist/src/parser/parseTransformAttribute.d.ts +10 -0
  155. package/dist/src/parser/parseUseDirectives.d.ts +2 -0
  156. package/dist/src/parser/percent.d.ts +9 -0
  157. package/dist/src/parser/recursivelyParseGradientsXlink.d.ts +2 -0
  158. package/dist/src/parser/rotateMatrix.d.ts +2 -0
  159. package/dist/src/parser/scaleMatrix.d.ts +2 -0
  160. package/dist/src/parser/selectorMatches.d.ts +2 -0
  161. package/dist/src/parser/setStrokeFillOpacity.d.ts +6 -0
  162. package/dist/src/parser/skewMatrix.d.ts +2 -0
  163. package/dist/src/parser/translateMatrix.d.ts +2 -0
  164. package/dist/src/shapes/ActiveSelection.d.ts +82 -0
  165. package/dist/src/shapes/Circle.d.ts +99 -0
  166. package/dist/src/shapes/Ellipse.d.ts +84 -0
  167. package/dist/src/shapes/Group.d.ts +408 -0
  168. package/dist/src/shapes/IText/DraggableTextDelegate.d.ts +78 -0
  169. package/dist/src/shapes/IText/IText.d.ts +335 -0
  170. package/dist/src/shapes/IText/ITextBehavior.d.ts +287 -0
  171. package/dist/src/shapes/IText/ITextClickBehavior.d.ts +83 -0
  172. package/dist/src/shapes/IText/ITextKeyBehavior.d.ts +195 -0
  173. package/dist/src/shapes/IText/constants.d.ts +13 -0
  174. package/dist/src/shapes/Image.d.ts +311 -0
  175. package/dist/src/shapes/Line.d.ts +126 -0
  176. package/dist/src/shapes/Object/AnimatableObject.d.ts +33 -0
  177. package/dist/src/shapes/Object/FabricObject.d.ts +11 -0
  178. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.d.ts +74 -0
  179. package/dist/src/shapes/Object/InteractiveObject.d.ts +296 -0
  180. package/dist/src/shapes/Object/Object.d.ts +594 -0
  181. package/dist/src/shapes/Object/ObjectGeometry.d.ts +327 -0
  182. package/dist/src/shapes/Object/ObjectOrigin.d.ts +109 -0
  183. package/dist/src/shapes/Object/StackedObject.d.ts +72 -0
  184. package/dist/src/shapes/Object/defaultValues.d.ts +76 -0
  185. package/dist/src/shapes/Object/types/BaseProps.d.ts +84 -0
  186. package/dist/src/shapes/Object/types/BorderProps.d.ts +37 -0
  187. package/dist/src/shapes/Object/types/ControlProps.d.ts +62 -0
  188. package/dist/src/shapes/Object/types/FabricObjectProps.d.ts +96 -0
  189. package/dist/src/shapes/Object/types/FillStrokeProps.d.ts +80 -0
  190. package/dist/src/shapes/Object/types/LockInteractionProps.d.ts +51 -0
  191. package/dist/src/shapes/Object/types/ObjectProps.d.ts +42 -0
  192. package/dist/src/shapes/Object/types/SerializedObjectProps.d.ts +66 -0
  193. package/dist/src/shapes/Object/types/index.d.ts +6 -0
  194. package/dist/src/shapes/Path.d.ts +130 -0
  195. package/dist/src/shapes/Polygon.d.ts +9 -0
  196. package/dist/src/shapes/Polyline.d.ts +140 -0
  197. package/dist/src/shapes/Rect.d.ts +76 -0
  198. package/dist/src/shapes/Text/StyledText.d.ts +119 -0
  199. package/dist/src/shapes/Text/Text.d.ts +673 -0
  200. package/dist/src/shapes/Text/TextSVGExportMixin.d.ts +32 -0
  201. package/dist/src/shapes/Text/constants.d.ts +7 -0
  202. package/dist/src/shapes/Textbox.d.ts +185 -0
  203. package/dist/src/shapes/Triangle.d.ts +25 -0
  204. package/dist/src/typedefs.d.ts +90 -0
  205. package/dist/src/util/animation/AnimationBase.d.ts +54 -0
  206. package/dist/src/util/animation/AnimationFrameProvider.d.ts +3 -0
  207. package/dist/src/util/animation/AnimationRegistry.d.ts +29 -0
  208. package/dist/src/util/animation/ArrayAnimation.d.ts +10 -0
  209. package/dist/src/util/animation/ColorAnimation.d.ts +11 -0
  210. package/dist/src/util/animation/ValueAnimation.d.ts +10 -0
  211. package/dist/src/util/animation/animate.d.ts +37 -0
  212. package/dist/src/util/animation/easing.d.ts +130 -0
  213. package/dist/src/util/animation/types.d.ts +87 -0
  214. package/dist/src/util/applyMixins.d.ts +8 -0
  215. package/dist/src/util/dom_event.d.ts +5 -0
  216. package/dist/src/util/dom_misc.d.ts +39 -0
  217. package/dist/src/util/dom_request.d.ts +14 -0
  218. package/dist/src/util/dom_style.d.ts +7 -0
  219. package/dist/src/util/fireEvent.d.ts +3 -0
  220. package/dist/src/util/index.d.ts +35 -0
  221. package/dist/src/util/internals/cloneDeep.d.ts +2 -0
  222. package/dist/src/util/internals/getRandomInt.d.ts +8 -0
  223. package/dist/src/util/internals/ifNaN.d.ts +8 -0
  224. package/dist/src/util/internals/index.d.ts +4 -0
  225. package/dist/src/util/internals/removeFromArray.d.ts +9 -0
  226. package/dist/src/util/internals/uid.d.ts +2 -0
  227. package/dist/src/util/lang_string.d.ts +22 -0
  228. package/dist/src/util/misc/boundingBoxFromPoints.d.ts +9 -0
  229. package/dist/src/util/misc/capValue.d.ts +2 -0
  230. package/dist/src/util/misc/cos.d.ts +10 -0
  231. package/dist/src/util/misc/dom.d.ts +28 -0
  232. package/dist/src/util/misc/findScaleTo.d.ts +29 -0
  233. package/dist/src/util/misc/groupSVGElements.d.ts +9 -0
  234. package/dist/src/util/misc/isTransparent.d.ts +11 -0
  235. package/dist/src/util/misc/matrix.d.ts +92 -0
  236. package/dist/src/util/misc/mergeClipPaths.d.ts +23 -0
  237. package/dist/src/util/misc/objectEnlive.d.ts +56 -0
  238. package/dist/src/util/misc/objectTransforms.d.ts +68 -0
  239. package/dist/src/util/misc/pick.d.ts +9 -0
  240. package/dist/src/util/misc/planeChange.d.ts +84 -0
  241. package/dist/src/util/misc/projectStroke/StrokeLineCapProjections.d.ts +51 -0
  242. package/dist/src/util/misc/projectStroke/StrokeLineJoinProjections.d.ts +81 -0
  243. package/dist/src/util/misc/projectStroke/StrokeProjectionsBase.d.ts +25 -0
  244. package/dist/src/util/misc/projectStroke/index.d.ts +11 -0
  245. package/dist/src/util/misc/projectStroke/types.d.ts +23 -0
  246. package/dist/src/util/misc/radiansDegreesConversion.d.ts +14 -0
  247. package/dist/src/util/misc/resolveOrigin.d.ts +9 -0
  248. package/dist/src/util/misc/rotatePoint.d.ts +12 -0
  249. package/dist/src/util/misc/sin.d.ts +10 -0
  250. package/dist/src/util/misc/svgParsing.d.ts +53 -0
  251. package/dist/src/util/misc/textStyles.d.ts +32 -0
  252. package/dist/src/util/misc/toFixed.d.ts +8 -0
  253. package/dist/src/util/misc/vectors.d.ts +57 -0
  254. package/dist/src/util/path/index.d.ts +96 -0
  255. package/dist/src/util/path/regex.d.ts +3 -0
  256. package/dist/src/util/path/typechecks.d.ts +24 -0
  257. package/dist/src/util/path/typedefs.d.ts +220 -0
  258. package/dist/src/util/transform_matrix_removal.d.ts +14 -0
  259. package/dist/src/util/types.d.ts +19 -0
  260. package/fabric.ts +51 -0
  261. package/index.node.ts +37 -0
  262. package/index.ts +1 -0
  263. package/package.json +100 -40
  264. package/publish.js +0 -26
  265. package/rollup.config.mjs +91 -0
  266. package/rollup.test.config.js +24 -0
  267. package/scripts/build.mjs +50 -0
  268. package/scripts/buildLock.mjs +115 -0
  269. package/scripts/buildReporter.mjs +15 -0
  270. package/scripts/buildStats.mjs +139 -0
  271. package/scripts/dirname.mjs +14 -0
  272. package/scripts/git.mjs +36 -0
  273. package/scripts/index.mjs +564 -0
  274. package/scripts/sandbox.mjs +149 -0
  275. package/src/ClassRegistry.ts +56 -0
  276. package/src/Collection.ts +346 -0
  277. package/src/CommonMethods.ts +63 -0
  278. package/src/EventTypeDefs.ts +296 -0
  279. package/src/Intersection.ts +302 -0
  280. package/src/Observable.ts +181 -0
  281. package/src/Pattern.ts +227 -0
  282. package/src/Point.ts +388 -0
  283. package/src/Shadow.ts +214 -0
  284. package/src/brushes/{base_brush.class.js → BaseBrush.ts} +65 -42
  285. package/src/brushes/CircleBrush.ts +145 -0
  286. package/src/brushes/PatternBrush.ts +70 -0
  287. package/src/brushes/PencilBrush.ts +300 -0
  288. package/src/brushes/SprayBrush.ts +219 -0
  289. package/src/cache.ts +90 -0
  290. package/src/canvas/Canvas.ts +1607 -0
  291. package/src/canvas/SelectableCanvas.ts +1608 -0
  292. package/src/canvas/StaticCanvas.ts +1734 -0
  293. package/src/canvas/TextEditingManager.ts +48 -0
  294. package/src/canvas/canvas_gestures.mixin.ts +207 -0
  295. package/src/color/Color.ts +404 -0
  296. package/src/color/color_map.ts +154 -0
  297. package/src/color/constants.ts +26 -0
  298. package/src/color/util.ts +32 -0
  299. package/src/config.ts +159 -0
  300. package/src/constants.ts +20 -0
  301. package/src/controls/Control.ts +380 -0
  302. package/src/controls/changeWidth.ts +52 -0
  303. package/src/controls/commonControls.ts +105 -0
  304. package/src/controls/controlRendering.ts +138 -0
  305. package/src/controls/drag.ts +31 -0
  306. package/src/controls/index.ts +22 -0
  307. package/src/controls/polyControl.ts +135 -0
  308. package/src/controls/rotate.ts +87 -0
  309. package/src/controls/scale.ts +277 -0
  310. package/src/controls/scaleSkew.ts +92 -0
  311. package/src/controls/skew.ts +242 -0
  312. package/src/controls/util.ts +154 -0
  313. package/src/controls/wrapWithFireEvent.ts +25 -0
  314. package/src/controls/wrapWithFixedAnchor.ts +20 -0
  315. package/src/env/browser.ts +32 -0
  316. package/src/env/index.ts +24 -0
  317. package/src/env/node.ts +56 -0
  318. package/src/env/types.ts +15 -0
  319. package/src/filters/{base_filter.class.js → BaseFilter.ts} +192 -151
  320. package/src/filters/BlendColor.ts +217 -0
  321. package/src/filters/BlendImage.ts +228 -0
  322. package/src/filters/Blur.ts +179 -0
  323. package/src/filters/Boilerplate.ts +94 -0
  324. package/src/filters/Brightness.ts +83 -0
  325. package/src/filters/Canvas2dFilterBackend.ts +65 -0
  326. package/src/filters/ColorMatrix.ts +145 -0
  327. package/src/filters/ColorMatrixFilters.ts +77 -0
  328. package/src/filters/Composed.ts +76 -0
  329. package/src/filters/Contrast.ts +82 -0
  330. package/src/filters/Convolute.ts +184 -0
  331. package/src/filters/FilterBackend.ts +34 -0
  332. package/src/filters/GLProbes/GLProbe.ts +11 -0
  333. package/src/filters/GLProbes/NodeGLProbe.ts +15 -0
  334. package/src/filters/GLProbes/WebGLProbe.ts +46 -0
  335. package/src/filters/Gamma.ts +110 -0
  336. package/src/filters/Grayscale.ts +102 -0
  337. package/src/filters/HueRotation.ts +62 -0
  338. package/src/filters/Invert.ts +99 -0
  339. package/src/filters/Noise.ts +94 -0
  340. package/src/filters/Pixelate.ts +96 -0
  341. package/src/filters/RemoveColor.ts +135 -0
  342. package/src/filters/Resize.ts +538 -0
  343. package/src/filters/Saturation.ts +87 -0
  344. package/src/filters/Vibrance.ts +88 -0
  345. package/src/filters/WebGLFilterBackend.ts +430 -0
  346. package/src/filters/filters.ts +28 -0
  347. package/src/filters/index.ts +5 -0
  348. package/src/filters/shaders/baseFilter.ts +19 -0
  349. package/src/filters/shaders/blendColor.ts +33 -0
  350. package/src/filters/shaders/blendImage.ts +32 -0
  351. package/src/filters/shaders/blur.ts +24 -0
  352. package/src/filters/shaders/brightness.ts +11 -0
  353. package/src/filters/shaders/colorMatrix.ts +12 -0
  354. package/src/filters/shaders/constrast.ts +11 -0
  355. package/src/filters/shaders/convolute.ts +154 -0
  356. package/src/filters/shaders/gamma.ts +15 -0
  357. package/src/filters/shaders/grayscale.ts +36 -0
  358. package/src/filters/shaders/invert.ts +19 -0
  359. package/src/filters/shaders/noise.ts +16 -0
  360. package/src/filters/shaders/pixelate.ts +19 -0
  361. package/src/filters/shaders/removeColor.ts +13 -0
  362. package/src/filters/shaders/saturation.ts +15 -0
  363. package/src/filters/shaders/vibrance.ts +16 -0
  364. package/src/filters/typedefs.ts +65 -0
  365. package/src/gradient/Gradient.ts +406 -0
  366. package/src/gradient/constants.ts +12 -0
  367. package/src/gradient/parser/index.ts +3 -0
  368. package/src/gradient/parser/misc.ts +13 -0
  369. package/src/gradient/parser/parseColorStops.ts +56 -0
  370. package/src/gradient/parser/parseCoords.ts +73 -0
  371. package/src/gradient/typedefs.ts +104 -0
  372. package/src/mixins/{eraser_brush.mixin.js → eraser_brush.mixin.ts} +350 -239
  373. package/src/parkinglot/canvas_animation.mixin.ts +121 -0
  374. package/src/parkinglot/straighten.ts +58 -0
  375. package/src/parser/applyViewboxTransform.ts +157 -0
  376. package/src/parser/attributes.ts +25 -0
  377. package/src/parser/constants.ts +115 -0
  378. package/src/parser/doesSomeParentMatch.ts +19 -0
  379. package/src/parser/elementById.ts +21 -0
  380. package/src/parser/elementMatchesRule.ts +16 -0
  381. package/src/parser/elements_parser.ts +191 -0
  382. package/src/parser/getCSSRules.ts +62 -0
  383. package/src/parser/getGlobalStylesForElement.ts +19 -0
  384. package/src/parser/getGradientDefs.ts +31 -0
  385. package/src/parser/getMultipleNodes.ts +15 -0
  386. package/src/parser/getSvgRegex.ts +5 -0
  387. package/src/parser/hasAncestorWithNodeName.ts +14 -0
  388. package/src/parser/index.ts +9 -0
  389. package/src/parser/loadSVGFromString.ts +26 -0
  390. package/src/parser/loadSVGFromURL.ts +40 -0
  391. package/src/parser/normalizeAttr.ts +10 -0
  392. package/src/parser/normalizeValue.ts +63 -0
  393. package/src/parser/parseAttributes.ts +90 -0
  394. package/src/parser/parseElements.ts +28 -0
  395. package/src/parser/parseFontDeclaration.ts +44 -0
  396. package/src/parser/parsePointsAttribute.ts +34 -0
  397. package/src/parser/parseSVGDocument.ts +93 -0
  398. package/src/parser/parseStyleAttribute.ts +27 -0
  399. package/src/parser/parseStyleObject.ts +15 -0
  400. package/src/parser/parseStyleString.ts +16 -0
  401. package/src/parser/parseTransformAttribute.ts +155 -0
  402. package/src/parser/parseUseDirectives.ts +78 -0
  403. package/src/parser/percent.ts +27 -0
  404. package/src/parser/recursivelyParseGradientsXlink.ts +42 -0
  405. package/src/parser/rotateMatrix.ts +21 -0
  406. package/src/parser/scaleMatrix.ts +9 -0
  407. package/src/parser/selectorMatches.ts +25 -0
  408. package/src/parser/setStrokeFillOpacity.ts +40 -0
  409. package/src/parser/skewMatrix.ts +6 -0
  410. package/src/parser/translateMatrix.ts +8 -0
  411. package/src/shapes/ActiveSelection.ts +189 -0
  412. package/src/shapes/Circle.ts +242 -0
  413. package/src/shapes/Ellipse.ts +179 -0
  414. package/src/shapes/Group.ts +1100 -0
  415. package/src/shapes/IText/DraggableTextDelegate.ts +382 -0
  416. package/src/shapes/IText/IText.ts +693 -0
  417. package/src/shapes/IText/ITextBehavior.ts +1064 -0
  418. package/src/shapes/IText/ITextClickBehavior.ts +325 -0
  419. package/src/shapes/IText/ITextKeyBehavior.ts +685 -0
  420. package/src/shapes/IText/constants.ts +47 -0
  421. package/src/shapes/Image.ts +841 -0
  422. package/src/shapes/Line.ts +346 -0
  423. package/src/shapes/Object/AnimatableObject.ts +106 -0
  424. package/src/shapes/Object/FabricObject.ts +29 -0
  425. package/src/shapes/Object/FabricObjectSVGExportMixin.ts +277 -0
  426. package/src/shapes/Object/InteractiveObject.ts +672 -0
  427. package/src/shapes/Object/Object.ts +1561 -0
  428. package/src/shapes/Object/ObjectGeometry.ts +813 -0
  429. package/src/shapes/Object/ObjectOrigin.ts +276 -0
  430. package/src/shapes/Object/StackedObject.ts +206 -0
  431. package/src/shapes/Object/defaultValues.ts +108 -0
  432. package/src/shapes/Object/types/BaseProps.ts +96 -0
  433. package/src/shapes/Object/types/BorderProps.ts +40 -0
  434. package/src/shapes/Object/types/ControlProps.ts +69 -0
  435. package/src/shapes/Object/types/FabricObjectProps.ts +111 -0
  436. package/src/shapes/Object/types/FillStrokeProps.ts +90 -0
  437. package/src/shapes/Object/types/LockInteractionProps.ts +57 -0
  438. package/src/shapes/Object/types/ObjectProps.ts +46 -0
  439. package/src/shapes/Object/types/SerializedObjectProps.ts +73 -0
  440. package/src/shapes/Object/types/index.ts +8 -0
  441. package/src/shapes/Path.ts +416 -0
  442. package/src/shapes/Polygon.ts +20 -0
  443. package/src/shapes/Polyline.ts +359 -0
  444. package/src/shapes/Rect.ts +233 -0
  445. package/src/shapes/Text/StyledText.ts +329 -0
  446. package/src/shapes/Text/Text.ts +1884 -0
  447. package/src/shapes/Text/TextSVGExportMixin.ts +288 -0
  448. package/src/shapes/Text/constants.ts +91 -0
  449. package/src/shapes/Textbox.ts +477 -0
  450. package/src/shapes/Triangle.ts +60 -0
  451. package/src/typedefs.ts +115 -0
  452. package/src/util/animation/AnimationBase.ts +166 -0
  453. package/src/util/animation/AnimationFrameProvider.ts +9 -0
  454. package/src/util/animation/AnimationRegistry.ts +58 -0
  455. package/src/util/animation/ArrayAnimation.ts +27 -0
  456. package/src/util/animation/ColorAnimation.ts +74 -0
  457. package/src/util/animation/ValueAnimation.ts +29 -0
  458. package/src/util/animation/animate.ts +74 -0
  459. package/src/util/animation/easing.ts +327 -0
  460. package/src/util/animation/types.ts +136 -0
  461. package/src/util/applyMixins.ts +22 -0
  462. package/src/util/dom_event.ts +28 -0
  463. package/src/util/dom_misc.ts +121 -0
  464. package/src/util/dom_request.ts +64 -0
  465. package/src/util/dom_style.ts +20 -0
  466. package/src/util/fireEvent.ts +15 -0
  467. package/src/util/index.ts +102 -0
  468. package/src/util/internals/cloneDeep.ts +2 -0
  469. package/src/util/internals/getRandomInt.ts +8 -0
  470. package/src/util/internals/ifNaN.ts +9 -0
  471. package/src/util/internals/index.ts +3 -0
  472. package/src/util/internals/removeFromArray.ts +14 -0
  473. package/src/util/internals/uid.ts +3 -0
  474. package/src/util/lang_string.ts +79 -0
  475. package/src/util/misc/boundingBoxFromPoints.ts +37 -0
  476. package/src/util/misc/capValue.ts +2 -0
  477. package/src/util/misc/cos.ts +24 -0
  478. package/src/util/misc/dom.ts +50 -0
  479. package/src/util/misc/findScaleTo.ts +44 -0
  480. package/src/util/misc/groupSVGElements.ts +15 -0
  481. package/src/util/misc/isTransparent.ts +28 -0
  482. package/src/util/misc/matrix.ts +207 -0
  483. package/src/util/misc/mergeClipPaths.ts +40 -0
  484. package/src/util/misc/objectEnlive.ts +189 -0
  485. package/src/util/misc/objectTransforms.ts +129 -0
  486. package/src/util/misc/pick.ts +29 -0
  487. package/src/util/misc/planeChange.ts +136 -0
  488. package/src/util/misc/projectStroke/StrokeLineCapProjections.ts +112 -0
  489. package/src/util/misc/projectStroke/StrokeLineJoinProjections.ts +226 -0
  490. package/src/util/misc/projectStroke/StrokeProjectionsBase.ts +75 -0
  491. package/src/util/misc/projectStroke/index.ts +53 -0
  492. package/src/util/misc/projectStroke/types.ts +24 -0
  493. package/src/util/misc/radiansDegreesConversion.ts +18 -0
  494. package/src/util/misc/resolveOrigin.ts +22 -0
  495. package/src/util/misc/rotatePoint.ts +15 -0
  496. package/src/util/misc/sin.ts +26 -0
  497. package/src/util/misc/svgParsing.ts +181 -0
  498. package/src/util/misc/textStyles.ts +134 -0
  499. package/src/util/misc/toFixed.ts +8 -0
  500. package/src/util/misc/vectors.ts +82 -0
  501. package/src/util/path/index.ts +1038 -0
  502. package/src/util/path/regex.ts +41 -0
  503. package/src/util/path/typechecks.ts +145 -0
  504. package/src/util/path/typedefs.ts +305 -0
  505. package/src/util/transform_matrix_removal.ts +60 -0
  506. package/src/util/types.ts +78 -0
  507. package/tsconfig.json +106 -0
  508. package/HEADER.js +0 -203
  509. package/build.js +0 -287
  510. package/dist/fabric.js +0 -31187
  511. package/dist/fabric.min.js +0 -1
  512. package/old-travis-reference.yml +0 -97
  513. package/src/brushes/circle_brush.class.js +0 -144
  514. package/src/brushes/pattern_brush.class.js +0 -61
  515. package/src/brushes/pencil_brush.class.js +0 -310
  516. package/src/brushes/spray_brush.class.js +0 -219
  517. package/src/canvas.class.js +0 -1312
  518. package/src/color.class.js +0 -636
  519. package/src/control.class.js +0 -339
  520. package/src/controls.actions.js +0 -740
  521. package/src/controls.render.js +0 -99
  522. package/src/elements_parser.js +0 -152
  523. package/src/filters/2d_backend.class.js +0 -65
  524. package/src/filters/blendcolor_filter.class.js +0 -251
  525. package/src/filters/blendimage_filter.class.js +0 -247
  526. package/src/filters/blur_filter.class.js +0 -217
  527. package/src/filters/brightness_filter.class.js +0 -113
  528. package/src/filters/colormatrix_filter.class.js +0 -159
  529. package/src/filters/composed_filter.class.js +0 -72
  530. package/src/filters/contrast_filter.class.js +0 -113
  531. package/src/filters/convolute_filter.class.js +0 -352
  532. package/src/filters/filter_boilerplate.js +0 -111
  533. package/src/filters/filter_generator.js +0 -85
  534. package/src/filters/gamma_filter.class.js +0 -136
  535. package/src/filters/grayscale_filter.class.js +0 -154
  536. package/src/filters/hue_rotation.class.js +0 -107
  537. package/src/filters/invert_filter.class.js +0 -111
  538. package/src/filters/noise_filter.class.js +0 -134
  539. package/src/filters/pixelate_filter.class.js +0 -137
  540. package/src/filters/removecolor_filter.class.js +0 -173
  541. package/src/filters/resize_filter.class.js +0 -490
  542. package/src/filters/saturate_filter.class.js +0 -119
  543. package/src/filters/vibrance_filter.class.js +0 -122
  544. package/src/filters/webgl_backend.class.js +0 -396
  545. package/src/globalFabric.js +0 -4
  546. package/src/gradient.class.js +0 -490
  547. package/src/intersection.class.js +0 -172
  548. package/src/log.js +0 -11
  549. package/src/mixins/animation.mixin.js +0 -231
  550. package/src/mixins/canvas_dataurl_exporter.mixin.js +0 -97
  551. package/src/mixins/canvas_events.mixin.js +0 -974
  552. package/src/mixins/canvas_gestures.mixin.js +0 -149
  553. package/src/mixins/canvas_grouping.mixin.js +0 -177
  554. package/src/mixins/canvas_serialization.mixin.js +0 -228
  555. package/src/mixins/collection.mixin.js +0 -170
  556. package/src/mixins/default_controls.js +0 -114
  557. package/src/mixins/itext.svg_export.js +0 -241
  558. package/src/mixins/itext_behavior.mixin.js +0 -940
  559. package/src/mixins/itext_click_behavior.mixin.js +0 -278
  560. package/src/mixins/itext_key_behavior.mixin.js +0 -694
  561. package/src/mixins/object.svg_export.js +0 -258
  562. package/src/mixins/object_geometry.mixin.js +0 -683
  563. package/src/mixins/object_interactivity.mixin.js +0 -314
  564. package/src/mixins/object_origin.mixin.js +0 -255
  565. package/src/mixins/object_stacking.mixin.js +0 -80
  566. package/src/mixins/object_straightening.mixin.js +0 -80
  567. package/src/mixins/observable.mixin.js +0 -141
  568. package/src/mixins/shared_methods.mixin.js +0 -94
  569. package/src/mixins/stateful.mixin.js +0 -107
  570. package/src/mixins/text_style.mixin.js +0 -324
  571. package/src/parser.js +0 -1090
  572. package/src/pattern.class.js +0 -189
  573. package/src/point.class.js +0 -337
  574. package/src/shadow.class.js +0 -195
  575. package/src/shapes/active_selection.class.js +0 -155
  576. package/src/shapes/circle.class.js +0 -210
  577. package/src/shapes/ellipse.class.js +0 -181
  578. package/src/shapes/group.class.js +0 -593
  579. package/src/shapes/image.class.js +0 -764
  580. package/src/shapes/itext.class.js +0 -526
  581. package/src/shapes/line.class.js +0 -324
  582. package/src/shapes/object.class.js +0 -2008
  583. package/src/shapes/path.class.js +0 -384
  584. package/src/shapes/polygon.class.js +0 -81
  585. package/src/shapes/polyline.class.js +0 -268
  586. package/src/shapes/rect.class.js +0 -187
  587. package/src/shapes/text.class.js +0 -1696
  588. package/src/shapes/textbox.class.js +0 -461
  589. package/src/shapes/triangle.class.js +0 -93
  590. package/src/static_canvas.class.js +0 -1881
  591. package/src/util/anim_ease.js +0 -398
  592. package/src/util/animate.js +0 -254
  593. package/src/util/animate_color.js +0 -74
  594. package/src/util/dom_event.js +0 -50
  595. package/src/util/dom_misc.js +0 -300
  596. package/src/util/dom_request.js +0 -54
  597. package/src/util/dom_style.js +0 -70
  598. package/src/util/lang_array.js +0 -94
  599. package/src/util/lang_class.js +0 -115
  600. package/src/util/lang_object.js +0 -75
  601. package/src/util/lang_string.js +0 -110
  602. package/src/util/misc.js +0 -1330
  603. package/src/util/named_accessors.mixin.js +0 -428
  604. package/src/util/path.js +0 -829
@@ -0,0 +1,1561 @@
1
+ import { cache } from '../../cache';
2
+ import { config } from '../../config';
3
+ import { ALIASING_LIMIT, iMatrix, VERSION } from '../../constants';
4
+ import { ObjectEvents } from '../../EventTypeDefs';
5
+ import { AnimatableObject } from './AnimatableObject';
6
+ import { Point } from '../../Point';
7
+ import { Shadow } from '../../Shadow';
8
+ import type {
9
+ TDegree,
10
+ TFiller,
11
+ TSize,
12
+ TCacheCanvasDimensions,
13
+ } from '../../typedefs';
14
+ import { classRegistry } from '../../ClassRegistry';
15
+ import { runningAnimations } from '../../util/animation/AnimationRegistry';
16
+ import { cloneDeep } from '../../util/internals/cloneDeep';
17
+ import { capValue } from '../../util/misc/capValue';
18
+ import { createCanvasElement, toDataURL } from '../../util/misc/dom';
19
+ import { invertTransform, qrDecompose } from '../../util/misc/matrix';
20
+ import { enlivenObjectEnlivables } from '../../util/misc/objectEnlive';
21
+ import {
22
+ resetObjectTransform,
23
+ saveObjectTransform,
24
+ } from '../../util/misc/objectTransforms';
25
+ import { sendObjectToPlane } from '../../util/misc/planeChange';
26
+ import { pick, pickBy } from '../../util/misc/pick';
27
+ import { toFixed } from '../../util/misc/toFixed';
28
+ import type { Group } from '../Group';
29
+ import { StaticCanvas } from '../../canvas/StaticCanvas';
30
+ import { isFiller, isSerializableFiller, isTextObject } from '../../util/types';
31
+ import type { Image } from '../Image';
32
+ import {
33
+ cacheProperties,
34
+ fabricObjectDefaultValues,
35
+ stateProperties,
36
+ } from './defaultValues';
37
+ import type { Gradient } from '../../gradient/Gradient';
38
+ import type { Pattern } from '../../Pattern';
39
+ import type { Canvas } from '../../canvas/Canvas';
40
+ import { SerializedObjectProps } from './types/SerializedObjectProps';
41
+ import { ObjectProps } from './types/ObjectProps';
42
+ import { TProps } from './types';
43
+
44
+ export type TCachedFabricObject = FabricObject &
45
+ Required<
46
+ Pick<
47
+ FabricObject,
48
+ | 'zoomX'
49
+ | 'zoomY'
50
+ | '_cacheCanvas'
51
+ | '_cacheContext'
52
+ | 'cacheTranslationX'
53
+ | 'cacheTranslationY'
54
+ >
55
+ > & {
56
+ _cacheContext: CanvasRenderingContext2D;
57
+ };
58
+
59
+ /**
60
+ * Root object class from which all 2d shape classes inherit from
61
+ * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects}
62
+ *
63
+ * @fires added
64
+ * @fires removed
65
+ *
66
+ * @fires selected
67
+ * @fires deselected
68
+ *
69
+ * @fires rotating
70
+ * @fires scaling
71
+ * @fires moving
72
+ * @fires skewing
73
+ * @fires modified
74
+ *
75
+ * @fires mousedown
76
+ * @fires mouseup
77
+ * @fires mouseover
78
+ * @fires mouseout
79
+ * @fires mousewheel
80
+ * @fires mousedblclick
81
+ *
82
+ * @fires dragover
83
+ * @fires dragenter
84
+ * @fires dragleave
85
+ * @fires drop
86
+ */
87
+ export class FabricObject<
88
+ Props extends TProps<ObjectProps> = Partial<ObjectProps>,
89
+ SProps extends SerializedObjectProps = SerializedObjectProps,
90
+ EventSpec extends ObjectEvents = ObjectEvents
91
+ >
92
+ extends AnimatableObject<EventSpec>
93
+ implements ObjectProps
94
+ {
95
+ declare minScaleLimit: number;
96
+
97
+ declare opacity: number;
98
+
99
+ declare paintFirst: 'fill' | 'stroke';
100
+ declare fill: string | TFiller | null;
101
+ declare fillRule: CanvasFillRule;
102
+ declare stroke: string | TFiller | null;
103
+ declare strokeDashArray: number[] | null;
104
+ declare strokeDashOffset: number;
105
+ declare strokeLineCap: CanvasLineCap;
106
+ declare strokeLineJoin: CanvasLineJoin;
107
+ declare strokeMiterLimit: number;
108
+
109
+ declare globalCompositeOperation: GlobalCompositeOperation;
110
+ declare backgroundColor: string;
111
+
112
+ declare shadow: Shadow | null;
113
+
114
+ declare visible: boolean;
115
+
116
+ declare includeDefaultValues: boolean;
117
+ declare excludeFromExport: boolean;
118
+
119
+ declare objectCaching: boolean;
120
+
121
+ declare clipPath?: FabricObject;
122
+ declare inverted: boolean;
123
+ declare absolutePositioned: boolean;
124
+ declare centeredRotation: boolean;
125
+
126
+ /**
127
+ * This list of properties is used to check if the state of an object is changed.
128
+ * This state change now is only used for children of groups to understand if a group
129
+ * needs its cache regenerated during a .set call
130
+ * @type Array
131
+ */
132
+ static stateProperties: string[] = stateProperties;
133
+
134
+ /**
135
+ * List of properties to consider when checking if cache needs refresh
136
+ * Those properties are checked by
137
+ * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty
138
+ * and refreshed at the next render
139
+ * @type Array
140
+ */
141
+ static cacheProperties: string[] = cacheProperties;
142
+
143
+ /**
144
+ * When set to `true`, object's cache will be rerendered next render call.
145
+ * since 1.7.0
146
+ * @type Boolean
147
+ * @default true
148
+ */
149
+ declare dirty: boolean;
150
+
151
+ /**
152
+ * Quick access for the _cacheCanvas rendering context
153
+ * This is part of the objectCaching feature
154
+ * since 1.7.0
155
+ * @type boolean
156
+ * @default undefined
157
+ * @private
158
+ */
159
+ _cacheContext: CanvasRenderingContext2D | null = null;
160
+
161
+ /**
162
+ * A reference to the HTMLCanvasElement that is used to contain the cache of the object
163
+ * this canvas element is resized and cleared as needed
164
+ * Is marked private, you can read it, don't use it since it is handled by fabric
165
+ * since 1.7.0
166
+ * @type HTMLCanvasElement
167
+ * @default undefined
168
+ * @private
169
+ */
170
+ declare _cacheCanvas?: HTMLCanvasElement;
171
+
172
+ /**
173
+ * Size of the cache canvas, width
174
+ * since 1.7.0
175
+ * @type number
176
+ * @default undefined
177
+ * @private
178
+ */
179
+ declare cacheWidth?: number;
180
+
181
+ /**
182
+ * Size of the cache canvas, height
183
+ * since 1.7.0
184
+ * @type number
185
+ * @default undefined
186
+ * @private
187
+ */
188
+ declare cacheHeight?: number;
189
+
190
+ /**
191
+ * zoom level used on the cacheCanvas to draw the cache, X axe
192
+ * since 1.7.0
193
+ * @type number
194
+ * @default undefined
195
+ * @private
196
+ */
197
+ declare zoomX?: number;
198
+
199
+ /**
200
+ * zoom level used on the cacheCanvas to draw the cache, Y axe
201
+ * since 1.7.0
202
+ * @type number
203
+ * @default undefined
204
+ * @private
205
+ */
206
+ declare zoomY?: number;
207
+
208
+ /**
209
+ * zoom level used on the cacheCanvas to draw the cache, Y axe
210
+ * since 1.7.0
211
+ * @type number
212
+ * @default undefined
213
+ * @private
214
+ */
215
+ declare cacheTranslationX?: number;
216
+
217
+ /**
218
+ * translation of the cacheCanvas away from the center, for subpixel accuracy and crispness
219
+ * since 1.7.0
220
+ * @type number
221
+ * @default undefined
222
+ * @private
223
+ */
224
+ declare cacheTranslationY?: number;
225
+
226
+ /**
227
+ * A reference to the parent of the object, usually a Group
228
+ * @type number
229
+ * @default undefined
230
+ * @private
231
+ */
232
+ declare group?: Group;
233
+
234
+ /**
235
+ * Indicate if the object is sitting on a cache dedicated to it
236
+ * or is part of a larger cache for many object ( a group for example)
237
+ * @type number
238
+ * @default undefined
239
+ * @private
240
+ */
241
+ declare ownCaching?: boolean;
242
+
243
+ /**
244
+ * Private. indicates if the object inside a group is on a transformed context or not
245
+ * or is part of a larger cache for many object ( a group for example)
246
+ * @type boolean
247
+ * @default undefined
248
+ * @private
249
+ */
250
+ declare _transformDone?: boolean;
251
+
252
+ static ownDefaults: Record<string, any> = fabricObjectDefaultValues;
253
+
254
+ static getDefaults(): Record<string, any> {
255
+ return { ...FabricObject.ownDefaults };
256
+ }
257
+
258
+ /**
259
+ * Legacy identifier of the class. Prefer using utils like isType or instanceOf
260
+ * Will be removed in fabric 7 or 8.
261
+ * The setter exists because is very hard to catch all the ways in which a type value
262
+ * could be set in the instance
263
+ * @TODO add sustainable warning message
264
+ * @type string
265
+ * @deprecated
266
+ */
267
+ get type() {
268
+ const name = this.constructor.name;
269
+ if (name === 'FabricObject') {
270
+ return 'object';
271
+ }
272
+ return name.toLowerCase();
273
+ }
274
+
275
+ set type(value) {
276
+ console.warn('Setting type has no effect', value);
277
+ }
278
+
279
+ /**
280
+ * Constructor
281
+ * @param {Object} [options] Options object
282
+ */
283
+ constructor(options: Props = {} as Props) {
284
+ super();
285
+ Object.assign(
286
+ this,
287
+ (this.constructor as typeof FabricObject).getDefaults()
288
+ );
289
+ this.setOptions(options);
290
+ }
291
+
292
+ /**
293
+ * Create a the canvas used to keep the cached copy of the object
294
+ * @private
295
+ */
296
+ _createCacheCanvas() {
297
+ this._cacheCanvas = createCanvasElement();
298
+ this._cacheContext = this._cacheCanvas.getContext('2d');
299
+ this._updateCacheCanvas();
300
+ // if canvas gets created, is empty, so dirty.
301
+ this.dirty = true;
302
+ }
303
+
304
+ /**
305
+ * Limit the cache dimensions so that X * Y do not cross config.perfLimitSizeTotal
306
+ * and each side do not cross fabric.cacheSideLimit
307
+ * those numbers are configurable so that you can get as much detail as you want
308
+ * making bargain with performances.
309
+ * @param {Object} dims
310
+ * @param {Object} dims.width width of canvas
311
+ * @param {Object} dims.height height of canvas
312
+ * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache
313
+ * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache
314
+ * @return {Object}.width width of canvas
315
+ * @return {Object}.height height of canvas
316
+ * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache
317
+ * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache
318
+ */
319
+ _limitCacheSize(
320
+ dims: TSize & { zoomX: number; zoomY: number; capped: boolean } & any
321
+ ) {
322
+ const width = dims.width,
323
+ height = dims.height,
324
+ max = config.maxCacheSideLimit,
325
+ min = config.minCacheSideLimit;
326
+ if (
327
+ width <= max &&
328
+ height <= max &&
329
+ width * height <= config.perfLimitSizeTotal
330
+ ) {
331
+ if (width < min) {
332
+ dims.width = min;
333
+ }
334
+ if (height < min) {
335
+ dims.height = min;
336
+ }
337
+ return dims;
338
+ }
339
+ const ar = width / height,
340
+ [limX, limY] = cache.limitDimsByArea(ar),
341
+ x = capValue(min, limX, max),
342
+ y = capValue(min, limY, max);
343
+ if (width > x) {
344
+ dims.zoomX /= width / x;
345
+ dims.width = x;
346
+ dims.capped = true;
347
+ }
348
+ if (height > y) {
349
+ dims.zoomY /= height / y;
350
+ dims.height = y;
351
+ dims.capped = true;
352
+ }
353
+ return dims;
354
+ }
355
+
356
+ /**
357
+ * Return the dimension and the zoom level needed to create a cache canvas
358
+ * big enough to host the object to be cached.
359
+ * @private
360
+ * @return {Object}.x width of object to be cached
361
+ * @return {Object}.y height of object to be cached
362
+ * @return {Object}.width width of canvas
363
+ * @return {Object}.height height of canvas
364
+ * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache
365
+ * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache
366
+ */
367
+ _getCacheCanvasDimensions(): TCacheCanvasDimensions {
368
+ const objectScale = this.getTotalObjectScaling(),
369
+ // calculate dimensions without skewing
370
+ dim = this._getTransformedDimensions({ skewX: 0, skewY: 0 }),
371
+ neededX = (dim.x * objectScale.x) / this.scaleX,
372
+ neededY = (dim.y * objectScale.y) / this.scaleY;
373
+ return {
374
+ // for sure this ALIASING_LIMIT is slightly creating problem
375
+ // in situation in which the cache canvas gets an upper limit
376
+ // also objectScale contains already scaleX and scaleY
377
+ width: neededX + ALIASING_LIMIT,
378
+ height: neededY + ALIASING_LIMIT,
379
+ zoomX: objectScale.x,
380
+ zoomY: objectScale.y,
381
+ x: neededX,
382
+ y: neededY,
383
+ };
384
+ }
385
+
386
+ /**
387
+ * Update width and height of the canvas for cache
388
+ * returns true or false if canvas needed resize.
389
+ * @private
390
+ * @return {Boolean} true if the canvas has been resized
391
+ */
392
+ _updateCacheCanvas() {
393
+ const canvas = this._cacheCanvas,
394
+ context = this._cacheContext,
395
+ dims = this._limitCacheSize(this._getCacheCanvasDimensions()),
396
+ minCacheSize = config.minCacheSideLimit,
397
+ width = dims.width,
398
+ height = dims.height,
399
+ zoomX = dims.zoomX,
400
+ zoomY = dims.zoomY,
401
+ dimensionsChanged =
402
+ width !== this.cacheWidth || height !== this.cacheHeight,
403
+ zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY;
404
+
405
+ if (!canvas || !context) {
406
+ return false;
407
+ }
408
+
409
+ let drawingWidth,
410
+ drawingHeight,
411
+ shouldRedraw = dimensionsChanged || zoomChanged,
412
+ additionalWidth = 0,
413
+ additionalHeight = 0,
414
+ shouldResizeCanvas = false;
415
+
416
+ if (dimensionsChanged) {
417
+ const canvasWidth = (this._cacheCanvas as HTMLCanvasElement).width,
418
+ canvasHeight = (this._cacheCanvas as HTMLCanvasElement).height,
419
+ sizeGrowing = width > canvasWidth || height > canvasHeight,
420
+ sizeShrinking =
421
+ (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) &&
422
+ canvasWidth > minCacheSize &&
423
+ canvasHeight > minCacheSize;
424
+ shouldResizeCanvas = sizeGrowing || sizeShrinking;
425
+ if (
426
+ sizeGrowing &&
427
+ !dims.capped &&
428
+ (width > minCacheSize || height > minCacheSize)
429
+ ) {
430
+ additionalWidth = width * 0.1;
431
+ additionalHeight = height * 0.1;
432
+ }
433
+ }
434
+ if (isTextObject(this) && this.path) {
435
+ shouldRedraw = true;
436
+ shouldResizeCanvas = true;
437
+ // IMHO in those lines we are using zoomX and zoomY not the this version.
438
+ additionalWidth += this.getHeightOfLine(0) * this.zoomX!;
439
+ additionalHeight += this.getHeightOfLine(0) * this.zoomY!;
440
+ }
441
+ if (shouldRedraw) {
442
+ if (shouldResizeCanvas) {
443
+ canvas.width = Math.ceil(width + additionalWidth);
444
+ canvas.height = Math.ceil(height + additionalHeight);
445
+ } else {
446
+ context.setTransform(1, 0, 0, 1, 0, 0);
447
+ context.clearRect(0, 0, canvas.width, canvas.height);
448
+ }
449
+ drawingWidth = dims.x / 2;
450
+ drawingHeight = dims.y / 2;
451
+ this.cacheTranslationX =
452
+ Math.round(canvas.width / 2 - drawingWidth) + drawingWidth;
453
+ this.cacheTranslationY =
454
+ Math.round(canvas.height / 2 - drawingHeight) + drawingHeight;
455
+ this.cacheWidth = width;
456
+ this.cacheHeight = height;
457
+ context.translate(this.cacheTranslationX, this.cacheTranslationY);
458
+ context.scale(zoomX, zoomY);
459
+ this.zoomX = zoomX;
460
+ this.zoomY = zoomY;
461
+ return true;
462
+ }
463
+ return false;
464
+ }
465
+
466
+ /**
467
+ * Sets object's properties from options, for class constructor only.
468
+ * Needs to be overridden for different defaults.
469
+ * @protected
470
+ * @param {Object} [options] Options object
471
+ */
472
+ protected setOptions(options: Record<string, any> = {}) {
473
+ this._setOptions(options);
474
+ }
475
+
476
+ /**
477
+ * Transforms context when rendering an object
478
+ * @param {CanvasRenderingContext2D} ctx Context
479
+ */
480
+ transform(ctx: CanvasRenderingContext2D) {
481
+ const needFullTransform =
482
+ (this.group && !this.group._transformDone) ||
483
+ (this.group && this.canvas && ctx === (this.canvas as Canvas).contextTop);
484
+ const m = this.calcTransformMatrix(!needFullTransform);
485
+ ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
486
+ }
487
+
488
+ /**
489
+ * Returns an object representation of an instance
490
+ * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output
491
+ * @return {Object} Object representation of an instance
492
+ */
493
+ protected toObject(propertiesToInclude: any[] = []): any {
494
+ const NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS,
495
+ clipPathData =
496
+ this.clipPath && !this.clipPath.excludeFromExport
497
+ ? {
498
+ ...this.clipPath.toObject(propertiesToInclude),
499
+ inverted: this.clipPath.inverted,
500
+ absolutePositioned: this.clipPath.absolutePositioned,
501
+ }
502
+ : null,
503
+ object = {
504
+ ...pick(this, propertiesToInclude as (keyof this)[]),
505
+ type: this.constructor.name,
506
+ version: VERSION,
507
+ originX: this.originX,
508
+ originY: this.originY,
509
+ left: toFixed(this.left, NUM_FRACTION_DIGITS),
510
+ top: toFixed(this.top, NUM_FRACTION_DIGITS),
511
+ width: toFixed(this.width, NUM_FRACTION_DIGITS),
512
+ height: toFixed(this.height, NUM_FRACTION_DIGITS),
513
+ fill: isSerializableFiller(this.fill)
514
+ ? this.fill.toObject()
515
+ : this.fill,
516
+ stroke: isSerializableFiller(this.stroke)
517
+ ? this.stroke.toObject()
518
+ : this.stroke,
519
+ strokeWidth: toFixed(this.strokeWidth, NUM_FRACTION_DIGITS),
520
+ strokeDashArray: this.strokeDashArray
521
+ ? this.strokeDashArray.concat()
522
+ : this.strokeDashArray,
523
+ strokeLineCap: this.strokeLineCap,
524
+ strokeDashOffset: this.strokeDashOffset,
525
+ strokeLineJoin: this.strokeLineJoin,
526
+ strokeUniform: this.strokeUniform,
527
+ strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS),
528
+ scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS),
529
+ scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS),
530
+ angle: toFixed(this.angle, NUM_FRACTION_DIGITS),
531
+ flipX: this.flipX,
532
+ flipY: this.flipY,
533
+ opacity: toFixed(this.opacity, NUM_FRACTION_DIGITS),
534
+ shadow:
535
+ this.shadow && this.shadow.toObject
536
+ ? this.shadow.toObject()
537
+ : this.shadow,
538
+ visible: this.visible,
539
+ backgroundColor: this.backgroundColor,
540
+ fillRule: this.fillRule,
541
+ paintFirst: this.paintFirst,
542
+ globalCompositeOperation: this.globalCompositeOperation,
543
+ skewX: toFixed(this.skewX, NUM_FRACTION_DIGITS),
544
+ skewY: toFixed(this.skewY, NUM_FRACTION_DIGITS),
545
+ ...(clipPathData ? { clipPath: clipPathData } : null),
546
+ };
547
+
548
+ return !this.includeDefaultValues
549
+ ? this._removeDefaultValues(object)
550
+ : object;
551
+ }
552
+
553
+ /**
554
+ * Returns (dataless) object representation of an instance
555
+ * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
556
+ * @return {Object} Object representation of an instance
557
+ */
558
+ toDatalessObject(propertiesToInclude?: any[]): any {
559
+ // will be overwritten by subclasses
560
+ return this.toObject(propertiesToInclude);
561
+ }
562
+
563
+ /**
564
+ * @private
565
+ * @param {Object} object
566
+ */
567
+ _removeDefaultValues<T extends object>(object: T): Partial<T> {
568
+ // getDefaults() ( get from static ownDefaults ) should win over prototype since anyway they get assigned to instance
569
+ // ownDefault vs prototype is swappable only if you change all the fabric objects consistently.
570
+ const defaults = (this.constructor as typeof FabricObject).getDefaults();
571
+ const hasStaticDefaultValues = Object.keys(defaults).length > 0;
572
+ const baseValues = hasStaticDefaultValues
573
+ ? defaults
574
+ : Object.getPrototypeOf(this);
575
+
576
+ return pickBy(object, (value, key) => {
577
+ if (key === 'left' || key === 'top' || key === 'type') {
578
+ return true;
579
+ }
580
+ const baseValue = baseValues[key];
581
+ return (
582
+ value !== baseValue &&
583
+ // basically a check for [] === []
584
+ !(
585
+ Array.isArray(value) &&
586
+ Array.isArray(baseValue) &&
587
+ value.length === 0 &&
588
+ baseValue.length === 0
589
+ )
590
+ );
591
+ });
592
+ }
593
+
594
+ /**
595
+ * Returns a string representation of an instance
596
+ * @return {String}
597
+ */
598
+ toString() {
599
+ return `#<${this.constructor.name}>`;
600
+ }
601
+
602
+ /**
603
+ * Return the object scale factor counting also the group scaling
604
+ * @return {Point}
605
+ */
606
+ getObjectScaling() {
607
+ // if the object is a top level one, on the canvas, we go for simple aritmetic
608
+ // otherwise the complex method with angles will return approximations and decimals
609
+ // and will likely kill the cache when not needed
610
+ // https://github.com/fabricjs/fabric.js/issues/7157
611
+ if (!this.group) {
612
+ return new Point(Math.abs(this.scaleX), Math.abs(this.scaleY));
613
+ }
614
+ // if we are inside a group total zoom calculation is complex, we defer to generic matrices
615
+ const options = qrDecompose(this.calcTransformMatrix());
616
+ return new Point(Math.abs(options.scaleX), Math.abs(options.scaleY));
617
+ }
618
+
619
+ /**
620
+ * Return the object scale factor counting also the group scaling, zoom and retina
621
+ * @return {Object} object with scaleX and scaleY properties
622
+ */
623
+ getTotalObjectScaling() {
624
+ const scale = this.getObjectScaling();
625
+ if (this.canvas) {
626
+ const zoom = this.canvas.getZoom();
627
+ const retina = this.getCanvasRetinaScaling();
628
+ return scale.scalarMultiply(zoom * retina);
629
+ }
630
+ return scale;
631
+ }
632
+
633
+ /**
634
+ * Return the object opacity counting also the group property
635
+ * @return {Number}
636
+ */
637
+ getObjectOpacity() {
638
+ let opacity = this.opacity;
639
+ if (this.group) {
640
+ opacity *= this.group.getObjectOpacity();
641
+ }
642
+ return opacity;
643
+ }
644
+
645
+ /**
646
+ * Makes sure the scale is valid and modifies it if necessary
647
+ * @todo: this is a control action issue, not a geometry one
648
+ * @private
649
+ * @param {Number} value, unconstrained
650
+ * @return {Number} constrained value;
651
+ */
652
+ _constrainScale(value: number): number {
653
+ if (Math.abs(value) < this.minScaleLimit) {
654
+ if (value < 0) {
655
+ return -this.minScaleLimit;
656
+ } else {
657
+ return this.minScaleLimit;
658
+ }
659
+ } else if (value === 0) {
660
+ return 0.0001;
661
+ }
662
+ return value;
663
+ }
664
+
665
+ /**
666
+ * Handles setting values on the instance and handling internal side effects
667
+ * @protected
668
+ * @param {String} key
669
+ * @param {*} value
670
+ */
671
+ _set(key: string, value: any) {
672
+ const isChanged = this[key as keyof this] !== value;
673
+
674
+ if (key === 'scaleX' || key === 'scaleY') {
675
+ value = this._constrainScale(value);
676
+ }
677
+ if (key === 'scaleX' && value < 0) {
678
+ this.flipX = !this.flipX;
679
+ value *= -1;
680
+ } else if (key === 'scaleY' && value < 0) {
681
+ this.flipY = !this.flipY;
682
+ value *= -1;
683
+ // i don't like this automatic initialization here
684
+ } else if (key === 'shadow' && value && !(value instanceof Shadow)) {
685
+ value = new Shadow(value);
686
+ } else if (key === 'dirty' && this.group) {
687
+ this.group.set('dirty', value);
688
+ }
689
+
690
+ this[key as keyof this] = value;
691
+
692
+ if (isChanged) {
693
+ const groupNeedsUpdate = this.group && this.group.isOnACache();
694
+ if (
695
+ (this.constructor as typeof FabricObject).cacheProperties.includes(key)
696
+ ) {
697
+ this.dirty = true;
698
+ groupNeedsUpdate && this.group!.set('dirty', true);
699
+ } else if (
700
+ groupNeedsUpdate &&
701
+ (this.constructor as typeof FabricObject).stateProperties.includes(key)
702
+ ) {
703
+ this.group!.set('dirty', true);
704
+ }
705
+ }
706
+ return this;
707
+ }
708
+
709
+ /*
710
+ * @private
711
+ * return if the object would be visible in rendering
712
+ * @memberOf FabricObject.prototype
713
+ * @return {Boolean}
714
+ */
715
+ isNotVisible() {
716
+ return (
717
+ this.opacity === 0 ||
718
+ (!this.width && !this.height && this.strokeWidth === 0) ||
719
+ !this.visible
720
+ );
721
+ }
722
+
723
+ /**
724
+ * Renders an object on a specified context
725
+ * @param {CanvasRenderingContext2D} ctx Context to render on
726
+ */
727
+ render(ctx: CanvasRenderingContext2D) {
728
+ // do not render if width/height are zeros or object is not visible
729
+ if (this.isNotVisible()) {
730
+ return;
731
+ }
732
+ if (
733
+ this.canvas &&
734
+ this.canvas.skipOffscreen &&
735
+ !this.group &&
736
+ !this.isOnScreen()
737
+ ) {
738
+ return;
739
+ }
740
+ ctx.save();
741
+ this._setupCompositeOperation(ctx);
742
+ this.drawSelectionBackground(ctx);
743
+ this.transform(ctx);
744
+ this._setOpacity(ctx);
745
+ this._setShadow(ctx);
746
+ if (this.shouldCache()) {
747
+ this.renderCache();
748
+ (this as TCachedFabricObject).drawCacheOnCanvas(ctx);
749
+ } else {
750
+ this._removeCacheCanvas();
751
+ this.dirty = false;
752
+ this.drawObject(ctx);
753
+ }
754
+ ctx.restore();
755
+ }
756
+
757
+ drawSelectionBackground(ctx: CanvasRenderingContext2D) {
758
+ /* no op */
759
+ }
760
+
761
+ renderCache(options?: any) {
762
+ options = options || {};
763
+ if (!this._cacheCanvas || !this._cacheContext) {
764
+ this._createCacheCanvas();
765
+ }
766
+ if (this.isCacheDirty() && this._cacheContext) {
767
+ this.drawObject(this._cacheContext, options.forClipping);
768
+ this.dirty = false;
769
+ }
770
+ }
771
+
772
+ /**
773
+ * Remove cacheCanvas and its dimensions from the objects
774
+ */
775
+ _removeCacheCanvas() {
776
+ this._cacheCanvas = undefined;
777
+ this._cacheContext = null;
778
+ this.cacheWidth = 0;
779
+ this.cacheHeight = 0;
780
+ }
781
+
782
+ /**
783
+ * return true if the object will draw a stroke
784
+ * Does not consider text styles. This is just a shortcut used at rendering time
785
+ * We want it to be an approximation and be fast.
786
+ * wrote to avoid extra caching, it has to return true when stroke happens,
787
+ * can guess when it will not happen at 100% chance, does not matter if it misses
788
+ * some use case where the stroke is invisible.
789
+ * @since 3.0.0
790
+ * @returns Boolean
791
+ */
792
+ hasStroke() {
793
+ return (
794
+ this.stroke && this.stroke !== 'transparent' && this.strokeWidth !== 0
795
+ );
796
+ }
797
+
798
+ /**
799
+ * return true if the object will draw a fill
800
+ * Does not consider text styles. This is just a shortcut used at rendering time
801
+ * We want it to be an approximation and be fast.
802
+ * wrote to avoid extra caching, it has to return true when fill happens,
803
+ * can guess when it will not happen at 100% chance, does not matter if it misses
804
+ * some use case where the fill is invisible.
805
+ * @since 3.0.0
806
+ * @returns Boolean
807
+ */
808
+ hasFill() {
809
+ return this.fill && this.fill !== 'transparent';
810
+ }
811
+
812
+ /**
813
+ * When set to `true`, force the object to have its own cache, even if it is inside a group
814
+ * it may be needed when your object behave in a particular way on the cache and always needs
815
+ * its own isolated canvas to render correctly.
816
+ * Created to be overridden
817
+ * since 1.7.12
818
+ * @returns Boolean
819
+ */
820
+ needsItsOwnCache() {
821
+ if (
822
+ this.paintFirst === 'stroke' &&
823
+ this.hasFill() &&
824
+ this.hasStroke() &&
825
+ typeof this.shadow === 'object'
826
+ ) {
827
+ return true;
828
+ }
829
+ if (this.clipPath) {
830
+ return true;
831
+ }
832
+ return false;
833
+ }
834
+
835
+ /**
836
+ * Decide if the object should cache or not. Create its own cache level
837
+ * objectCaching is a global flag, wins over everything
838
+ * needsItsOwnCache should be used when the object drawing method requires
839
+ * a cache step. None of the fabric classes requires it.
840
+ * Generally you do not cache objects in groups because the group outside is cached.
841
+ * Read as: cache if is needed, or if the feature is enabled but we are not already caching.
842
+ * @return {Boolean}
843
+ */
844
+ shouldCache() {
845
+ this.ownCaching =
846
+ this.needsItsOwnCache() ||
847
+ (this.objectCaching && (!this.group || !this.group.isOnACache()));
848
+ return this.ownCaching;
849
+ }
850
+
851
+ /**
852
+ * Check if this object or a child object will cast a shadow
853
+ * used by Group.shouldCache to know if child has a shadow recursively
854
+ * @return {Boolean}
855
+ * @deprecated
856
+ */
857
+ willDrawShadow() {
858
+ return (
859
+ !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0)
860
+ );
861
+ }
862
+
863
+ /**
864
+ * Execute the drawing operation for an object clipPath
865
+ * @param {CanvasRenderingContext2D} ctx Context to render on
866
+ * @param {FabricObject} clipPath
867
+ */
868
+ drawClipPathOnCache(
869
+ ctx: CanvasRenderingContext2D,
870
+ clipPath: TCachedFabricObject
871
+ ) {
872
+ ctx.save();
873
+ // DEBUG: uncomment this line, comment the following
874
+ // ctx.globalAlpha = 0.4
875
+ if (clipPath.inverted) {
876
+ ctx.globalCompositeOperation = 'destination-out';
877
+ } else {
878
+ ctx.globalCompositeOperation = 'destination-in';
879
+ }
880
+ //ctx.scale(1 / 2, 1 / 2);
881
+ if (clipPath.absolutePositioned) {
882
+ const m = invertTransform(this.calcTransformMatrix());
883
+ ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
884
+ }
885
+ clipPath.transform(ctx);
886
+ ctx.scale(1 / clipPath.zoomX, 1 / clipPath.zoomY);
887
+ ctx.drawImage(
888
+ clipPath._cacheCanvas,
889
+ -clipPath.cacheTranslationX,
890
+ -clipPath.cacheTranslationY
891
+ );
892
+ ctx.restore();
893
+ }
894
+
895
+ /**
896
+ * Execute the drawing operation for an object on a specified context
897
+ * @param {CanvasRenderingContext2D} ctx Context to render on
898
+ * @param {boolean} forClipping apply clipping styles
899
+ */
900
+ drawObject(ctx: CanvasRenderingContext2D, forClipping?: boolean) {
901
+ const originalFill = this.fill,
902
+ originalStroke = this.stroke;
903
+ if (forClipping) {
904
+ this.fill = 'black';
905
+ this.stroke = '';
906
+ this._setClippingProperties(ctx);
907
+ } else {
908
+ this._renderBackground(ctx);
909
+ }
910
+ this._render(ctx);
911
+ this._drawClipPath(ctx, this.clipPath);
912
+ this.fill = originalFill;
913
+ this.stroke = originalStroke;
914
+ }
915
+
916
+ /**
917
+ * Prepare clipPath state and cache and draw it on instance's cache
918
+ * @param {CanvasRenderingContext2D} ctx
919
+ * @param {FabricObject} clipPath
920
+ */
921
+ _drawClipPath(ctx: CanvasRenderingContext2D, clipPath?: FabricObject) {
922
+ if (!clipPath) {
923
+ return;
924
+ }
925
+ // needed to setup a couple of variables
926
+ // path canvas gets overridden with this one.
927
+ // TODO find a better solution?
928
+ clipPath._set('canvas', this.canvas);
929
+ clipPath.shouldCache();
930
+ clipPath._transformDone = true;
931
+ clipPath.renderCache({ forClipping: true });
932
+ this.drawClipPathOnCache(ctx, clipPath as TCachedFabricObject);
933
+ }
934
+
935
+ /**
936
+ * Paint the cached copy of the object on the target context.
937
+ * @param {CanvasRenderingContext2D} ctx Context to render on
938
+ */
939
+ drawCacheOnCanvas(this: TCachedFabricObject, ctx: CanvasRenderingContext2D) {
940
+ ctx.scale(1 / this.zoomX, 1 / this.zoomY);
941
+ ctx.drawImage(
942
+ this._cacheCanvas,
943
+ -this.cacheTranslationX,
944
+ -this.cacheTranslationY
945
+ );
946
+ }
947
+
948
+ /**
949
+ * Check if cache is dirty
950
+ * @param {Boolean} skipCanvas skip canvas checks because this object is painted
951
+ * on parent canvas.
952
+ */
953
+ isCacheDirty(skipCanvas = false) {
954
+ if (this.isNotVisible()) {
955
+ return false;
956
+ }
957
+ if (
958
+ this._cacheCanvas &&
959
+ this._cacheContext &&
960
+ !skipCanvas &&
961
+ this._updateCacheCanvas()
962
+ ) {
963
+ // in this case the context is already cleared.
964
+ return true;
965
+ } else {
966
+ if (this.dirty || (this.clipPath && this.clipPath.absolutePositioned)) {
967
+ if (this._cacheCanvas && this._cacheContext && !skipCanvas) {
968
+ const width = this.cacheWidth! / this.zoomX!;
969
+ const height = this.cacheHeight! / this.zoomY!;
970
+ this._cacheContext.clearRect(-width / 2, -height / 2, width, height);
971
+ }
972
+ return true;
973
+ }
974
+ }
975
+ return false;
976
+ }
977
+
978
+ /**
979
+ * Draws a background for the object big as its untransformed dimensions
980
+ * @private
981
+ * @param {CanvasRenderingContext2D} ctx Context to render on
982
+ */
983
+ _renderBackground(ctx: CanvasRenderingContext2D) {
984
+ if (!this.backgroundColor) {
985
+ return;
986
+ }
987
+ const dim = this._getNonTransformedDimensions();
988
+ ctx.fillStyle = this.backgroundColor;
989
+
990
+ ctx.fillRect(-dim.x / 2, -dim.y / 2, dim.x, dim.y);
991
+ // if there is background color no other shadows
992
+ // should be casted
993
+ this._removeShadow(ctx);
994
+ }
995
+
996
+ /**
997
+ * @private
998
+ * @param {CanvasRenderingContext2D} ctx Context to render on
999
+ */
1000
+ _setOpacity(ctx: CanvasRenderingContext2D) {
1001
+ if (this.group && !this.group._transformDone) {
1002
+ ctx.globalAlpha = this.getObjectOpacity();
1003
+ } else {
1004
+ ctx.globalAlpha *= this.opacity;
1005
+ }
1006
+ }
1007
+
1008
+ _setStrokeStyles(
1009
+ ctx: CanvasRenderingContext2D,
1010
+ decl: Pick<
1011
+ this,
1012
+ | 'stroke'
1013
+ | 'strokeWidth'
1014
+ | 'strokeLineCap'
1015
+ | 'strokeDashOffset'
1016
+ | 'strokeLineJoin'
1017
+ | 'strokeMiterLimit'
1018
+ >
1019
+ ) {
1020
+ const stroke = decl.stroke;
1021
+ if (stroke) {
1022
+ ctx.lineWidth = decl.strokeWidth;
1023
+ ctx.lineCap = decl.strokeLineCap;
1024
+ ctx.lineDashOffset = decl.strokeDashOffset;
1025
+ ctx.lineJoin = decl.strokeLineJoin;
1026
+ ctx.miterLimit = decl.strokeMiterLimit;
1027
+ if (isFiller(stroke)) {
1028
+ if (
1029
+ (stroke as Gradient<'linear'>).gradientUnits === 'percentage' ||
1030
+ (stroke as Gradient<'linear'>).gradientTransform ||
1031
+ (stroke as Pattern).patternTransform
1032
+ ) {
1033
+ // need to transform gradient in a pattern.
1034
+ // this is a slow process. If you are hitting this codepath, and the object
1035
+ // is not using caching, you should consider switching it on.
1036
+ // we need a canvas as big as the current object caching canvas.
1037
+ this._applyPatternForTransformedGradient(ctx, stroke);
1038
+ } else {
1039
+ // is a simple gradient or pattern
1040
+ ctx.strokeStyle = stroke.toLive(ctx)!;
1041
+ this._applyPatternGradientTransform(ctx, stroke);
1042
+ }
1043
+ } else {
1044
+ // is a color
1045
+ ctx.strokeStyle = decl.stroke as string;
1046
+ }
1047
+ }
1048
+ }
1049
+
1050
+ _setFillStyles(ctx: CanvasRenderingContext2D, { fill }: Pick<this, 'fill'>) {
1051
+ if (fill) {
1052
+ if (isFiller(fill)) {
1053
+ ctx.fillStyle = fill.toLive(ctx)!;
1054
+ this._applyPatternGradientTransform(ctx, fill);
1055
+ } else {
1056
+ ctx.fillStyle = fill;
1057
+ }
1058
+ }
1059
+ }
1060
+
1061
+ _setClippingProperties(ctx: CanvasRenderingContext2D) {
1062
+ ctx.globalAlpha = 1;
1063
+ ctx.strokeStyle = 'transparent';
1064
+ ctx.fillStyle = '#000000';
1065
+ }
1066
+
1067
+ /**
1068
+ * @private
1069
+ * Sets line dash
1070
+ * @param {CanvasRenderingContext2D} ctx Context to set the dash line on
1071
+ * @param {Array} dashArray array representing dashes
1072
+ */
1073
+ _setLineDash(ctx: CanvasRenderingContext2D, dashArray?: number[] | null) {
1074
+ if (!dashArray || dashArray.length === 0) {
1075
+ return;
1076
+ }
1077
+ // Spec requires the concatenation of two copies of the dash array when the number of elements is odd
1078
+ if (1 & dashArray.length) {
1079
+ dashArray.push(...dashArray);
1080
+ }
1081
+ ctx.setLineDash(dashArray);
1082
+ }
1083
+
1084
+ /**
1085
+ * @private
1086
+ * @param {CanvasRenderingContext2D} ctx Context to render on
1087
+ */
1088
+ _setShadow(ctx: CanvasRenderingContext2D) {
1089
+ if (!this.shadow) {
1090
+ return;
1091
+ }
1092
+
1093
+ const shadow = this.shadow,
1094
+ canvas = this.canvas,
1095
+ retinaScaling = this.getCanvasRetinaScaling(),
1096
+ [sx, , , sy] = canvas?.viewportTransform || iMatrix,
1097
+ multX = sx * retinaScaling,
1098
+ multY = sy * retinaScaling,
1099
+ scaling = shadow.nonScaling ? new Point(1, 1) : this.getObjectScaling();
1100
+ ctx.shadowColor = shadow.color;
1101
+ ctx.shadowBlur =
1102
+ (shadow.blur *
1103
+ config.browserShadowBlurConstant *
1104
+ (multX + multY) *
1105
+ (scaling.x + scaling.y)) /
1106
+ 4;
1107
+ ctx.shadowOffsetX = shadow.offsetX * multX * scaling.x;
1108
+ ctx.shadowOffsetY = shadow.offsetY * multY * scaling.y;
1109
+ }
1110
+
1111
+ /**
1112
+ * @private
1113
+ * @param {CanvasRenderingContext2D} ctx Context to render on
1114
+ */
1115
+ _removeShadow(ctx: CanvasRenderingContext2D) {
1116
+ if (!this.shadow) {
1117
+ return;
1118
+ }
1119
+
1120
+ ctx.shadowColor = '';
1121
+ ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;
1122
+ }
1123
+
1124
+ /**
1125
+ * @private
1126
+ * @param {CanvasRenderingContext2D} ctx Context to render on
1127
+ * @param {TFiller} filler {@link Pattern} or {@link Gradient}
1128
+ */
1129
+ _applyPatternGradientTransform(
1130
+ ctx: CanvasRenderingContext2D,
1131
+ filler: TFiller
1132
+ ) {
1133
+ if (!isFiller(filler)) {
1134
+ return { offsetX: 0, offsetY: 0 };
1135
+ }
1136
+ const t =
1137
+ (filler as Gradient<'linear'>).gradientTransform ||
1138
+ (filler as Pattern).patternTransform;
1139
+ const offsetX = -this.width / 2 + filler.offsetX || 0,
1140
+ offsetY = -this.height / 2 + filler.offsetY || 0;
1141
+
1142
+ if ((filler as Gradient<'linear'>).gradientUnits === 'percentage') {
1143
+ ctx.transform(this.width, 0, 0, this.height, offsetX, offsetY);
1144
+ } else {
1145
+ ctx.transform(1, 0, 0, 1, offsetX, offsetY);
1146
+ }
1147
+ if (t) {
1148
+ ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]);
1149
+ }
1150
+ return { offsetX: offsetX, offsetY: offsetY };
1151
+ }
1152
+
1153
+ /**
1154
+ * @private
1155
+ * @param {CanvasRenderingContext2D} ctx Context to render on
1156
+ */
1157
+ _renderPaintInOrder(ctx: CanvasRenderingContext2D) {
1158
+ if (this.paintFirst === 'stroke') {
1159
+ this._renderStroke(ctx);
1160
+ this._renderFill(ctx);
1161
+ } else {
1162
+ this._renderFill(ctx);
1163
+ this._renderStroke(ctx);
1164
+ }
1165
+ }
1166
+
1167
+ /**
1168
+ * @private
1169
+ * function that actually render something on the context.
1170
+ * empty here to allow Obects to work on tests to benchmark fabric functionalites
1171
+ * not related to rendering
1172
+ * @param {CanvasRenderingContext2D} ctx Context to render on
1173
+ */
1174
+ _render(ctx: CanvasRenderingContext2D) {
1175
+ // placeholder to be overridden
1176
+ }
1177
+
1178
+ /**
1179
+ * @private
1180
+ * @param {CanvasRenderingContext2D} ctx Context to render on
1181
+ */
1182
+ _renderFill(ctx: CanvasRenderingContext2D) {
1183
+ if (!this.fill) {
1184
+ return;
1185
+ }
1186
+
1187
+ ctx.save();
1188
+ this._setFillStyles(ctx, this);
1189
+ if (this.fillRule === 'evenodd') {
1190
+ ctx.fill('evenodd');
1191
+ } else {
1192
+ ctx.fill();
1193
+ }
1194
+ ctx.restore();
1195
+ }
1196
+
1197
+ /**
1198
+ * @private
1199
+ * @param {CanvasRenderingContext2D} ctx Context to render on
1200
+ */
1201
+ _renderStroke(ctx: CanvasRenderingContext2D) {
1202
+ if (!this.stroke || this.strokeWidth === 0) {
1203
+ return;
1204
+ }
1205
+
1206
+ if (this.shadow && !this.shadow.affectStroke) {
1207
+ this._removeShadow(ctx);
1208
+ }
1209
+
1210
+ ctx.save();
1211
+ if (this.strokeUniform) {
1212
+ const scaling = this.getObjectScaling();
1213
+ ctx.scale(1 / scaling.x, 1 / scaling.y);
1214
+ }
1215
+ this._setLineDash(ctx, this.strokeDashArray);
1216
+ this._setStrokeStyles(ctx, this);
1217
+ ctx.stroke();
1218
+ ctx.restore();
1219
+ }
1220
+
1221
+ /**
1222
+ * This function try to patch the missing gradientTransform on canvas gradients.
1223
+ * transforming a context to transform the gradient, is going to transform the stroke too.
1224
+ * we want to transform the gradient but not the stroke operation, so we create
1225
+ * a transformed gradient on a pattern and then we use the pattern instead of the gradient.
1226
+ * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size
1227
+ * is limited.
1228
+ * @private
1229
+ * @param {CanvasRenderingContext2D} ctx Context to render on
1230
+ * @param {Gradient} filler
1231
+ */
1232
+ _applyPatternForTransformedGradient(
1233
+ ctx: CanvasRenderingContext2D,
1234
+ filler: TFiller
1235
+ ) {
1236
+ const dims = this._limitCacheSize(this._getCacheCanvasDimensions()),
1237
+ pCanvas = createCanvasElement(),
1238
+ retinaScaling = this.getCanvasRetinaScaling(),
1239
+ width = dims.x / this.scaleX / retinaScaling,
1240
+ height = dims.y / this.scaleY / retinaScaling;
1241
+ pCanvas.width = width;
1242
+ pCanvas.height = height;
1243
+ const pCtx = pCanvas.getContext('2d');
1244
+ if (!pCtx) {
1245
+ return;
1246
+ }
1247
+ pCtx.beginPath();
1248
+ pCtx.moveTo(0, 0);
1249
+ pCtx.lineTo(width, 0);
1250
+ pCtx.lineTo(width, height);
1251
+ pCtx.lineTo(0, height);
1252
+ pCtx.closePath();
1253
+ pCtx.translate(width / 2, height / 2);
1254
+ pCtx.scale(
1255
+ dims.zoomX / this.scaleX / retinaScaling,
1256
+ dims.zoomY / this.scaleY / retinaScaling
1257
+ );
1258
+ this._applyPatternGradientTransform(pCtx, filler);
1259
+ pCtx.fillStyle = filler.toLive(ctx)!;
1260
+ pCtx.fill();
1261
+ ctx.translate(
1262
+ -this.width / 2 - this.strokeWidth / 2,
1263
+ -this.height / 2 - this.strokeWidth / 2
1264
+ );
1265
+ ctx.scale(
1266
+ (retinaScaling * this.scaleX) / dims.zoomX,
1267
+ (retinaScaling * this.scaleY) / dims.zoomY
1268
+ );
1269
+ ctx.strokeStyle = pCtx.createPattern(pCanvas, 'no-repeat') ?? '';
1270
+ }
1271
+
1272
+ /**
1273
+ * This function is an helper for svg import. it returns the center of the object in the svg
1274
+ * untransformed coordinates
1275
+ * @private
1276
+ * @return {Point} center point from element coordinates
1277
+ */
1278
+ _findCenterFromElement() {
1279
+ return new Point(this.left + this.width / 2, this.top + this.height / 2);
1280
+ }
1281
+
1282
+ /**
1283
+ * Clones an instance.
1284
+ * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
1285
+ * @returns {Promise<FabricObject>}
1286
+ */
1287
+ clone(propertiesToInclude: string[]) {
1288
+ const objectForm = this.toObject(propertiesToInclude);
1289
+ return (this.constructor as typeof FabricObject).fromObject(
1290
+ objectForm
1291
+ ) as unknown as this;
1292
+ }
1293
+
1294
+ /**
1295
+ * Creates an instance of Image out of an object
1296
+ * makes use of toCanvasElement.
1297
+ * Once this method was based on toDataUrl and loadImage, so it also had a quality
1298
+ * and format option. toCanvasElement is faster and produce no loss of quality.
1299
+ * If you need to get a real Jpeg or Png from an object, using toDataURL is the right way to do it.
1300
+ * toCanvasElement and then toBlob from the obtained canvas is also a good option.
1301
+ * @todo fix the export type, it could not be Image but the type that getClass return for 'image'.
1302
+ * @param {Object} [options] for clone as image, passed to toDataURL
1303
+ * @param {Number} [options.multiplier=1] Multiplier to scale by
1304
+ * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14
1305
+ * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14
1306
+ * @param {Number} [options.width] Cropping width. Introduced in v1.2.14
1307
+ * @param {Number} [options.height] Cropping height. Introduced in v1.2.14
1308
+ * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4
1309
+ * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4
1310
+ * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2
1311
+ * @return {Image} Object cloned as image.
1312
+ */
1313
+ cloneAsImage(options: any): Image {
1314
+ const canvasEl = this.toCanvasElement(options);
1315
+ // TODO: how to import Image w/o an import cycle?
1316
+ const ImageClass = classRegistry.getClass('image');
1317
+ return new ImageClass(canvasEl);
1318
+ }
1319
+
1320
+ /**
1321
+ * Converts an object into a HTMLCanvas element
1322
+ * @param {Object} options Options object
1323
+ * @param {Number} [options.multiplier=1] Multiplier to scale by
1324
+ * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14
1325
+ * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14
1326
+ * @param {Number} [options.width] Cropping width. Introduced in v1.2.14
1327
+ * @param {Number} [options.height] Cropping height. Introduced in v1.2.14
1328
+ * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4
1329
+ * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4
1330
+ * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2
1331
+ * @param {Boolean} [options.viewportTransform] Account for canvas viewport transform
1332
+ * @return {HTMLCanvasElement} Returns DOM element <canvas> with the FabricObject
1333
+ */
1334
+ toCanvasElement(options: any = {}) {
1335
+ const origParams = saveObjectTransform(this),
1336
+ originalGroup = this.group,
1337
+ originalShadow = this.shadow,
1338
+ abs = Math.abs,
1339
+ retinaScaling = options.enableRetinaScaling
1340
+ ? Math.max(config.devicePixelRatio, 1)
1341
+ : 1,
1342
+ multiplier = (options.multiplier || 1) * retinaScaling;
1343
+ delete this.group;
1344
+ if (options.withoutTransform) {
1345
+ resetObjectTransform(this);
1346
+ }
1347
+ if (options.withoutShadow) {
1348
+ this.shadow = null;
1349
+ }
1350
+ if (options.viewportTransform) {
1351
+ sendObjectToPlane(this, this.getViewportTransform());
1352
+ }
1353
+
1354
+ const el = createCanvasElement(),
1355
+ // skip canvas zoom and calculate with setCoords now.
1356
+ boundingRect = this.getBoundingRect(true, true),
1357
+ shadow = this.shadow,
1358
+ shadowOffset = new Point();
1359
+
1360
+ if (shadow) {
1361
+ const shadowBlur = shadow.blur;
1362
+ const scaling = shadow.nonScaling
1363
+ ? new Point(1, 1)
1364
+ : this.getObjectScaling();
1365
+ // consider non scaling shadow.
1366
+ shadowOffset.x =
1367
+ 2 * Math.round(abs(shadow.offsetX) + shadowBlur) * abs(scaling.x);
1368
+ shadowOffset.y =
1369
+ 2 * Math.round(abs(shadow.offsetY) + shadowBlur) * abs(scaling.y);
1370
+ }
1371
+ const width = boundingRect.width + shadowOffset.x,
1372
+ height = boundingRect.height + shadowOffset.y;
1373
+ // if the current width/height is not an integer
1374
+ // we need to make it so.
1375
+ el.width = Math.ceil(width);
1376
+ el.height = Math.ceil(height);
1377
+ const canvas = new StaticCanvas(el, {
1378
+ enableRetinaScaling: false,
1379
+ renderOnAddRemove: false,
1380
+ skipOffscreen: false,
1381
+ });
1382
+ if (options.format === 'jpeg') {
1383
+ canvas.backgroundColor = '#fff';
1384
+ }
1385
+ this.setPositionByOrigin(
1386
+ new Point(canvas.width / 2, canvas.height / 2),
1387
+ 'center',
1388
+ 'center'
1389
+ );
1390
+ const originalCanvas = this.canvas;
1391
+ // static canvas and canvas have both an array of InteractiveObjects
1392
+ // @ts-ignore this needs to be fixed somehow, or ignored globally
1393
+ canvas._objects = [this];
1394
+ this.set('canvas', canvas);
1395
+ this.setCoords();
1396
+ const canvasEl = canvas.toCanvasElement(multiplier || 1, options);
1397
+ this.set('canvas', originalCanvas);
1398
+ this.shadow = originalShadow;
1399
+ if (originalGroup) {
1400
+ this.group = originalGroup;
1401
+ }
1402
+ this.set(origParams);
1403
+ this.setCoords();
1404
+ // canvas.dispose will call image.dispose that will nullify the elements
1405
+ // since this canvas is a simple element for the process, we remove references
1406
+ // to objects in this way in order to avoid object trashing.
1407
+ canvas._objects = [];
1408
+ // since render has settled it is safe to destroy canvas
1409
+ canvas.destroy();
1410
+ return canvasEl;
1411
+ }
1412
+
1413
+ /**
1414
+ * Converts an object into a data-url-like string
1415
+ * @param {Object} options Options object
1416
+ * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png"
1417
+ * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.
1418
+ * @param {Number} [options.multiplier=1] Multiplier to scale by
1419
+ * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14
1420
+ * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14
1421
+ * @param {Number} [options.width] Cropping width. Introduced in v1.2.14
1422
+ * @param {Number} [options.height] Cropping height. Introduced in v1.2.14
1423
+ * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4
1424
+ * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4
1425
+ * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2
1426
+ * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format
1427
+ */
1428
+ toDataURL(options: any = {}) {
1429
+ return toDataURL(
1430
+ this.toCanvasElement(options),
1431
+ options.format || 'png',
1432
+ options.quality || 1
1433
+ );
1434
+ }
1435
+
1436
+ /**
1437
+ * Returns true if any of the specified types is identical to the type of an instance
1438
+ * @param {String} type Type to check against
1439
+ * @return {Boolean}
1440
+ */
1441
+ isType(...types: string[]) {
1442
+ return types.includes(this.constructor.name) || types.includes(this.type);
1443
+ }
1444
+
1445
+ /**
1446
+ * Returns complexity of an instance
1447
+ * @return {Number} complexity of this instance (is 1 unless subclassed)
1448
+ */
1449
+ complexity() {
1450
+ return 1;
1451
+ }
1452
+
1453
+ /**
1454
+ * Returns a JSON representation of an instance
1455
+ * @return {Object} JSON
1456
+ */
1457
+ toJSON() {
1458
+ // delegate, not alias
1459
+ return this.toObject();
1460
+ }
1461
+
1462
+ /**
1463
+ * Sets "angle" of an instance with centered rotation
1464
+ * @param {TDegree} angle Angle value (in degrees)
1465
+ */
1466
+ rotate(angle: TDegree) {
1467
+ const shouldCenterOrigin =
1468
+ (this.originX !== 'center' || this.originY !== 'center') &&
1469
+ this.centeredRotation;
1470
+
1471
+ if (shouldCenterOrigin) {
1472
+ this._setOriginToCenter();
1473
+ }
1474
+
1475
+ this.set('angle', angle);
1476
+
1477
+ if (shouldCenterOrigin) {
1478
+ this._resetOrigin();
1479
+ }
1480
+ }
1481
+
1482
+ /**
1483
+ * This callback function is called by the parent group of an object every
1484
+ * time a non-delegated property changes on the group. It is passed the key
1485
+ * and value as parameters. Not adding in this function's signature to avoid
1486
+ * Travis build error about unused variables.
1487
+ */
1488
+ setOnGroup() {
1489
+ // implemented by sub-classes, as needed.
1490
+ }
1491
+
1492
+ /**
1493
+ * Sets canvas globalCompositeOperation for specific object
1494
+ * custom composition operation for the particular object can be specified using globalCompositeOperation property
1495
+ * @param {CanvasRenderingContext2D} ctx Rendering canvas context
1496
+ */
1497
+ _setupCompositeOperation(ctx: CanvasRenderingContext2D) {
1498
+ if (this.globalCompositeOperation) {
1499
+ ctx.globalCompositeOperation = this.globalCompositeOperation;
1500
+ }
1501
+ }
1502
+
1503
+ /**
1504
+ * cancel instance's running animations
1505
+ * override if necessary to dispose artifacts such as `clipPath`
1506
+ */
1507
+ dispose() {
1508
+ runningAnimations.cancelByTarget(this);
1509
+ this.off();
1510
+ this._set('canvas', undefined);
1511
+ }
1512
+
1513
+ /**
1514
+ *
1515
+ * @param {Function} klass
1516
+ * @param {object} object
1517
+ * @param {object} [options]
1518
+ * @param {string} [options.extraParam] property to pass as first argument to the constructor
1519
+ * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
1520
+ * @returns {Promise<FabricObject>}
1521
+ */
1522
+ static _fromObject<S extends FabricObject>(
1523
+ object: Record<string, unknown>,
1524
+ {
1525
+ extraParam,
1526
+ ...options
1527
+ }: { extraParam?: string; signal?: AbortSignal } = {}
1528
+ ): Promise<S> {
1529
+ return enlivenObjectEnlivables<any>(cloneDeep(object), options).then(
1530
+ (enlivedMap) => {
1531
+ const allOptions = { ...options, ...enlivedMap };
1532
+ // from the resulting enlived options, extract options.extraParam to arg0
1533
+ // to avoid accidental overrides later
1534
+ if (extraParam) {
1535
+ const { [extraParam]: arg0, type, ...rest } = allOptions;
1536
+ // @ts-ignore;
1537
+ return new this(arg0, rest);
1538
+ } else {
1539
+ return new this(allOptions);
1540
+ }
1541
+ }
1542
+ ) as Promise<S>;
1543
+ }
1544
+
1545
+ /**
1546
+ *
1547
+ * @param {object} object
1548
+ * @param {object} [options]
1549
+ * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
1550
+ * @returns {Promise<FabricObject>}
1551
+ */
1552
+ static fromObject<T extends TProps<SerializedObjectProps>>(
1553
+ object: T,
1554
+ options?: { signal?: AbortSignal }
1555
+ ) {
1556
+ return this._fromObject(object, options);
1557
+ }
1558
+ }
1559
+
1560
+ classRegistry.setClass(FabricObject);
1561
+ classRegistry.setClass(FabricObject, 'object');