fabric 5.3.0 → 6.0.0-beta10

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