fabric 5.3.0-browser → 6.0.0-beta1

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