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,1709 @@
1
+ import { getEnv } from '../env';
2
+ import { config } from '../config';
3
+ import { iMatrix, VERSION } from '../constants';
4
+ import type { CanvasEvents, StaticCanvasEvents } from '../EventTypeDefs';
5
+ import type { Gradient } from '../gradient/Gradient';
6
+ import { createCollectionMixin } from '../Collection';
7
+ import { CommonMethods } from '../CommonMethods';
8
+ import type { Pattern } from '../Pattern';
9
+ import { Point } from '../Point';
10
+ import type { BaseFabricObject as FabricObject } from '../EventTypeDefs';
11
+ import type { TCachedFabricObject } from '../shapes/Object/Object';
12
+ import type { Rect } from '../shapes/Rect';
13
+ import {
14
+ Constructor,
15
+ ImageFormat,
16
+ TCornerPoint,
17
+ TDataUrlOptions,
18
+ TFiller,
19
+ TMat2D,
20
+ TSize,
21
+ TSVGReviver,
22
+ TToCanvasElementOptions,
23
+ TValidToObjectMethod,
24
+ } from '../typedefs';
25
+ import {
26
+ cancelAnimFrame,
27
+ requestAnimFrame,
28
+ } from '../util/animation/AnimationFrameProvider';
29
+ import { cleanUpJsdomNode, getElementOffset } from '../util/dom_misc';
30
+ import { uid } from '../util/internals/uid';
31
+ import { createCanvasElement, isHTMLCanvas, toDataURL } from '../util/misc/dom';
32
+ import { invertTransform, transformPoint } from '../util/misc/matrix';
33
+ import {
34
+ enlivenObjectEnlivables,
35
+ EnlivenObjectOptions,
36
+ enlivenObjects,
37
+ } from '../util/misc/objectEnlive';
38
+ import { pick } from '../util/misc/pick';
39
+ import { matrixToSVG } from '../util/misc/svgParsing';
40
+ import { toFixed } from '../util/misc/toFixed';
41
+ import { isCollection, isFiller, isPattern, isTextObject } from '../util/types';
42
+
43
+ const CANVAS_INIT_ERROR = 'Could not initialize `canvas` element';
44
+
45
+ export type TCanvasSizeOptions = {
46
+ backstoreOnly?: boolean;
47
+ cssOnly?: boolean;
48
+ };
49
+
50
+ export type TSVGExportOptions = {
51
+ suppressPreamble?: boolean;
52
+ viewBox?: {
53
+ x: number;
54
+ y: number;
55
+ width: number;
56
+ height: number;
57
+ };
58
+ encoding?: 'UTF-8'; // test Encoding type and see what happens
59
+ width?: string;
60
+ height?: string;
61
+ reviver?: TSVGReviver;
62
+ };
63
+
64
+ type TCanvasHydrationOption = {
65
+ signal?: AbortSignal;
66
+ };
67
+
68
+ /**
69
+ * Static canvas class
70
+ * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo}
71
+ * @fires before:render
72
+ * @fires after:render
73
+ * @fires canvas:cleared
74
+ * @fires object:added
75
+ * @fires object:removed
76
+ */
77
+ // TODO: fix `EventSpec` inheritance https://github.com/microsoft/TypeScript/issues/26154#issuecomment-1366616260
78
+ export class StaticCanvas<
79
+ EventSpec extends StaticCanvasEvents = StaticCanvasEvents
80
+ > extends createCollectionMixin(CommonMethods<CanvasEvents>) {
81
+ /**
82
+ * Background color of canvas instance.
83
+ * @type {(String|TFiller)}
84
+ * @default
85
+ */
86
+ declare backgroundColor: TFiller | string;
87
+
88
+ /**
89
+ * Background image of canvas instance.
90
+ * since 2.4.0 image caching is active, please when putting an image as background, add to the
91
+ * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom
92
+ * vale. As an alternative you can disable image objectCaching
93
+ * @type FabricObject
94
+ * @default
95
+ */
96
+ declare backgroundImage: FabricObject | null;
97
+
98
+ /**
99
+ * Overlay color of canvas instance.
100
+ * @since 1.3.9
101
+ * @type {(String|TFiller)}
102
+ * @default
103
+ */
104
+ declare overlayColor: TFiller | string;
105
+
106
+ /**
107
+ * Overlay image of canvas instance.
108
+ * since 2.4.0 image caching is active, please when putting an image as overlay, add to the
109
+ * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom
110
+ * vale. As an alternative you can disable image objectCaching
111
+ * @type FabricObject
112
+ * @default
113
+ */
114
+ declare overlayImage: FabricObject | null;
115
+
116
+ /**
117
+ * Indicates whether toObject/toDatalessObject should include default values
118
+ * if set to false, takes precedence over the object value.
119
+ * @type Boolean
120
+ * @default
121
+ */
122
+ declare includeDefaultValues: boolean;
123
+
124
+ /**
125
+ * Indicates whether {@link add}, {@link insertAt} and {@link remove},
126
+ * {@link moveTo}, {@link clear} and many more, should also re-render canvas.
127
+ * Disabling this option will not give a performance boost when adding/removing a lot of objects to/from canvas at once
128
+ * since the renders are queued and executed one per frame.
129
+ * Disabling is suggested anyway and managing the renders of the app manually is not a big effort ( canvas.requestRenderAll() )
130
+ * Left default to true to do not break documentation and old app, fiddles.
131
+ * @type Boolean
132
+ * @default
133
+ */
134
+ declare renderOnAddRemove: boolean;
135
+
136
+ /**
137
+ * Indicates whether object controls (borders/controls) are rendered above overlay image
138
+ * @type Boolean
139
+ * @default
140
+ */
141
+ declare controlsAboveOverlay: boolean;
142
+
143
+ /**
144
+ * Indicates whether the browser can be scrolled when using a touchscreen and dragging on the canvas
145
+ * @type Boolean
146
+ * @default
147
+ */
148
+ declare allowTouchScrolling: boolean;
149
+
150
+ /**
151
+ * Indicates whether this canvas will use image smoothing, this is on by default in browsers
152
+ * @type Boolean
153
+ * @default
154
+ */
155
+ declare imageSmoothingEnabled: boolean;
156
+
157
+ /**
158
+ * The transformation (a Canvas 2D API transform matrix) which focuses the viewport
159
+ * @type Array
160
+ * @example <caption>Default transform</caption>
161
+ * canvas.viewportTransform = [1, 0, 0, 1, 0, 0];
162
+ * @example <caption>Scale by 70% and translate toward bottom-right by 50, without skewing</caption>
163
+ * canvas.viewportTransform = [0.7, 0, 0, 0.7, 50, 50];
164
+ * @default
165
+ */
166
+ declare viewportTransform: TMat2D;
167
+
168
+ /**
169
+ * if set to false background image is not affected by viewport transform
170
+ * @since 1.6.3
171
+ * @type Boolean
172
+ * @todo we should really find a different way to do this
173
+ * @default
174
+ */
175
+ declare backgroundVpt: boolean;
176
+
177
+ /**
178
+ * if set to false overlya image is not affected by viewport transform
179
+ * @since 1.6.3
180
+ * @type Boolean
181
+ * @todo we should really find a different way to do this
182
+ * @default
183
+ */
184
+ declare overlayVpt: boolean;
185
+
186
+ /**
187
+ * When true, canvas is scaled by devicePixelRatio for better rendering on retina screens
188
+ * @type Boolean
189
+ * @default
190
+ */
191
+ declare enableRetinaScaling: boolean;
192
+
193
+ /**
194
+ * Describe canvas element extension over design
195
+ * properties are tl,tr,bl,br.
196
+ * if canvas is not zoomed/panned those points are the four corner of canvas
197
+ * if canvas is viewportTransformed you those points indicate the extension
198
+ * of canvas element in plain untrasformed coordinates
199
+ * The coordinates get updated with @method calcViewportBoundaries.
200
+ */
201
+ declare vptCoords: TCornerPoint;
202
+
203
+ /**
204
+ * Based on vptCoords and object.aCoords, skip rendering of objects that
205
+ * are not included in current viewport.
206
+ * May greatly help in applications with crowded canvas and use of zoom/pan
207
+ * If One of the corner of the bounding box of the object is on the canvas
208
+ * the objects get rendered.
209
+ * @type Boolean
210
+ * @default
211
+ */
212
+ declare skipOffscreen: boolean;
213
+
214
+ /**
215
+ * a fabricObject that, without stroke define a clipping area with their shape. filled in black
216
+ * the clipPath object gets used when the canvas has rendered, and the context is placed in the
217
+ * top left corner of the canvas.
218
+ * clipPath will clip away controls, if you do not want this to happen use controlsAboveOverlay = true
219
+ * @type FabricObject
220
+ */
221
+ declare clipPath: FabricObject;
222
+
223
+ /**
224
+ * A reference to the canvas actual HTMLCanvasElement.
225
+ * Can be use to read the raw pixels, but never write or manipulate
226
+ * @type HTMLCanvasElement
227
+ */
228
+ declare lowerCanvasEl: HTMLCanvasElement;
229
+
230
+ declare contextContainer: CanvasRenderingContext2D;
231
+
232
+ /**
233
+ * Width in virtual/logical pixels of the canvas.
234
+ * The canvas can be larger than width if retina scaling is active
235
+ * @type number
236
+ */
237
+ declare width: number;
238
+
239
+ /**
240
+ * Height in virtual/logical pixels of the canvas.
241
+ * The canvas can be taller than width if retina scaling is active
242
+ * @type height
243
+ */
244
+ declare height: number;
245
+
246
+ /**
247
+ * If true the Canvas is in the process or has been disposed/destroyed.
248
+ * No more rendering operation will be executed on this canvas.
249
+ * @type boolean
250
+ */
251
+ declare destroyed?: boolean;
252
+
253
+ /**
254
+ * Started the process of disposing but not done yet.
255
+ * WIll likely complete the render cycle already scheduled but stopping adding more.
256
+ * @type boolean
257
+ */
258
+ declare disposed?: boolean;
259
+
260
+ /**
261
+ * Keeps a copy of the canvas style before setting retina scaling and other potions
262
+ * in order to return it to original state on dispose
263
+ * @type string
264
+ */
265
+ declare _originalCanvasStyle?: string;
266
+
267
+ declare _offset: { left: number; top: number };
268
+ protected declare hasLostContext: boolean;
269
+ protected declare nextRenderHandle: number;
270
+
271
+ // reference to
272
+ protected declare __cleanupTask?: {
273
+ (): void;
274
+ kill: (reason?: any) => void;
275
+ };
276
+
277
+ constructor(el: string | HTMLCanvasElement, options = {}) {
278
+ super();
279
+ this.set(options);
280
+ this.initElements(el);
281
+ this._setDimensionsImpl({
282
+ width: this.width || this.lowerCanvasEl.width || 0,
283
+ height: this.height || this.lowerCanvasEl.height || 0,
284
+ });
285
+ this.viewportTransform = [...this.viewportTransform];
286
+ this.calcViewportBoundaries();
287
+ }
288
+
289
+ protected initElements(el: string | HTMLCanvasElement) {
290
+ this._createLowerCanvas(el);
291
+ this._originalCanvasStyle = this.lowerCanvasEl.style.cssText;
292
+ }
293
+
294
+ add(...objects: FabricObject[]) {
295
+ const size = super.add(...objects);
296
+ objects.length > 0 && this.renderOnAddRemove && this.requestRenderAll();
297
+ return size;
298
+ }
299
+
300
+ insertAt(index: number, ...objects: FabricObject[]) {
301
+ const size = super.insertAt(index, ...objects);
302
+ objects.length > 0 && this.renderOnAddRemove && this.requestRenderAll();
303
+ return size;
304
+ }
305
+
306
+ remove(...objects: FabricObject[]) {
307
+ const removed = super.remove(...objects);
308
+ removed.length > 0 && this.renderOnAddRemove && this.requestRenderAll();
309
+ return removed;
310
+ }
311
+
312
+ _onObjectAdded(obj: FabricObject) {
313
+ if (obj.canvas && obj.canvas !== this) {
314
+ /* _DEV_MODE_START_ */
315
+ console.warn(
316
+ 'fabric.Canvas: trying to add an object that belongs to a different canvas.\n' +
317
+ 'Resulting to default behavior: removing object from previous canvas and adding to new canvas'
318
+ );
319
+ /* _DEV_MODE_END_ */
320
+ obj.canvas.remove(obj);
321
+ }
322
+ obj._set('canvas', this);
323
+ obj.setCoords();
324
+ this.fire('object:added', { target: obj });
325
+ obj.fire('added', { target: this });
326
+ }
327
+
328
+ _onObjectRemoved(obj: FabricObject) {
329
+ obj._set('canvas', undefined);
330
+ this.fire('object:removed', { target: obj });
331
+ obj.fire('removed', { target: this });
332
+ }
333
+
334
+ _onStackOrderChanged() {
335
+ this.renderOnAddRemove && this.requestRenderAll();
336
+ }
337
+
338
+ /**
339
+ * @private
340
+ */
341
+ _isRetinaScaling() {
342
+ return config.devicePixelRatio > 1 && this.enableRetinaScaling;
343
+ }
344
+
345
+ /**
346
+ * @private
347
+ * @return {Number} retinaScaling if applied, otherwise 1;
348
+ */
349
+ getRetinaScaling() {
350
+ return this._isRetinaScaling() ? Math.max(1, config.devicePixelRatio) : 1;
351
+ }
352
+
353
+ protected _initRetinaScaling() {
354
+ this.__initRetinaScaling(this.lowerCanvasEl, this.contextContainer);
355
+ }
356
+
357
+ protected __initRetinaScaling(
358
+ canvas: HTMLCanvasElement,
359
+ context: CanvasRenderingContext2D
360
+ ) {
361
+ const scaleRatio = config.devicePixelRatio;
362
+ canvas.setAttribute('width', (this.width * scaleRatio).toString());
363
+ canvas.setAttribute('height', (this.height * scaleRatio).toString());
364
+ context.scale(scaleRatio, scaleRatio);
365
+ }
366
+
367
+ /**
368
+ * Calculates canvas element offset relative to the document
369
+ * This method is also attached as "resize" event handler of window
370
+ */
371
+ calcOffset() {
372
+ return (this._offset = getElementOffset(this.lowerCanvasEl));
373
+ }
374
+
375
+ /**
376
+ * @private
377
+ */
378
+ protected _createCanvasElement() {
379
+ const element = createCanvasElement();
380
+ if (!element) {
381
+ throw new Error(CANVAS_INIT_ERROR);
382
+ }
383
+ if (typeof element.getContext === 'undefined') {
384
+ throw new Error(CANVAS_INIT_ERROR);
385
+ }
386
+ return element;
387
+ }
388
+
389
+ /**
390
+ * Creates a bottom canvas
391
+ * @private
392
+ * @param {HTMLElement} [canvasEl]
393
+ */
394
+ protected _createLowerCanvas(canvasEl: HTMLCanvasElement | string) {
395
+ // canvasEl === 'HTMLCanvasElement' does not work on jsdom/node
396
+ if (isHTMLCanvas(canvasEl)) {
397
+ this.lowerCanvasEl = canvasEl;
398
+ } else {
399
+ this.lowerCanvasEl =
400
+ (getEnv().document.getElementById(canvasEl) as HTMLCanvasElement) ||
401
+ this._createCanvasElement();
402
+ }
403
+ if (this.lowerCanvasEl.hasAttribute('data-fabric')) {
404
+ /* _DEV_MODE_START_ */
405
+ throw new Error(
406
+ 'fabric.js: trying to initialize a canvas that has already been initialized'
407
+ );
408
+ /* _DEV_MODE_END_ */
409
+ }
410
+ this.lowerCanvasEl.classList.add('lower-canvas');
411
+ this.lowerCanvasEl.setAttribute('data-fabric', 'main');
412
+ this.contextContainer = this.lowerCanvasEl.getContext('2d')!;
413
+ }
414
+
415
+ /**
416
+ * Returns canvas width (in px)
417
+ * @return {Number}
418
+ */
419
+ getWidth(): number {
420
+ return this.width;
421
+ }
422
+
423
+ /**
424
+ * Returns canvas height (in px)
425
+ * @return {Number}
426
+ */
427
+ getHeight(): number {
428
+ return this.height;
429
+ }
430
+
431
+ /**
432
+ * Sets width of this canvas instance
433
+ * @param {Number|String} value Value to set width to
434
+ * @param {Object} [options] Options object
435
+ * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions
436
+ * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions
437
+ * @deprecated will be removed in 7.0
438
+ */
439
+ setWidth(value: number, options: TCanvasSizeOptions) {
440
+ return this.setDimensions({ width: value }, options);
441
+ }
442
+
443
+ /**
444
+ * Sets height of this canvas instance
445
+ * @param {Number|String} value Value to set height to
446
+ * @param {Object} [options] Options object
447
+ * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions
448
+ * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions
449
+ * @deprecated will be removed in 7.0
450
+ */
451
+ setHeight(value: number, options: TCanvasSizeOptions) {
452
+ return this.setDimensions({ height: value }, options);
453
+ }
454
+
455
+ /**
456
+ * Internal use only
457
+ * @protected
458
+ */
459
+ protected _setDimensionsImpl(
460
+ dimensions: Partial<TSize>,
461
+ { cssOnly = false, backstoreOnly = false }: TCanvasSizeOptions = {}
462
+ ) {
463
+ Object.entries(dimensions).forEach(([prop, value]) => {
464
+ let cssValue = `${value}`;
465
+
466
+ if (!cssOnly) {
467
+ this._setBackstoreDimension(prop as keyof TSize, value);
468
+ cssValue += 'px';
469
+ this.hasLostContext = true;
470
+ }
471
+
472
+ if (!backstoreOnly) {
473
+ this._setCssDimension(prop as keyof TSize, cssValue);
474
+ }
475
+ });
476
+
477
+ this._isRetinaScaling() && this._initRetinaScaling();
478
+ this.calcOffset();
479
+ }
480
+
481
+ /**
482
+ * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em)
483
+ * @param {Object} dimensions Object with width/height properties
484
+ * @param {Number|String} [dimensions.width] Width of canvas element
485
+ * @param {Number|String} [dimensions.height] Height of canvas element
486
+ * @param {Object} [options] Options object
487
+ * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions
488
+ * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions
489
+ */
490
+ setDimensions(
491
+ dimensions: Partial<TSize>,
492
+ { cssOnly = false, backstoreOnly = false }: TCanvasSizeOptions = {}
493
+ ) {
494
+ this._setDimensionsImpl(dimensions, {
495
+ cssOnly,
496
+ backstoreOnly,
497
+ });
498
+ if (!cssOnly) {
499
+ this.requestRenderAll();
500
+ }
501
+ }
502
+
503
+ /**
504
+ * Helper for setting width/height
505
+ * @private
506
+ * @param {String} prop property (width|height)
507
+ * @param {Number} value value to set property to
508
+ * @todo subclass in canvas and handle upperCanvasEl there.
509
+ */
510
+ _setBackstoreDimension(prop: keyof TSize, value: number) {
511
+ this.lowerCanvasEl[prop] = value;
512
+ this[prop] = value;
513
+ }
514
+
515
+ /**
516
+ * Helper for setting css width/height
517
+ * @private
518
+ * @param {String} prop property (width|height)
519
+ * @param {String} value value to set property to
520
+ * @todo subclass in canvas and handle upperCanvasEl there.
521
+ */
522
+ _setCssDimension(prop: keyof TSize, value: string) {
523
+ this.lowerCanvasEl.style[prop] = value;
524
+ }
525
+
526
+ /**
527
+ * Returns canvas zoom level
528
+ * @return {Number}
529
+ */
530
+ getZoom() {
531
+ return this.viewportTransform[0];
532
+ }
533
+
534
+ /**
535
+ * Sets viewport transformation of this canvas instance
536
+ * @param {Array} vpt a Canvas 2D API transform matrix
537
+ */
538
+ setViewportTransform(vpt: TMat2D) {
539
+ const backgroundObject = this.backgroundImage,
540
+ overlayObject = this.overlayImage,
541
+ len = this._objects.length;
542
+
543
+ this.viewportTransform = vpt;
544
+ for (let i = 0; i < len; i++) {
545
+ const object = this._objects[i];
546
+ object.group || object.setCoords();
547
+ }
548
+ if (backgroundObject) {
549
+ backgroundObject.setCoords();
550
+ }
551
+ if (overlayObject) {
552
+ overlayObject.setCoords();
553
+ }
554
+ this.calcViewportBoundaries();
555
+ this.renderOnAddRemove && this.requestRenderAll();
556
+ }
557
+
558
+ /**
559
+ * Sets zoom level of this canvas instance, the zoom centered around point
560
+ * meaning that following zoom to point with the same point will have the visual
561
+ * effect of the zoom originating from that point. The point won't move.
562
+ * It has nothing to do with canvas center or visual center of the viewport.
563
+ * @param {Point} point to zoom with respect to
564
+ * @param {Number} value to set zoom to, less than 1 zooms out
565
+ */
566
+ zoomToPoint(point: Point, value: number) {
567
+ // TODO: just change the scale, preserve other transformations
568
+ const before = point,
569
+ vpt: TMat2D = [...this.viewportTransform];
570
+ const newPoint = transformPoint(point, invertTransform(vpt));
571
+ vpt[0] = value;
572
+ vpt[3] = value;
573
+ const after = transformPoint(newPoint, vpt);
574
+ vpt[4] += before.x - after.x;
575
+ vpt[5] += before.y - after.y;
576
+ this.setViewportTransform(vpt);
577
+ }
578
+
579
+ /**
580
+ * Sets zoom level of this canvas instance
581
+ * @param {Number} value to set zoom to, less than 1 zooms out
582
+ */
583
+ setZoom(value: number) {
584
+ this.zoomToPoint(new Point(0, 0), value);
585
+ }
586
+
587
+ /**
588
+ * Pan viewport so as to place point at top left corner of canvas
589
+ * @param {Point} point to move to
590
+ */
591
+ absolutePan(point: Point) {
592
+ const vpt: TMat2D = [...this.viewportTransform];
593
+ vpt[4] = -point.x;
594
+ vpt[5] = -point.y;
595
+ return this.setViewportTransform(vpt);
596
+ }
597
+
598
+ /**
599
+ * Pans viewpoint relatively
600
+ * @param {Point} point (position vector) to move by
601
+ */
602
+ relativePan(point: Point) {
603
+ return this.absolutePan(
604
+ new Point(
605
+ -point.x - this.viewportTransform[4],
606
+ -point.y - this.viewportTransform[5]
607
+ )
608
+ );
609
+ }
610
+
611
+ /**
612
+ * Returns &lt;canvas> element corresponding to this instance
613
+ * @return {HTMLCanvasElement}
614
+ */
615
+ getElement(): HTMLCanvasElement {
616
+ return this.lowerCanvasEl;
617
+ }
618
+
619
+ /**
620
+ * Clears specified context of canvas element
621
+ * @param {CanvasRenderingContext2D} ctx Context to clear
622
+ */
623
+ clearContext(ctx: CanvasRenderingContext2D) {
624
+ ctx.clearRect(0, 0, this.width, this.height);
625
+ }
626
+
627
+ /**
628
+ * Returns context of canvas where objects are drawn
629
+ * @return {CanvasRenderingContext2D}
630
+ */
631
+ getContext(): CanvasRenderingContext2D {
632
+ return this.contextContainer;
633
+ }
634
+
635
+ /**
636
+ * Clears all contexts (background, main, top) of an instance
637
+ */
638
+ clear() {
639
+ this.remove(...this.getObjects());
640
+ this.backgroundImage = null;
641
+ this.overlayImage = null;
642
+ this.backgroundColor = '';
643
+ this.overlayColor = '';
644
+ this.clearContext(this.contextContainer);
645
+ this.fire('canvas:cleared');
646
+ this.renderOnAddRemove && this.requestRenderAll();
647
+ }
648
+
649
+ /**
650
+ * Renders the canvas
651
+ */
652
+ renderAll() {
653
+ this.cancelRequestedRender();
654
+ if (this.destroyed) {
655
+ return;
656
+ }
657
+ this.renderCanvas(this.contextContainer, this._objects);
658
+ }
659
+
660
+ /**
661
+ * Function created to be instance bound at initialization
662
+ * used in requestAnimationFrame rendering
663
+ * Let the fabricJS call it. If you call it manually you could have more
664
+ * animationFrame stacking on to of each other
665
+ * for an imperative rendering, use canvas.renderAll
666
+ * @private
667
+ */
668
+ renderAndReset() {
669
+ this.nextRenderHandle = 0;
670
+ this.renderAll();
671
+ }
672
+
673
+ /**
674
+ * Append a renderAll request to next animation frame.
675
+ * unless one is already in progress, in that case nothing is done
676
+ * a boolean flag will avoid appending more.
677
+ */
678
+ requestRenderAll() {
679
+ if (!this.nextRenderHandle && !this.disposed && !this.destroyed) {
680
+ this.nextRenderHandle = requestAnimFrame(() => this.renderAndReset());
681
+ }
682
+ }
683
+
684
+ /**
685
+ * Calculate the position of the 4 corner of canvas with current viewportTransform.
686
+ * helps to determinate when an object is in the current rendering viewport using
687
+ * object absolute coordinates ( aCoords )
688
+ * @return {Object} points.tl
689
+ * @chainable
690
+ */
691
+ calcViewportBoundaries(): TCornerPoint {
692
+ const width = this.width,
693
+ height = this.height,
694
+ iVpt = invertTransform(this.viewportTransform),
695
+ a = transformPoint({ x: 0, y: 0 }, iVpt),
696
+ b = transformPoint({ x: width, y: height }, iVpt),
697
+ // we don't support vpt flipping
698
+ // but the code is robust enough to mostly work with flipping
699
+ min = a.min(b),
700
+ max = a.max(b);
701
+ return (this.vptCoords = {
702
+ tl: min,
703
+ tr: new Point(max.x, min.y),
704
+ bl: new Point(min.x, max.y),
705
+ br: max,
706
+ });
707
+ }
708
+
709
+ cancelRequestedRender() {
710
+ if (this.nextRenderHandle) {
711
+ cancelAnimFrame(this.nextRenderHandle);
712
+ this.nextRenderHandle = 0;
713
+ }
714
+ }
715
+
716
+ drawControls(ctx: CanvasRenderingContext2D) {
717
+ // Static canvas has no controls
718
+ }
719
+
720
+ /**
721
+ * Renders background, objects, overlay and controls.
722
+ * @param {CanvasRenderingContext2D} ctx
723
+ * @param {Array} objects to render
724
+ */
725
+ renderCanvas(ctx: CanvasRenderingContext2D, objects: FabricObject[]) {
726
+ if (this.destroyed) {
727
+ return;
728
+ }
729
+
730
+ const v = this.viewportTransform,
731
+ path = this.clipPath;
732
+ this.calcViewportBoundaries();
733
+ this.clearContext(ctx);
734
+ ctx.imageSmoothingEnabled = this.imageSmoothingEnabled;
735
+ // @ts-ignore node-canvas stuff
736
+ ctx.patternQuality = 'best';
737
+ this.fire('before:render', { ctx });
738
+ this._renderBackground(ctx);
739
+
740
+ ctx.save();
741
+ //apply viewport transform once for all rendering process
742
+ ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
743
+ this._renderObjects(ctx, objects);
744
+ ctx.restore();
745
+ if (!this.controlsAboveOverlay) {
746
+ this.drawControls(ctx);
747
+ }
748
+ if (path) {
749
+ path._set('canvas', this);
750
+ // needed to setup a couple of variables
751
+ path.shouldCache();
752
+ path._transformDone = true;
753
+ path.renderCache({ forClipping: true });
754
+ this.drawClipPathOnCanvas(ctx, path as TCachedFabricObject);
755
+ }
756
+ this._renderOverlay(ctx);
757
+ if (this.controlsAboveOverlay) {
758
+ this.drawControls(ctx);
759
+ }
760
+ this.fire('after:render', { ctx });
761
+
762
+ if (this.__cleanupTask) {
763
+ this.__cleanupTask();
764
+ this.__cleanupTask = undefined;
765
+ }
766
+ }
767
+
768
+ /**
769
+ * Paint the cached clipPath on the lowerCanvasEl
770
+ * @param {CanvasRenderingContext2D} ctx Context to render on
771
+ */
772
+ drawClipPathOnCanvas(
773
+ ctx: CanvasRenderingContext2D,
774
+ clipPath: TCachedFabricObject
775
+ ) {
776
+ const v = this.viewportTransform;
777
+ ctx.save();
778
+ ctx.transform(...v);
779
+ // DEBUG: uncomment this line, comment the following
780
+ // ctx.globalAlpha = 0.4;
781
+ ctx.globalCompositeOperation = 'destination-in';
782
+ clipPath.transform(ctx);
783
+ ctx.scale(1 / clipPath.zoomX, 1 / clipPath.zoomY);
784
+ ctx.drawImage(
785
+ clipPath._cacheCanvas,
786
+ -clipPath.cacheTranslationX,
787
+ -clipPath.cacheTranslationY
788
+ );
789
+ ctx.restore();
790
+ }
791
+
792
+ /**
793
+ * @private
794
+ * @param {CanvasRenderingContext2D} ctx Context to render on
795
+ * @param {Array} objects to render
796
+ */
797
+ _renderObjects(ctx: CanvasRenderingContext2D, objects: FabricObject[]) {
798
+ for (let i = 0, len = objects.length; i < len; ++i) {
799
+ objects[i] && objects[i].render(ctx);
800
+ }
801
+ }
802
+
803
+ /**
804
+ * @private
805
+ * @param {CanvasRenderingContext2D} ctx Context to render on
806
+ * @param {string} property 'background' or 'overlay'
807
+ */
808
+ _renderBackgroundOrOverlay(
809
+ ctx: CanvasRenderingContext2D,
810
+ property: 'background' | 'overlay'
811
+ ) {
812
+ const fill = this[`${property}Color`],
813
+ object = this[`${property}Image`],
814
+ v = this.viewportTransform,
815
+ needsVpt = this[`${property}Vpt`];
816
+ if (!fill && !object) {
817
+ return;
818
+ }
819
+ const isAFiller = isFiller(fill);
820
+ if (fill) {
821
+ ctx.save();
822
+ ctx.beginPath();
823
+ ctx.moveTo(0, 0);
824
+ ctx.lineTo(this.width, 0);
825
+ ctx.lineTo(this.width, this.height);
826
+ ctx.lineTo(0, this.height);
827
+ ctx.closePath();
828
+ ctx.fillStyle = isAFiller ? fill.toLive(ctx /* this */)! : fill;
829
+ if (needsVpt) {
830
+ ctx.transform(...v);
831
+ }
832
+ if (isAFiller) {
833
+ ctx.transform(1, 0, 0, 1, fill.offsetX || 0, fill.offsetY || 0);
834
+ const m = ((fill as Gradient<'linear'>).gradientTransform ||
835
+ (fill as Pattern).patternTransform) as TMat2D;
836
+ m && ctx.transform(...m);
837
+ }
838
+ ctx.fill();
839
+ ctx.restore();
840
+ }
841
+ if (object) {
842
+ ctx.save();
843
+ if (needsVpt) {
844
+ ctx.transform(...v);
845
+ }
846
+ object.render(ctx);
847
+ ctx.restore();
848
+ }
849
+ }
850
+
851
+ /**
852
+ * @private
853
+ * @param {CanvasRenderingContext2D} ctx Context to render on
854
+ */
855
+ _renderBackground(ctx: CanvasRenderingContext2D) {
856
+ this._renderBackgroundOrOverlay(ctx, 'background');
857
+ }
858
+
859
+ /**
860
+ * @private
861
+ * @param {CanvasRenderingContext2D} ctx Context to render on
862
+ */
863
+ _renderOverlay(ctx: CanvasRenderingContext2D) {
864
+ this._renderBackgroundOrOverlay(ctx, 'overlay');
865
+ }
866
+
867
+ /**
868
+ * Returns coordinates of a center of canvas.
869
+ * Returned value is an object with top and left properties
870
+ * @return {Object} object with "top" and "left" number values
871
+ * @deprecated migrate to `getCenterPoint`
872
+ */
873
+ getCenter() {
874
+ return {
875
+ top: this.height / 2,
876
+ left: this.width / 2,
877
+ };
878
+ }
879
+
880
+ /**
881
+ * Returns coordinates of a center of canvas.
882
+ * @return {Point}
883
+ */
884
+ getCenterPoint() {
885
+ return new Point(this.width / 2, this.height / 2);
886
+ }
887
+
888
+ /**
889
+ * Centers object horizontally in the canvas
890
+ */
891
+ centerObjectH(object: FabricObject) {
892
+ return this._centerObject(
893
+ object,
894
+ new Point(this.getCenterPoint().x, object.getCenterPoint().y)
895
+ );
896
+ }
897
+
898
+ /**
899
+ * Centers object vertically in the canvas
900
+ * @param {FabricObject} object Object to center vertically
901
+ */
902
+ centerObjectV(object: FabricObject) {
903
+ return this._centerObject(
904
+ object,
905
+ new Point(object.getCenterPoint().x, this.getCenterPoint().y)
906
+ );
907
+ }
908
+
909
+ /**
910
+ * Centers object vertically and horizontally in the canvas
911
+ * @param {FabricObject} object Object to center vertically and horizontally
912
+ */
913
+ centerObject(object: FabricObject) {
914
+ return this._centerObject(object, this.getCenterPoint());
915
+ }
916
+
917
+ /**
918
+ * Centers object vertically and horizontally in the viewport
919
+ * @param {FabricObject} object Object to center vertically and horizontally
920
+ */
921
+ viewportCenterObject(object: FabricObject) {
922
+ return this._centerObject(object, this.getVpCenter());
923
+ }
924
+
925
+ /**
926
+ * Centers object horizontally in the viewport, object.top is unchanged
927
+ * @param {FabricObject} object Object to center vertically and horizontally
928
+ */
929
+ viewportCenterObjectH(object: FabricObject) {
930
+ return this._centerObject(
931
+ object,
932
+ new Point(this.getVpCenter().x, object.getCenterPoint().y)
933
+ );
934
+ }
935
+
936
+ /**
937
+ * Centers object Vertically in the viewport, object.top is unchanged
938
+ * @param {FabricObject} object Object to center vertically and horizontally
939
+ */
940
+ viewportCenterObjectV(object: FabricObject) {
941
+ return this._centerObject(
942
+ object,
943
+ new Point(object.getCenterPoint().x, this.getVpCenter().y)
944
+ );
945
+ }
946
+
947
+ /**
948
+ * Calculate the point in canvas that correspond to the center of actual viewport.
949
+ * @return {Point} vpCenter, viewport center
950
+ */
951
+ getVpCenter(): Point {
952
+ return transformPoint(
953
+ this.getCenterPoint(),
954
+ invertTransform(this.viewportTransform)
955
+ );
956
+ }
957
+
958
+ /**
959
+ * @private
960
+ * @param {FabricObject} object Object to center
961
+ * @param {Point} center Center point
962
+ */
963
+ _centerObject(object: FabricObject, center: Point) {
964
+ object.setXY(center, 'center', 'center');
965
+ object.setCoords();
966
+ this.renderOnAddRemove && this.requestRenderAll();
967
+ }
968
+
969
+ /**
970
+ * Returns dataless JSON representation of canvas
971
+ * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
972
+ * @return {String} json string
973
+ */
974
+ toDatalessJSON(propertiesToInclude?: string[]) {
975
+ return this.toDatalessObject(propertiesToInclude);
976
+ }
977
+
978
+ /**
979
+ * Returns object representation of canvas
980
+ * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
981
+ * @return {Object} object representation of an instance
982
+ */
983
+ toObject(propertiesToInclude?: string[]) {
984
+ return this._toObjectMethod('toObject', propertiesToInclude);
985
+ }
986
+
987
+ /**
988
+ * Returns Object representation of canvas
989
+ * this alias is provided because if you call JSON.stringify on an instance,
990
+ * the toJSON object will be invoked if it exists.
991
+ * Having a toJSON method means you can do JSON.stringify(myCanvas)
992
+ * @return {Object} JSON compatible object
993
+ * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}
994
+ * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo}
995
+ * @example <caption>JSON without additional properties</caption>
996
+ * var json = canvas.toJSON();
997
+ * @example <caption>JSON with additional properties included</caption>
998
+ * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY']);
999
+ * @example <caption>JSON without default values</caption>
1000
+ * var json = canvas.toJSON();
1001
+ */
1002
+ toJSON() {
1003
+ return this.toObject();
1004
+ }
1005
+
1006
+ /**
1007
+ * Returns dataless object representation of canvas
1008
+ * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
1009
+ * @return {Object} object representation of an instance
1010
+ */
1011
+ toDatalessObject(propertiesToInclude?: string[]) {
1012
+ return this._toObjectMethod('toDatalessObject', propertiesToInclude);
1013
+ }
1014
+
1015
+ /**
1016
+ * @private
1017
+ */
1018
+ _toObjectMethod(
1019
+ methodName: TValidToObjectMethod,
1020
+ propertiesToInclude?: string[]
1021
+ ) {
1022
+ const clipPath = this.clipPath;
1023
+ const clipPathData =
1024
+ clipPath && !clipPath.excludeFromExport
1025
+ ? this._toObject(clipPath, methodName, propertiesToInclude)
1026
+ : null;
1027
+ return {
1028
+ version: VERSION,
1029
+ ...pick(this, propertiesToInclude as (keyof this)[]),
1030
+ objects: this._objects
1031
+ .filter((object) => !object.excludeFromExport)
1032
+ .map((instance) =>
1033
+ this._toObject(instance, methodName, propertiesToInclude)
1034
+ ),
1035
+ ...this.__serializeBgOverlay(methodName, propertiesToInclude),
1036
+ ...(clipPathData ? { clipPath: clipPathData } : null),
1037
+ };
1038
+ }
1039
+
1040
+ /**
1041
+ * @private
1042
+ */
1043
+ _toObject(
1044
+ instance: FabricObject,
1045
+ methodName: TValidToObjectMethod,
1046
+ propertiesToInclude?: string[]
1047
+ ) {
1048
+ let originalValue;
1049
+
1050
+ if (!this.includeDefaultValues) {
1051
+ originalValue = instance.includeDefaultValues;
1052
+ instance.includeDefaultValues = false;
1053
+ }
1054
+
1055
+ const object = instance[methodName](propertiesToInclude);
1056
+ if (!this.includeDefaultValues) {
1057
+ instance.includeDefaultValues = !!originalValue;
1058
+ }
1059
+ return object;
1060
+ }
1061
+
1062
+ /**
1063
+ * @private
1064
+ */
1065
+ __serializeBgOverlay(
1066
+ methodName: TValidToObjectMethod,
1067
+ propertiesToInclude?: string[]
1068
+ ) {
1069
+ const data: any = {},
1070
+ bgImage = this.backgroundImage,
1071
+ overlayImage = this.overlayImage,
1072
+ bgColor = this.backgroundColor,
1073
+ overlayColor = this.overlayColor;
1074
+
1075
+ if (isFiller(bgColor)) {
1076
+ if (!bgColor.excludeFromExport) {
1077
+ data.background = bgColor.toObject(propertiesToInclude);
1078
+ }
1079
+ } else if (bgColor) {
1080
+ data.background = bgColor;
1081
+ }
1082
+
1083
+ if (isFiller(overlayColor)) {
1084
+ if (!overlayColor.excludeFromExport) {
1085
+ data.overlay = overlayColor.toObject(propertiesToInclude);
1086
+ }
1087
+ } else if (overlayColor) {
1088
+ data.overlay = overlayColor;
1089
+ }
1090
+
1091
+ if (bgImage && !bgImage.excludeFromExport) {
1092
+ data.backgroundImage = this._toObject(
1093
+ bgImage,
1094
+ methodName,
1095
+ propertiesToInclude
1096
+ );
1097
+ }
1098
+ if (overlayImage && !overlayImage.excludeFromExport) {
1099
+ data.overlayImage = this._toObject(
1100
+ overlayImage,
1101
+ methodName,
1102
+ propertiesToInclude
1103
+ );
1104
+ }
1105
+
1106
+ return data;
1107
+ }
1108
+
1109
+ /* _TO_SVG_START_ */
1110
+ /**
1111
+ * When true, getSvgTransform() will apply the StaticCanvas.viewportTransform to the SVG transformation. When true,
1112
+ * a zoomed canvas will then produce zoomed SVG output.
1113
+ * @type Boolean
1114
+ * @default
1115
+ */
1116
+ declare svgViewportTransformation: boolean;
1117
+
1118
+ /**
1119
+ * Returns SVG representation of canvas
1120
+ * @function
1121
+ * @param {Object} [options] Options object for SVG output
1122
+ * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included
1123
+ * @param {Object} [options.viewBox] SVG viewbox object
1124
+ * @param {Number} [options.viewBox.x] x-coordinate of viewbox
1125
+ * @param {Number} [options.viewBox.y] y-coordinate of viewbox
1126
+ * @param {Number} [options.viewBox.width] Width of viewbox
1127
+ * @param {Number} [options.viewBox.height] Height of viewbox
1128
+ * @param {String} [options.encoding=UTF-8] Encoding of SVG output
1129
+ * @param {String} [options.width] desired width of svg with or without units
1130
+ * @param {String} [options.height] desired height of svg with or without units
1131
+ * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation.
1132
+ * @return {String} SVG string
1133
+ * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}
1134
+ * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo}
1135
+ * @example <caption>Normal SVG output</caption>
1136
+ * var svg = canvas.toSVG();
1137
+ * @example <caption>SVG output without preamble (without &lt;?xml ../>)</caption>
1138
+ * var svg = canvas.toSVG({suppressPreamble: true});
1139
+ * @example <caption>SVG output with viewBox attribute</caption>
1140
+ * var svg = canvas.toSVG({
1141
+ * viewBox: {
1142
+ * x: 100,
1143
+ * y: 100,
1144
+ * width: 200,
1145
+ * height: 300
1146
+ * }
1147
+ * });
1148
+ * @example <caption>SVG output with different encoding (default: UTF-8)</caption>
1149
+ * var svg = canvas.toSVG({encoding: 'ISO-8859-1'});
1150
+ * @example <caption>Modify SVG output with reviver function</caption>
1151
+ * var svg = canvas.toSVG(null, function(svg) {
1152
+ * return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', '');
1153
+ * });
1154
+ */
1155
+ toSVG(options: TSVGExportOptions = {}, reviver: TSVGReviver) {
1156
+ options.reviver = reviver;
1157
+ const markup: string[] = [];
1158
+
1159
+ this._setSVGPreamble(markup, options);
1160
+ this._setSVGHeader(markup, options);
1161
+ if (this.clipPath) {
1162
+ markup.push(`<g clip-path="url(#${this.clipPath.clipPathId})" >\n`);
1163
+ }
1164
+ this._setSVGBgOverlayColor(markup, 'background');
1165
+ this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver);
1166
+ this._setSVGObjects(markup, reviver);
1167
+ if (this.clipPath) {
1168
+ markup.push('</g>\n');
1169
+ }
1170
+ this._setSVGBgOverlayColor(markup, 'overlay');
1171
+ this._setSVGBgOverlayImage(markup, 'overlayImage', reviver);
1172
+
1173
+ markup.push('</svg>');
1174
+
1175
+ return markup.join('');
1176
+ }
1177
+
1178
+ /**
1179
+ * @private
1180
+ */
1181
+ _setSVGPreamble(markup: string[], options: TSVGExportOptions): void {
1182
+ if (options.suppressPreamble) {
1183
+ return;
1184
+ }
1185
+ markup.push(
1186
+ '<?xml version="1.0" encoding="',
1187
+ options.encoding || 'UTF-8',
1188
+ '" standalone="no" ?>\n',
1189
+ '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" ',
1190
+ '"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n'
1191
+ );
1192
+ }
1193
+
1194
+ /**
1195
+ * @private
1196
+ */
1197
+ _setSVGHeader(markup: string[], options: TSVGExportOptions): void {
1198
+ const width = options.width || `${this.width}`,
1199
+ height = options.height || `${this.height}`,
1200
+ NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS,
1201
+ optViewBox = options.viewBox;
1202
+ let viewBox: string;
1203
+ if (optViewBox) {
1204
+ viewBox = `viewBox="${optViewBox.x} ${optViewBox.y} ${optViewBox.width} ${optViewBox.height}" `;
1205
+ } else if (this.svgViewportTransformation) {
1206
+ const vpt = this.viewportTransform;
1207
+ viewBox = `viewBox="${toFixed(
1208
+ -vpt[4] / vpt[0],
1209
+ NUM_FRACTION_DIGITS
1210
+ )} ${toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS)} ${toFixed(
1211
+ this.width / vpt[0],
1212
+ NUM_FRACTION_DIGITS
1213
+ )} ${toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS)}" `;
1214
+ } else {
1215
+ viewBox = `viewBox="0 0 ${this.width} ${this.height}" `;
1216
+ }
1217
+
1218
+ markup.push(
1219
+ '<svg ',
1220
+ 'xmlns="http://www.w3.org/2000/svg" ',
1221
+ 'xmlns:xlink="http://www.w3.org/1999/xlink" ',
1222
+ 'version="1.1" ',
1223
+ 'width="',
1224
+ width,
1225
+ '" ',
1226
+ 'height="',
1227
+ height,
1228
+ '" ',
1229
+ viewBox,
1230
+ 'xml:space="preserve">\n',
1231
+ '<desc>Created with Fabric.js ',
1232
+ VERSION,
1233
+ '</desc>\n',
1234
+ '<defs>\n',
1235
+ this.createSVGFontFacesMarkup(),
1236
+ this.createSVGRefElementsMarkup(),
1237
+ this.createSVGClipPathMarkup(options),
1238
+ '</defs>\n'
1239
+ );
1240
+ }
1241
+
1242
+ createSVGClipPathMarkup(options: TSVGExportOptions): string {
1243
+ const clipPath = this.clipPath;
1244
+ if (clipPath) {
1245
+ clipPath.clipPathId = `CLIPPATH_${uid()}`;
1246
+ return (
1247
+ '<clipPath id="' +
1248
+ clipPath.clipPathId +
1249
+ '" >\n' +
1250
+ this.clipPath.toClipPathSVG(options.reviver) +
1251
+ '</clipPath>\n'
1252
+ );
1253
+ }
1254
+ return '';
1255
+ }
1256
+
1257
+ /**
1258
+ * Creates markup containing SVG referenced elements like patterns, gradients etc.
1259
+ * @return {String}
1260
+ */
1261
+ createSVGRefElementsMarkup(): string {
1262
+ return (['background', 'overlay'] as const)
1263
+ .map((prop) => {
1264
+ const fill = this[`${prop}Color`];
1265
+ if (isFiller(fill)) {
1266
+ const shouldTransform = this[`${prop}Vpt`],
1267
+ vpt = this.viewportTransform,
1268
+ object = {
1269
+ width: this.width / (shouldTransform ? vpt[0] : 1),
1270
+ height: this.height / (shouldTransform ? vpt[3] : 1),
1271
+ };
1272
+ return fill.toSVG(object as Rect, {
1273
+ additionalTransform: shouldTransform ? matrixToSVG(vpt) : '',
1274
+ });
1275
+ }
1276
+ })
1277
+ .join('');
1278
+ }
1279
+
1280
+ /**
1281
+ * Creates markup containing SVG font faces,
1282
+ * font URLs for font faces must be collected by developers
1283
+ * and are not extracted from the DOM by fabricjs
1284
+ * @param {Array} objects Array of fabric objects
1285
+ * @return {String}
1286
+ */
1287
+ createSVGFontFacesMarkup(): string {
1288
+ const objects: FabricObject[] = [],
1289
+ fontList: Record<string, boolean> = {},
1290
+ fontPaths = config.fontPaths;
1291
+
1292
+ this._objects.forEach(function add(object) {
1293
+ objects.push(object);
1294
+ if (isCollection(object)) {
1295
+ object._objects.forEach(add);
1296
+ }
1297
+ });
1298
+
1299
+ objects.forEach((obj) => {
1300
+ if (!isTextObject(obj)) {
1301
+ return;
1302
+ }
1303
+ let fontFamily = obj.fontFamily;
1304
+ if (fontList[fontFamily] || !fontPaths[fontFamily]) {
1305
+ return;
1306
+ }
1307
+ fontList[fontFamily] = true;
1308
+ if (!obj.styles) {
1309
+ return;
1310
+ }
1311
+ Object.values(obj.styles).forEach((styleRow) => {
1312
+ Object.values(styleRow).forEach((textCharStyle) => {
1313
+ fontFamily = textCharStyle.fontFamily;
1314
+ if (!fontList[fontFamily] && fontPaths[fontFamily]) {
1315
+ fontList[fontFamily] = true;
1316
+ }
1317
+ });
1318
+ });
1319
+ });
1320
+
1321
+ const fontListMarkup = Object.keys(fontList)
1322
+ .map(
1323
+ (fontFamily) =>
1324
+ `\t\t@font-face {\n\t\t\tfont-family: '${fontFamily}';\n\t\t\tsrc: url('${fontPaths[fontFamily]}');\n\t\t}\n`
1325
+ )
1326
+ .join('');
1327
+
1328
+ if (fontListMarkup) {
1329
+ return `\t<style type="text/css"><![CDATA[\n${fontListMarkup}]]></style>\n`;
1330
+ }
1331
+ return '';
1332
+ }
1333
+
1334
+ /**
1335
+ * @private
1336
+ */
1337
+ _setSVGObjects(markup: string[], reviver: TSVGReviver) {
1338
+ this.forEachObject((fabricObject) => {
1339
+ if (fabricObject.excludeFromExport) {
1340
+ return;
1341
+ }
1342
+ this._setSVGObject(markup, fabricObject, reviver);
1343
+ });
1344
+ }
1345
+
1346
+ /**
1347
+ * This is its own function because the Canvas ( non static ) requires extra code here
1348
+ * @private
1349
+ */
1350
+ _setSVGObject(
1351
+ markup: string[],
1352
+ instance: FabricObject,
1353
+ reviver: TSVGReviver
1354
+ ) {
1355
+ markup.push(instance.toSVG(reviver));
1356
+ }
1357
+
1358
+ /**
1359
+ * @private
1360
+ */
1361
+ _setSVGBgOverlayImage(
1362
+ markup: string[],
1363
+ property: 'overlayImage' | 'backgroundImage',
1364
+ reviver: TSVGReviver
1365
+ ) {
1366
+ const bgOrOverlay = this[property];
1367
+ if (bgOrOverlay && !bgOrOverlay.excludeFromExport && bgOrOverlay.toSVG) {
1368
+ markup.push(bgOrOverlay.toSVG(reviver));
1369
+ }
1370
+ }
1371
+
1372
+ /**
1373
+ * @TODO this seems to handle patterns but fail at gradients.
1374
+ * @private
1375
+ */
1376
+ _setSVGBgOverlayColor(markup: string[], property: 'background' | 'overlay') {
1377
+ const filler = this[`${property}Color`];
1378
+ if (!filler) {
1379
+ return;
1380
+ }
1381
+ if (isFiller(filler)) {
1382
+ const repeat = (filler as Pattern).repeat || '',
1383
+ finalWidth = this.width,
1384
+ finalHeight = this.height,
1385
+ shouldInvert = this[`${property}Vpt`],
1386
+ additionalTransform = shouldInvert
1387
+ ? matrixToSVG(invertTransform(this.viewportTransform))
1388
+ : '';
1389
+ markup.push(
1390
+ `<rect transform="${additionalTransform} translate(${finalWidth / 2},${
1391
+ finalHeight / 2
1392
+ })" x="${filler.offsetX - finalWidth / 2}" y="${
1393
+ filler.offsetY - finalHeight / 2
1394
+ }" width="${
1395
+ (repeat === 'repeat-y' || repeat === 'no-repeat') && isPattern(filler)
1396
+ ? filler.source.width
1397
+ : finalWidth
1398
+ }" height="${
1399
+ (repeat === 'repeat-x' || repeat === 'no-repeat') && isPattern(filler)
1400
+ ? filler.source.height
1401
+ : finalHeight
1402
+ }" fill="url(#SVGID_${filler.id})"></rect>\n`
1403
+ );
1404
+ } else {
1405
+ markup.push(
1406
+ '<rect x="0" y="0" width="100%" height="100%" ',
1407
+ 'fill="',
1408
+ filler,
1409
+ '"',
1410
+ '></rect>\n'
1411
+ );
1412
+ }
1413
+ }
1414
+ /* _TO_SVG_END_ */
1415
+
1416
+ /**
1417
+ * Populates canvas with data from the specified JSON.
1418
+ * JSON format must conform to the one of {@link fabric.Canvas#toJSON}
1419
+ *
1420
+ * **IMPORTANT**: It is recommended to abort loading tasks before calling this method to prevent race conditions and unnecessary networking
1421
+ *
1422
+ * @param {String|Object} json JSON string or object
1423
+ * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.
1424
+ * @param {Object} [options] options
1425
+ * @param {AbortSignal} [options.signal] see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
1426
+ * @return {Promise<Canvas | StaticCanvas>} instance
1427
+ * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}
1428
+ * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo}
1429
+ * @example <caption>loadFromJSON</caption>
1430
+ * canvas.loadFromJSON(json).then((canvas) => canvas.requestRenderAll());
1431
+ * @example <caption>loadFromJSON with reviver</caption>
1432
+ * canvas.loadFromJSON(json, function(o, object) {
1433
+ * // `o` = json object
1434
+ * // `object` = fabric.Object instance
1435
+ * // ... do some stuff ...
1436
+ * }).then((canvas) => {
1437
+ * ... canvas is restored, add your code.
1438
+ * });
1439
+ *
1440
+ */
1441
+ loadFromJSON(
1442
+ json: string | Record<string, any>,
1443
+ reviver?: EnlivenObjectOptions['reviver'],
1444
+ { signal }: TCanvasHydrationOption = {}
1445
+ ): Promise<this> {
1446
+ if (!json) {
1447
+ return Promise.reject(new Error('fabric.js: `json` is undefined'));
1448
+ }
1449
+
1450
+ // parse json if it wasn't already
1451
+ const serialized = typeof json === 'string' ? JSON.parse(json) : json;
1452
+ const {
1453
+ objects = [],
1454
+ backgroundImage,
1455
+ background,
1456
+ overlayImage,
1457
+ overlay,
1458
+ clipPath,
1459
+ } = serialized;
1460
+ const renderOnAddRemove = this.renderOnAddRemove;
1461
+ this.renderOnAddRemove = false;
1462
+
1463
+ return Promise.all([
1464
+ enlivenObjects(objects, {
1465
+ reviver,
1466
+ signal,
1467
+ }),
1468
+ enlivenObjectEnlivables(
1469
+ {
1470
+ backgroundImage,
1471
+ backgroundColor: background,
1472
+ overlayImage,
1473
+ overlayColor: overlay,
1474
+ clipPath,
1475
+ },
1476
+ { signal }
1477
+ ),
1478
+ ]).then(([enlived, enlivedMap]) => {
1479
+ this.clear();
1480
+ this.add(...enlived);
1481
+ this.set(serialized);
1482
+ this.set(enlivedMap);
1483
+ this.renderOnAddRemove = renderOnAddRemove;
1484
+ return this;
1485
+ });
1486
+ }
1487
+
1488
+ /**
1489
+ * Clones canvas instance
1490
+ * @param {string[]} [properties] Array of properties to include in the cloned canvas and children
1491
+ */
1492
+ clone(properties: string[]) {
1493
+ const data = this.toObject(properties);
1494
+ const canvas = this.cloneWithoutData();
1495
+ return canvas.loadFromJSON(data);
1496
+ }
1497
+
1498
+ /**
1499
+ * Clones canvas instance without cloning existing data.
1500
+ * This essentially copies canvas dimensions since loadFromJSON does not affect canvas size.
1501
+ */
1502
+ cloneWithoutData() {
1503
+ const el = createCanvasElement();
1504
+ el.width = this.width;
1505
+ el.height = this.height;
1506
+ return new (this.constructor as Constructor<this>)(el);
1507
+ }
1508
+
1509
+ /**
1510
+ * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately
1511
+ * @param {Object} [options] Options object
1512
+ * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png"
1513
+ * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.
1514
+ * @param {Number} [options.multiplier=1] Multiplier to scale by, to have consistent
1515
+ * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14
1516
+ * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14
1517
+ * @param {Number} [options.width] Cropping width. Introduced in v1.2.14
1518
+ * @param {Number} [options.height] Cropping height. Introduced in v1.2.14
1519
+ * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 2.0.0
1520
+ * @param {(object: fabric.Object) => boolean} [options.filter] Function to filter objects.
1521
+ * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format
1522
+ * @see {@link https://jsfiddle.net/xsjua1rd/ demo}
1523
+ * @example <caption>Generate jpeg dataURL with lower quality</caption>
1524
+ * var dataURL = canvas.toDataURL({
1525
+ * format: 'jpeg',
1526
+ * quality: 0.8
1527
+ * });
1528
+ * @example <caption>Generate cropped png dataURL (clipping of canvas)</caption>
1529
+ * var dataURL = canvas.toDataURL({
1530
+ * format: 'png',
1531
+ * left: 100,
1532
+ * top: 100,
1533
+ * width: 200,
1534
+ * height: 200
1535
+ * });
1536
+ * @example <caption>Generate double scaled png dataURL</caption>
1537
+ * var dataURL = canvas.toDataURL({
1538
+ * format: 'png',
1539
+ * multiplier: 2
1540
+ * });
1541
+ * @example <caption>Generate dataURL with objects that overlap a specified object</caption>
1542
+ * var myObject;
1543
+ * var dataURL = canvas.toDataURL({
1544
+ * filter: (object) => object.isContainedWithinObject(myObject) || object.intersectsWithObject(myObject)
1545
+ * });
1546
+ */
1547
+ toDataURL(options = {} as TDataUrlOptions): string {
1548
+ const {
1549
+ format = ImageFormat.png,
1550
+ quality = 1,
1551
+ multiplier = 1,
1552
+ enableRetinaScaling = false,
1553
+ } = options;
1554
+ const finalMultiplier =
1555
+ multiplier * (enableRetinaScaling ? this.getRetinaScaling() : 1);
1556
+
1557
+ return toDataURL(
1558
+ this.toCanvasElement(finalMultiplier, options),
1559
+ format,
1560
+ quality
1561
+ );
1562
+ }
1563
+
1564
+ /**
1565
+ * Create a new HTMLCanvas element painted with the current canvas content.
1566
+ * No need to resize the actual one or repaint it.
1567
+ * Will transfer object ownership to a new canvas, paint it, and set everything back.
1568
+ * This is an intermediary step used to get to a dataUrl but also it is useful to
1569
+ * create quick image copies of a canvas without passing for the dataUrl string
1570
+ * @param {Number} [multiplier] a zoom factor.
1571
+ * @param {Object} [options] Cropping informations
1572
+ * @param {Number} [options.left] Cropping left offset.
1573
+ * @param {Number} [options.top] Cropping top offset.
1574
+ * @param {Number} [options.width] Cropping width.
1575
+ * @param {Number} [options.height] Cropping height.
1576
+ * @param {(object: fabric.Object) => boolean} [options.filter] Function to filter objects.
1577
+ */
1578
+ toCanvasElement(
1579
+ multiplier = 1,
1580
+ { width, height, left, top, filter } = {} as TToCanvasElementOptions
1581
+ ): HTMLCanvasElement {
1582
+ const scaledWidth = (width || this.width) * multiplier,
1583
+ scaledHeight = (height || this.height) * multiplier,
1584
+ zoom = this.getZoom(),
1585
+ originalWidth = this.width,
1586
+ originalHeight = this.height,
1587
+ newZoom = zoom * multiplier,
1588
+ vp = this.viewportTransform,
1589
+ translateX = (vp[4] - (left || 0)) * multiplier,
1590
+ translateY = (vp[5] - (top || 0)) * multiplier,
1591
+ newVp = [newZoom, 0, 0, newZoom, translateX, translateY] as TMat2D,
1592
+ originalRetina = this.enableRetinaScaling,
1593
+ canvasEl = createCanvasElement(),
1594
+ objectsToRender = filter
1595
+ ? this._objects.filter((obj) => filter(obj))
1596
+ : this._objects;
1597
+ canvasEl.width = scaledWidth;
1598
+ canvasEl.height = scaledHeight;
1599
+ this.enableRetinaScaling = false;
1600
+ this.viewportTransform = newVp;
1601
+ this.width = scaledWidth;
1602
+ this.height = scaledHeight;
1603
+ this.calcViewportBoundaries();
1604
+ this.renderCanvas(canvasEl.getContext('2d')!, objectsToRender);
1605
+ this.viewportTransform = vp;
1606
+ this.width = originalWidth;
1607
+ this.height = originalHeight;
1608
+ this.calcViewportBoundaries();
1609
+ this.enableRetinaScaling = originalRetina;
1610
+ return canvasEl;
1611
+ }
1612
+
1613
+ /**
1614
+ * Waits until rendering has settled to destroy the canvas
1615
+ * @returns {Promise<boolean>} a promise resolving to `true` once the canvas has been destroyed or to `false` if the canvas has was already destroyed
1616
+ * @throws if aborted by a consequent call
1617
+ */
1618
+ dispose() {
1619
+ this.disposed = true;
1620
+ return new Promise<boolean>((resolve, reject) => {
1621
+ const task = () => {
1622
+ this.destroy();
1623
+ resolve(true);
1624
+ };
1625
+ task.kill = reject;
1626
+ if (this.__cleanupTask) {
1627
+ this.__cleanupTask.kill('aborted');
1628
+ }
1629
+
1630
+ if (this.destroyed) {
1631
+ resolve(false);
1632
+ } else if (this.nextRenderHandle) {
1633
+ this.__cleanupTask = task;
1634
+ } else {
1635
+ task();
1636
+ }
1637
+ });
1638
+ }
1639
+
1640
+ /**
1641
+ * Clears the canvas element, disposes objects and frees resources
1642
+ *
1643
+ * **CAUTION**:
1644
+ *
1645
+ * This method is **UNSAFE**.
1646
+ * You may encounter a race condition using it if there's a requested render.
1647
+ * Call this method only if you are sure rendering has settled.
1648
+ * Consider using {@link dispose} as it is **SAFE**
1649
+ *
1650
+ * @private
1651
+ */
1652
+ destroy() {
1653
+ this.destroyed = true;
1654
+ this.cancelRequestedRender();
1655
+ this.forEachObject((object) => object.dispose());
1656
+ this._objects = [];
1657
+ if (this.backgroundImage && this.backgroundImage.dispose) {
1658
+ this.backgroundImage.dispose();
1659
+ }
1660
+ this.backgroundImage = null;
1661
+ if (this.overlayImage && this.overlayImage.dispose) {
1662
+ this.overlayImage.dispose();
1663
+ }
1664
+ this.overlayImage = null;
1665
+ // @ts-expect-error disposing
1666
+ this.contextContainer = null;
1667
+ const canvasElement = this.lowerCanvasEl;
1668
+ // @ts-expect-error disposing
1669
+ this.lowerCanvasEl = undefined;
1670
+ // restore canvas style and attributes
1671
+ canvasElement.classList.remove('lower-canvas');
1672
+ canvasElement.removeAttribute('data-fabric');
1673
+ // restore canvas size to original size in case retina scaling was applied
1674
+ canvasElement.setAttribute('width', `${this.width}`);
1675
+ canvasElement.setAttribute('height', `${this.height}`);
1676
+ canvasElement.style.cssText = this._originalCanvasStyle || '';
1677
+ this._originalCanvasStyle = undefined;
1678
+ cleanUpJsdomNode(canvasElement);
1679
+ }
1680
+
1681
+ /**
1682
+ * Returns a string representation of an instance
1683
+ * @return {String} string representation of an instance
1684
+ */
1685
+ toString() {
1686
+ return `#<Canvas (${this.complexity()}): { objects: ${
1687
+ this._objects.length
1688
+ } }>`;
1689
+ }
1690
+ }
1691
+
1692
+ Object.assign(StaticCanvas.prototype, {
1693
+ backgroundColor: '',
1694
+ backgroundImage: null,
1695
+ overlayColor: '',
1696
+ overlayImage: null,
1697
+ includeDefaultValues: true,
1698
+ renderOnAddRemove: true,
1699
+ controlsAboveOverlay: false,
1700
+ allowTouchScrolling: false,
1701
+ imageSmoothingEnabled: true,
1702
+ viewportTransform: iMatrix.concat(),
1703
+ backgroundVpt: true,
1704
+ overlayVpt: true,
1705
+ enableRetinaScaling: true,
1706
+ svgViewportTransformation: true,
1707
+ skipOffscreen: true,
1708
+ clipPath: undefined,
1709
+ });