fabric 5.3.0 → 6.0.0-beta3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (604) hide show
  1. package/.babelrc +11 -0
  2. package/.babelrcAlt +19 -0
  3. package/.browserslistrc +5 -0
  4. package/.eslintignore +3 -0
  5. package/.eslintrc.js +43 -0
  6. package/.eslintrc.json +38 -46
  7. package/.eslintrc_tests +12 -0
  8. package/.gitattributes +2 -0
  9. package/.gitpod.yml +17 -1
  10. package/.prettierignore +19 -0
  11. package/.prettierrc +4 -0
  12. package/CHANGELOG.md +532 -189
  13. package/CONTRIBUTING.md +224 -59
  14. package/README.md +200 -235
  15. package/bower.json +1 -3
  16. package/dist/fabric.d.ts +42 -0
  17. package/dist/index.d.ts +2 -0
  18. package/dist/index.js +27582 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/index.min.js +1 -0
  21. package/dist/index.mjs +27519 -0
  22. package/dist/index.mjs.map +1 -0
  23. package/dist/index.node.cjs +27663 -0
  24. package/dist/index.node.cjs.map +1 -0
  25. package/dist/index.node.d.ts +14 -0
  26. package/dist/index.node.mjs +27606 -0
  27. package/dist/index.node.mjs.map +1 -0
  28. package/dist/src/ClassRegistry.d.ts +13 -0
  29. package/dist/src/Collection.d.ts +136 -0
  30. package/dist/src/CommonMethods.d.ts +32 -0
  31. package/dist/src/EventTypeDefs.d.ts +227 -0
  32. package/dist/src/Intersection.d.ts +112 -0
  33. package/dist/src/Observable.d.ts +60 -0
  34. package/dist/src/Pattern.d.ts +113 -0
  35. package/dist/src/Point.d.ts +232 -0
  36. package/dist/src/Shadow.d.ts +97 -0
  37. package/dist/src/brushes/BaseBrush.d.ts +105 -0
  38. package/dist/src/brushes/CircleBrush.d.ts +49 -0
  39. package/dist/src/brushes/PatternBrush.d.ts +23 -0
  40. package/dist/src/brushes/PencilBrush.d.ts +92 -0
  41. package/dist/src/brushes/SprayBrush.d.ts +79 -0
  42. package/dist/src/cache.d.ts +47 -0
  43. package/dist/src/canvas/Canvas.d.ts +548 -0
  44. package/dist/src/canvas/SelectableCanvas.d.ts +754 -0
  45. package/dist/src/canvas/StaticCanvas.d.ts +778 -0
  46. package/dist/src/canvas/TextEditingManager.d.ts +17 -0
  47. package/dist/src/canvas/canvas_gestures.mixin.d.ts +2 -0
  48. package/dist/src/color/Color.d.ts +174 -0
  49. package/dist/src/color/color_map.d.ts +155 -0
  50. package/dist/src/color/constants.d.ts +22 -0
  51. package/dist/src/color/util.d.ts +12 -0
  52. package/dist/src/config.d.ts +115 -0
  53. package/dist/src/constants.d.ts +14 -0
  54. package/dist/src/controls/Control.d.ts +228 -0
  55. package/dist/src/controls/changeWidth.d.ts +13 -0
  56. package/dist/src/controls/commonControls.d.ts +28 -0
  57. package/dist/src/controls/controlRendering.d.ts +29 -0
  58. package/dist/src/controls/drag.d.ts +12 -0
  59. package/dist/src/controls/index.d.ts +13 -0
  60. package/dist/src/controls/polyControl.d.ts +5 -0
  61. package/dist/src/controls/rotate.d.ts +12 -0
  62. package/dist/src/controls/scale.d.ts +47 -0
  63. package/dist/src/controls/scaleSkew.d.ts +39 -0
  64. package/dist/src/controls/skew.d.ts +33 -0
  65. package/dist/src/controls/util.d.ts +41 -0
  66. package/dist/src/controls/wrapWithFireEvent.d.ts +8 -0
  67. package/dist/src/controls/wrapWithFixedAnchor.d.ts +9 -0
  68. package/dist/src/env/browser.d.ts +3 -0
  69. package/dist/src/env/index.d.ts +15 -0
  70. package/dist/src/env/node.d.ts +5 -0
  71. package/dist/src/env/types.d.ts +15 -0
  72. package/dist/src/filters/BaseFilter.d.ts +153 -0
  73. package/dist/src/filters/BlendColor.d.ts +80 -0
  74. package/dist/src/filters/BlendImage.d.ts +92 -0
  75. package/dist/src/filters/Blur.d.ts +51 -0
  76. package/dist/src/filters/Boilerplate.d.ts +48 -0
  77. package/dist/src/filters/Brightness.d.ts +47 -0
  78. package/dist/src/filters/Canvas2dFilterBackend.d.ts +27 -0
  79. package/dist/src/filters/ColorMatrix.d.ts +63 -0
  80. package/dist/src/filters/ColorMatrixFilters.d.ts +545 -0
  81. package/dist/src/filters/Composed.d.ts +45 -0
  82. package/dist/src/filters/Contrast.d.ts +45 -0
  83. package/dist/src/filters/Convolute.d.ts +82 -0
  84. package/dist/src/filters/FilterBackend.d.ts +14 -0
  85. package/dist/src/filters/GLProbes/GLProbe.d.ts +11 -0
  86. package/dist/src/filters/GLProbes/NodeGLProbe.d.ts +11 -0
  87. package/dist/src/filters/GLProbes/WebGLProbe.d.ts +20 -0
  88. package/dist/src/filters/Gamma.d.ts +54 -0
  89. package/dist/src/filters/Grayscale.d.ts +46 -0
  90. package/dist/src/filters/HueRotation.d.ts +24 -0
  91. package/dist/src/filters/Invert.d.ts +55 -0
  92. package/dist/src/filters/Noise.d.ts +54 -0
  93. package/dist/src/filters/Pixelate.d.ts +44 -0
  94. package/dist/src/filters/RemoveColor.d.ts +63 -0
  95. package/dist/src/filters/Resize.d.ts +136 -0
  96. package/dist/src/filters/Saturation.d.ts +48 -0
  97. package/dist/src/filters/Vibrance.d.ts +48 -0
  98. package/dist/src/filters/WebGLFilterBackend.d.ts +126 -0
  99. package/dist/src/filters/filters.d.ts +21 -0
  100. package/dist/src/filters/index.d.ts +5 -0
  101. package/dist/src/filters/shaders/baseFilter.d.ts +4 -0
  102. package/dist/src/filters/shaders/blendColor.d.ts +13 -0
  103. package/dist/src/filters/shaders/blendImage.d.ts +3 -0
  104. package/dist/src/filters/shaders/blur.d.ts +2 -0
  105. package/dist/src/filters/shaders/brightness.d.ts +2 -0
  106. package/dist/src/filters/shaders/colorMatrix.d.ts +2 -0
  107. package/dist/src/filters/shaders/constrast.d.ts +2 -0
  108. package/dist/src/filters/shaders/convolute.d.ts +11 -0
  109. package/dist/src/filters/shaders/gamma.d.ts +2 -0
  110. package/dist/src/filters/shaders/grayscale.d.ts +3 -0
  111. package/dist/src/filters/shaders/invert.d.ts +2 -0
  112. package/dist/src/filters/shaders/noise.d.ts +2 -0
  113. package/dist/src/filters/shaders/pixelate.d.ts +2 -0
  114. package/dist/src/filters/shaders/removeColor.d.ts +2 -0
  115. package/dist/src/filters/shaders/saturation.d.ts +2 -0
  116. package/dist/src/filters/shaders/vibrance.d.ts +2 -0
  117. package/dist/src/filters/typedefs.d.ts +49 -0
  118. package/dist/src/gradient/Gradient.d.ts +149 -0
  119. package/dist/src/gradient/constants.d.ts +15 -0
  120. package/dist/src/gradient/parser/index.d.ts +4 -0
  121. package/dist/src/gradient/parser/misc.d.ts +4 -0
  122. package/dist/src/gradient/parser/parseColorStops.d.ts +3 -0
  123. package/dist/src/gradient/parser/parseCoords.d.ts +17 -0
  124. package/dist/src/gradient/typedefs.d.ts +93 -0
  125. package/dist/src/mixins/eraser_brush.mixin.d.ts +2 -0
  126. package/dist/src/parkinglot/canvas_animation.mixin.d.ts +2 -0
  127. package/dist/src/parkinglot/straighten.d.ts +2 -0
  128. package/dist/src/parser/applyViewboxTransform.d.ts +5 -0
  129. package/dist/src/parser/attributes.d.ts +6 -0
  130. package/dist/src/parser/constants.d.ts +53 -0
  131. package/dist/src/parser/doesSomeParentMatch.d.ts +2 -0
  132. package/dist/src/parser/elementById.d.ts +6 -0
  133. package/dist/src/parser/elementMatchesRule.d.ts +5 -0
  134. package/dist/src/parser/elements_parser.d.ts +3 -0
  135. package/dist/src/parser/getCSSRules.d.ts +7 -0
  136. package/dist/src/parser/getGlobalStylesForElement.d.ts +5 -0
  137. package/dist/src/parser/getGradientDefs.d.ts +7 -0
  138. package/dist/src/parser/getMultipleNodes.d.ts +2 -0
  139. package/dist/src/parser/getSvgRegex.d.ts +2 -0
  140. package/dist/src/parser/hasAncestorWithNodeName.d.ts +2 -0
  141. package/dist/src/parser/index.d.ts +10 -0
  142. package/dist/src/parser/loadSVGFromString.d.ts +12 -0
  143. package/dist/src/parser/loadSVGFromURL.d.ts +13 -0
  144. package/dist/src/parser/normalizeAttr.d.ts +2 -0
  145. package/dist/src/parser/normalizeValue.d.ts +2 -0
  146. package/dist/src/parser/parseAttributes.d.ts +9 -0
  147. package/dist/src/parser/parseElements.d.ts +11 -0
  148. package/dist/src/parser/parseFontDeclaration.d.ts +10 -0
  149. package/dist/src/parser/parsePointsAttribute.d.ts +12 -0
  150. package/dist/src/parser/parseSVGDocument.d.ts +15 -0
  151. package/dist/src/parser/parseStyleAttribute.d.ts +9 -0
  152. package/dist/src/parser/parseStyleObject.d.ts +2 -0
  153. package/dist/src/parser/parseStyleString.d.ts +2 -0
  154. package/dist/src/parser/parseTransformAttribute.d.ts +10 -0
  155. package/dist/src/parser/parseUseDirectives.d.ts +2 -0
  156. package/dist/src/parser/percent.d.ts +9 -0
  157. package/dist/src/parser/recursivelyParseGradientsXlink.d.ts +2 -0
  158. package/dist/src/parser/rotateMatrix.d.ts +2 -0
  159. package/dist/src/parser/scaleMatrix.d.ts +2 -0
  160. package/dist/src/parser/selectorMatches.d.ts +2 -0
  161. package/dist/src/parser/setStrokeFillOpacity.d.ts +6 -0
  162. package/dist/src/parser/skewMatrix.d.ts +2 -0
  163. package/dist/src/parser/translateMatrix.d.ts +2 -0
  164. package/dist/src/shapes/ActiveSelection.d.ts +82 -0
  165. package/dist/src/shapes/Circle.d.ts +99 -0
  166. package/dist/src/shapes/Ellipse.d.ts +84 -0
  167. package/dist/src/shapes/Group.d.ts +408 -0
  168. package/dist/src/shapes/IText/DraggableTextDelegate.d.ts +78 -0
  169. package/dist/src/shapes/IText/IText.d.ts +335 -0
  170. package/dist/src/shapes/IText/ITextBehavior.d.ts +287 -0
  171. package/dist/src/shapes/IText/ITextClickBehavior.d.ts +83 -0
  172. package/dist/src/shapes/IText/ITextKeyBehavior.d.ts +195 -0
  173. package/dist/src/shapes/IText/constants.d.ts +13 -0
  174. package/dist/src/shapes/Image.d.ts +311 -0
  175. package/dist/src/shapes/Line.d.ts +126 -0
  176. package/dist/src/shapes/Object/AnimatableObject.d.ts +33 -0
  177. package/dist/src/shapes/Object/FabricObject.d.ts +11 -0
  178. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.d.ts +74 -0
  179. package/dist/src/shapes/Object/InteractiveObject.d.ts +296 -0
  180. package/dist/src/shapes/Object/Object.d.ts +594 -0
  181. package/dist/src/shapes/Object/ObjectGeometry.d.ts +327 -0
  182. package/dist/src/shapes/Object/ObjectOrigin.d.ts +109 -0
  183. package/dist/src/shapes/Object/StackedObject.d.ts +72 -0
  184. package/dist/src/shapes/Object/defaultValues.d.ts +76 -0
  185. package/dist/src/shapes/Object/types/BaseProps.d.ts +84 -0
  186. package/dist/src/shapes/Object/types/BorderProps.d.ts +37 -0
  187. package/dist/src/shapes/Object/types/ControlProps.d.ts +62 -0
  188. package/dist/src/shapes/Object/types/FabricObjectProps.d.ts +96 -0
  189. package/dist/src/shapes/Object/types/FillStrokeProps.d.ts +80 -0
  190. package/dist/src/shapes/Object/types/LockInteractionProps.d.ts +51 -0
  191. package/dist/src/shapes/Object/types/ObjectProps.d.ts +42 -0
  192. package/dist/src/shapes/Object/types/SerializedObjectProps.d.ts +66 -0
  193. package/dist/src/shapes/Object/types/index.d.ts +6 -0
  194. package/dist/src/shapes/Path.d.ts +130 -0
  195. package/dist/src/shapes/Polygon.d.ts +9 -0
  196. package/dist/src/shapes/Polyline.d.ts +140 -0
  197. package/dist/src/shapes/Rect.d.ts +76 -0
  198. package/dist/src/shapes/Text/StyledText.d.ts +119 -0
  199. package/dist/src/shapes/Text/Text.d.ts +673 -0
  200. package/dist/src/shapes/Text/TextSVGExportMixin.d.ts +32 -0
  201. package/dist/src/shapes/Text/constants.d.ts +7 -0
  202. package/dist/src/shapes/Textbox.d.ts +185 -0
  203. package/dist/src/shapes/Triangle.d.ts +25 -0
  204. package/dist/src/typedefs.d.ts +90 -0
  205. package/dist/src/util/animation/AnimationBase.d.ts +54 -0
  206. package/dist/src/util/animation/AnimationFrameProvider.d.ts +3 -0
  207. package/dist/src/util/animation/AnimationRegistry.d.ts +29 -0
  208. package/dist/src/util/animation/ArrayAnimation.d.ts +10 -0
  209. package/dist/src/util/animation/ColorAnimation.d.ts +11 -0
  210. package/dist/src/util/animation/ValueAnimation.d.ts +10 -0
  211. package/dist/src/util/animation/animate.d.ts +37 -0
  212. package/dist/src/util/animation/easing.d.ts +130 -0
  213. package/dist/src/util/animation/types.d.ts +87 -0
  214. package/dist/src/util/applyMixins.d.ts +8 -0
  215. package/dist/src/util/dom_event.d.ts +5 -0
  216. package/dist/src/util/dom_misc.d.ts +39 -0
  217. package/dist/src/util/dom_request.d.ts +14 -0
  218. package/dist/src/util/dom_style.d.ts +7 -0
  219. package/dist/src/util/fireEvent.d.ts +3 -0
  220. package/dist/src/util/index.d.ts +35 -0
  221. package/dist/src/util/internals/cloneDeep.d.ts +2 -0
  222. package/dist/src/util/internals/getRandomInt.d.ts +8 -0
  223. package/dist/src/util/internals/ifNaN.d.ts +8 -0
  224. package/dist/src/util/internals/index.d.ts +4 -0
  225. package/dist/src/util/internals/removeFromArray.d.ts +9 -0
  226. package/dist/src/util/internals/uid.d.ts +2 -0
  227. package/dist/src/util/lang_string.d.ts +22 -0
  228. package/dist/src/util/misc/boundingBoxFromPoints.d.ts +9 -0
  229. package/dist/src/util/misc/capValue.d.ts +2 -0
  230. package/dist/src/util/misc/cos.d.ts +10 -0
  231. package/dist/src/util/misc/dom.d.ts +28 -0
  232. package/dist/src/util/misc/findScaleTo.d.ts +29 -0
  233. package/dist/src/util/misc/groupSVGElements.d.ts +9 -0
  234. package/dist/src/util/misc/isTransparent.d.ts +11 -0
  235. package/dist/src/util/misc/matrix.d.ts +92 -0
  236. package/dist/src/util/misc/mergeClipPaths.d.ts +23 -0
  237. package/dist/src/util/misc/objectEnlive.d.ts +56 -0
  238. package/dist/src/util/misc/objectTransforms.d.ts +68 -0
  239. package/dist/src/util/misc/pick.d.ts +9 -0
  240. package/dist/src/util/misc/planeChange.d.ts +84 -0
  241. package/dist/src/util/misc/projectStroke/StrokeLineCapProjections.d.ts +51 -0
  242. package/dist/src/util/misc/projectStroke/StrokeLineJoinProjections.d.ts +81 -0
  243. package/dist/src/util/misc/projectStroke/StrokeProjectionsBase.d.ts +25 -0
  244. package/dist/src/util/misc/projectStroke/index.d.ts +11 -0
  245. package/dist/src/util/misc/projectStroke/types.d.ts +23 -0
  246. package/dist/src/util/misc/radiansDegreesConversion.d.ts +14 -0
  247. package/dist/src/util/misc/resolveOrigin.d.ts +9 -0
  248. package/dist/src/util/misc/rotatePoint.d.ts +12 -0
  249. package/dist/src/util/misc/sin.d.ts +10 -0
  250. package/dist/src/util/misc/svgParsing.d.ts +53 -0
  251. package/dist/src/util/misc/textStyles.d.ts +32 -0
  252. package/dist/src/util/misc/toFixed.d.ts +8 -0
  253. package/dist/src/util/misc/vectors.d.ts +57 -0
  254. package/dist/src/util/path/index.d.ts +96 -0
  255. package/dist/src/util/path/regex.d.ts +3 -0
  256. package/dist/src/util/path/typechecks.d.ts +24 -0
  257. package/dist/src/util/path/typedefs.d.ts +220 -0
  258. package/dist/src/util/transform_matrix_removal.d.ts +14 -0
  259. package/dist/src/util/types.d.ts +19 -0
  260. package/fabric.ts +51 -0
  261. package/index.node.ts +37 -0
  262. package/index.ts +1 -0
  263. package/package.json +100 -40
  264. package/publish.js +0 -26
  265. package/rollup.config.mjs +91 -0
  266. package/rollup.test.config.js +24 -0
  267. package/scripts/build.mjs +50 -0
  268. package/scripts/buildLock.mjs +115 -0
  269. package/scripts/buildReporter.mjs +15 -0
  270. package/scripts/buildStats.mjs +139 -0
  271. package/scripts/dirname.mjs +14 -0
  272. package/scripts/git.mjs +36 -0
  273. package/scripts/index.mjs +564 -0
  274. package/scripts/sandbox.mjs +149 -0
  275. package/src/ClassRegistry.ts +56 -0
  276. package/src/Collection.ts +346 -0
  277. package/src/CommonMethods.ts +63 -0
  278. package/src/EventTypeDefs.ts +296 -0
  279. package/src/Intersection.ts +302 -0
  280. package/src/Observable.ts +181 -0
  281. package/src/Pattern.ts +227 -0
  282. package/src/Point.ts +388 -0
  283. package/src/Shadow.ts +214 -0
  284. package/src/brushes/{base_brush.class.js → BaseBrush.ts} +65 -42
  285. package/src/brushes/CircleBrush.ts +145 -0
  286. package/src/brushes/PatternBrush.ts +70 -0
  287. package/src/brushes/PencilBrush.ts +300 -0
  288. package/src/brushes/SprayBrush.ts +219 -0
  289. package/src/cache.ts +90 -0
  290. package/src/canvas/Canvas.ts +1607 -0
  291. package/src/canvas/SelectableCanvas.ts +1608 -0
  292. package/src/canvas/StaticCanvas.ts +1734 -0
  293. package/src/canvas/TextEditingManager.ts +48 -0
  294. package/src/canvas/canvas_gestures.mixin.ts +207 -0
  295. package/src/color/Color.ts +404 -0
  296. package/src/color/color_map.ts +154 -0
  297. package/src/color/constants.ts +26 -0
  298. package/src/color/util.ts +32 -0
  299. package/src/config.ts +159 -0
  300. package/src/constants.ts +20 -0
  301. package/src/controls/Control.ts +380 -0
  302. package/src/controls/changeWidth.ts +52 -0
  303. package/src/controls/commonControls.ts +105 -0
  304. package/src/controls/controlRendering.ts +138 -0
  305. package/src/controls/drag.ts +31 -0
  306. package/src/controls/index.ts +22 -0
  307. package/src/controls/polyControl.ts +135 -0
  308. package/src/controls/rotate.ts +87 -0
  309. package/src/controls/scale.ts +277 -0
  310. package/src/controls/scaleSkew.ts +92 -0
  311. package/src/controls/skew.ts +242 -0
  312. package/src/controls/util.ts +154 -0
  313. package/src/controls/wrapWithFireEvent.ts +25 -0
  314. package/src/controls/wrapWithFixedAnchor.ts +20 -0
  315. package/src/env/browser.ts +32 -0
  316. package/src/env/index.ts +24 -0
  317. package/src/env/node.ts +56 -0
  318. package/src/env/types.ts +15 -0
  319. package/src/filters/{base_filter.class.js → BaseFilter.ts} +192 -151
  320. package/src/filters/BlendColor.ts +217 -0
  321. package/src/filters/BlendImage.ts +228 -0
  322. package/src/filters/Blur.ts +179 -0
  323. package/src/filters/Boilerplate.ts +94 -0
  324. package/src/filters/Brightness.ts +83 -0
  325. package/src/filters/Canvas2dFilterBackend.ts +65 -0
  326. package/src/filters/ColorMatrix.ts +145 -0
  327. package/src/filters/ColorMatrixFilters.ts +77 -0
  328. package/src/filters/Composed.ts +76 -0
  329. package/src/filters/Contrast.ts +82 -0
  330. package/src/filters/Convolute.ts +184 -0
  331. package/src/filters/FilterBackend.ts +34 -0
  332. package/src/filters/GLProbes/GLProbe.ts +11 -0
  333. package/src/filters/GLProbes/NodeGLProbe.ts +15 -0
  334. package/src/filters/GLProbes/WebGLProbe.ts +46 -0
  335. package/src/filters/Gamma.ts +110 -0
  336. package/src/filters/Grayscale.ts +102 -0
  337. package/src/filters/HueRotation.ts +62 -0
  338. package/src/filters/Invert.ts +99 -0
  339. package/src/filters/Noise.ts +94 -0
  340. package/src/filters/Pixelate.ts +96 -0
  341. package/src/filters/RemoveColor.ts +135 -0
  342. package/src/filters/Resize.ts +538 -0
  343. package/src/filters/Saturation.ts +87 -0
  344. package/src/filters/Vibrance.ts +88 -0
  345. package/src/filters/WebGLFilterBackend.ts +430 -0
  346. package/src/filters/filters.ts +28 -0
  347. package/src/filters/index.ts +5 -0
  348. package/src/filters/shaders/baseFilter.ts +19 -0
  349. package/src/filters/shaders/blendColor.ts +33 -0
  350. package/src/filters/shaders/blendImage.ts +32 -0
  351. package/src/filters/shaders/blur.ts +24 -0
  352. package/src/filters/shaders/brightness.ts +11 -0
  353. package/src/filters/shaders/colorMatrix.ts +12 -0
  354. package/src/filters/shaders/constrast.ts +11 -0
  355. package/src/filters/shaders/convolute.ts +154 -0
  356. package/src/filters/shaders/gamma.ts +15 -0
  357. package/src/filters/shaders/grayscale.ts +36 -0
  358. package/src/filters/shaders/invert.ts +19 -0
  359. package/src/filters/shaders/noise.ts +16 -0
  360. package/src/filters/shaders/pixelate.ts +19 -0
  361. package/src/filters/shaders/removeColor.ts +13 -0
  362. package/src/filters/shaders/saturation.ts +15 -0
  363. package/src/filters/shaders/vibrance.ts +16 -0
  364. package/src/filters/typedefs.ts +65 -0
  365. package/src/gradient/Gradient.ts +406 -0
  366. package/src/gradient/constants.ts +12 -0
  367. package/src/gradient/parser/index.ts +3 -0
  368. package/src/gradient/parser/misc.ts +13 -0
  369. package/src/gradient/parser/parseColorStops.ts +56 -0
  370. package/src/gradient/parser/parseCoords.ts +73 -0
  371. package/src/gradient/typedefs.ts +104 -0
  372. package/src/mixins/{eraser_brush.mixin.js → eraser_brush.mixin.ts} +350 -239
  373. package/src/parkinglot/canvas_animation.mixin.ts +121 -0
  374. package/src/parkinglot/straighten.ts +58 -0
  375. package/src/parser/applyViewboxTransform.ts +157 -0
  376. package/src/parser/attributes.ts +25 -0
  377. package/src/parser/constants.ts +115 -0
  378. package/src/parser/doesSomeParentMatch.ts +19 -0
  379. package/src/parser/elementById.ts +21 -0
  380. package/src/parser/elementMatchesRule.ts +16 -0
  381. package/src/parser/elements_parser.ts +191 -0
  382. package/src/parser/getCSSRules.ts +62 -0
  383. package/src/parser/getGlobalStylesForElement.ts +19 -0
  384. package/src/parser/getGradientDefs.ts +31 -0
  385. package/src/parser/getMultipleNodes.ts +15 -0
  386. package/src/parser/getSvgRegex.ts +5 -0
  387. package/src/parser/hasAncestorWithNodeName.ts +14 -0
  388. package/src/parser/index.ts +9 -0
  389. package/src/parser/loadSVGFromString.ts +26 -0
  390. package/src/parser/loadSVGFromURL.ts +40 -0
  391. package/src/parser/normalizeAttr.ts +10 -0
  392. package/src/parser/normalizeValue.ts +63 -0
  393. package/src/parser/parseAttributes.ts +90 -0
  394. package/src/parser/parseElements.ts +28 -0
  395. package/src/parser/parseFontDeclaration.ts +44 -0
  396. package/src/parser/parsePointsAttribute.ts +34 -0
  397. package/src/parser/parseSVGDocument.ts +93 -0
  398. package/src/parser/parseStyleAttribute.ts +27 -0
  399. package/src/parser/parseStyleObject.ts +15 -0
  400. package/src/parser/parseStyleString.ts +16 -0
  401. package/src/parser/parseTransformAttribute.ts +155 -0
  402. package/src/parser/parseUseDirectives.ts +78 -0
  403. package/src/parser/percent.ts +27 -0
  404. package/src/parser/recursivelyParseGradientsXlink.ts +42 -0
  405. package/src/parser/rotateMatrix.ts +21 -0
  406. package/src/parser/scaleMatrix.ts +9 -0
  407. package/src/parser/selectorMatches.ts +25 -0
  408. package/src/parser/setStrokeFillOpacity.ts +40 -0
  409. package/src/parser/skewMatrix.ts +6 -0
  410. package/src/parser/translateMatrix.ts +8 -0
  411. package/src/shapes/ActiveSelection.ts +189 -0
  412. package/src/shapes/Circle.ts +242 -0
  413. package/src/shapes/Ellipse.ts +179 -0
  414. package/src/shapes/Group.ts +1100 -0
  415. package/src/shapes/IText/DraggableTextDelegate.ts +382 -0
  416. package/src/shapes/IText/IText.ts +693 -0
  417. package/src/shapes/IText/ITextBehavior.ts +1064 -0
  418. package/src/shapes/IText/ITextClickBehavior.ts +325 -0
  419. package/src/shapes/IText/ITextKeyBehavior.ts +685 -0
  420. package/src/shapes/IText/constants.ts +47 -0
  421. package/src/shapes/Image.ts +841 -0
  422. package/src/shapes/Line.ts +346 -0
  423. package/src/shapes/Object/AnimatableObject.ts +106 -0
  424. package/src/shapes/Object/FabricObject.ts +29 -0
  425. package/src/shapes/Object/FabricObjectSVGExportMixin.ts +277 -0
  426. package/src/shapes/Object/InteractiveObject.ts +672 -0
  427. package/src/shapes/Object/Object.ts +1561 -0
  428. package/src/shapes/Object/ObjectGeometry.ts +813 -0
  429. package/src/shapes/Object/ObjectOrigin.ts +276 -0
  430. package/src/shapes/Object/StackedObject.ts +206 -0
  431. package/src/shapes/Object/defaultValues.ts +108 -0
  432. package/src/shapes/Object/types/BaseProps.ts +96 -0
  433. package/src/shapes/Object/types/BorderProps.ts +40 -0
  434. package/src/shapes/Object/types/ControlProps.ts +69 -0
  435. package/src/shapes/Object/types/FabricObjectProps.ts +111 -0
  436. package/src/shapes/Object/types/FillStrokeProps.ts +90 -0
  437. package/src/shapes/Object/types/LockInteractionProps.ts +57 -0
  438. package/src/shapes/Object/types/ObjectProps.ts +46 -0
  439. package/src/shapes/Object/types/SerializedObjectProps.ts +73 -0
  440. package/src/shapes/Object/types/index.ts +8 -0
  441. package/src/shapes/Path.ts +416 -0
  442. package/src/shapes/Polygon.ts +20 -0
  443. package/src/shapes/Polyline.ts +359 -0
  444. package/src/shapes/Rect.ts +233 -0
  445. package/src/shapes/Text/StyledText.ts +329 -0
  446. package/src/shapes/Text/Text.ts +1884 -0
  447. package/src/shapes/Text/TextSVGExportMixin.ts +288 -0
  448. package/src/shapes/Text/constants.ts +91 -0
  449. package/src/shapes/Textbox.ts +477 -0
  450. package/src/shapes/Triangle.ts +60 -0
  451. package/src/typedefs.ts +115 -0
  452. package/src/util/animation/AnimationBase.ts +166 -0
  453. package/src/util/animation/AnimationFrameProvider.ts +9 -0
  454. package/src/util/animation/AnimationRegistry.ts +58 -0
  455. package/src/util/animation/ArrayAnimation.ts +27 -0
  456. package/src/util/animation/ColorAnimation.ts +74 -0
  457. package/src/util/animation/ValueAnimation.ts +29 -0
  458. package/src/util/animation/animate.ts +74 -0
  459. package/src/util/animation/easing.ts +327 -0
  460. package/src/util/animation/types.ts +136 -0
  461. package/src/util/applyMixins.ts +22 -0
  462. package/src/util/dom_event.ts +28 -0
  463. package/src/util/dom_misc.ts +121 -0
  464. package/src/util/dom_request.ts +64 -0
  465. package/src/util/dom_style.ts +20 -0
  466. package/src/util/fireEvent.ts +15 -0
  467. package/src/util/index.ts +102 -0
  468. package/src/util/internals/cloneDeep.ts +2 -0
  469. package/src/util/internals/getRandomInt.ts +8 -0
  470. package/src/util/internals/ifNaN.ts +9 -0
  471. package/src/util/internals/index.ts +3 -0
  472. package/src/util/internals/removeFromArray.ts +14 -0
  473. package/src/util/internals/uid.ts +3 -0
  474. package/src/util/lang_string.ts +79 -0
  475. package/src/util/misc/boundingBoxFromPoints.ts +37 -0
  476. package/src/util/misc/capValue.ts +2 -0
  477. package/src/util/misc/cos.ts +24 -0
  478. package/src/util/misc/dom.ts +50 -0
  479. package/src/util/misc/findScaleTo.ts +44 -0
  480. package/src/util/misc/groupSVGElements.ts +15 -0
  481. package/src/util/misc/isTransparent.ts +28 -0
  482. package/src/util/misc/matrix.ts +207 -0
  483. package/src/util/misc/mergeClipPaths.ts +40 -0
  484. package/src/util/misc/objectEnlive.ts +189 -0
  485. package/src/util/misc/objectTransforms.ts +129 -0
  486. package/src/util/misc/pick.ts +29 -0
  487. package/src/util/misc/planeChange.ts +136 -0
  488. package/src/util/misc/projectStroke/StrokeLineCapProjections.ts +112 -0
  489. package/src/util/misc/projectStroke/StrokeLineJoinProjections.ts +226 -0
  490. package/src/util/misc/projectStroke/StrokeProjectionsBase.ts +75 -0
  491. package/src/util/misc/projectStroke/index.ts +53 -0
  492. package/src/util/misc/projectStroke/types.ts +24 -0
  493. package/src/util/misc/radiansDegreesConversion.ts +18 -0
  494. package/src/util/misc/resolveOrigin.ts +22 -0
  495. package/src/util/misc/rotatePoint.ts +15 -0
  496. package/src/util/misc/sin.ts +26 -0
  497. package/src/util/misc/svgParsing.ts +181 -0
  498. package/src/util/misc/textStyles.ts +134 -0
  499. package/src/util/misc/toFixed.ts +8 -0
  500. package/src/util/misc/vectors.ts +82 -0
  501. package/src/util/path/index.ts +1038 -0
  502. package/src/util/path/regex.ts +41 -0
  503. package/src/util/path/typechecks.ts +145 -0
  504. package/src/util/path/typedefs.ts +305 -0
  505. package/src/util/transform_matrix_removal.ts +60 -0
  506. package/src/util/types.ts +78 -0
  507. package/tsconfig.json +106 -0
  508. package/HEADER.js +0 -203
  509. package/build.js +0 -287
  510. package/dist/fabric.js +0 -31187
  511. package/dist/fabric.min.js +0 -1
  512. package/old-travis-reference.yml +0 -97
  513. package/src/brushes/circle_brush.class.js +0 -144
  514. package/src/brushes/pattern_brush.class.js +0 -61
  515. package/src/brushes/pencil_brush.class.js +0 -310
  516. package/src/brushes/spray_brush.class.js +0 -219
  517. package/src/canvas.class.js +0 -1312
  518. package/src/color.class.js +0 -636
  519. package/src/control.class.js +0 -339
  520. package/src/controls.actions.js +0 -740
  521. package/src/controls.render.js +0 -99
  522. package/src/elements_parser.js +0 -152
  523. package/src/filters/2d_backend.class.js +0 -65
  524. package/src/filters/blendcolor_filter.class.js +0 -251
  525. package/src/filters/blendimage_filter.class.js +0 -247
  526. package/src/filters/blur_filter.class.js +0 -217
  527. package/src/filters/brightness_filter.class.js +0 -113
  528. package/src/filters/colormatrix_filter.class.js +0 -159
  529. package/src/filters/composed_filter.class.js +0 -72
  530. package/src/filters/contrast_filter.class.js +0 -113
  531. package/src/filters/convolute_filter.class.js +0 -352
  532. package/src/filters/filter_boilerplate.js +0 -111
  533. package/src/filters/filter_generator.js +0 -85
  534. package/src/filters/gamma_filter.class.js +0 -136
  535. package/src/filters/grayscale_filter.class.js +0 -154
  536. package/src/filters/hue_rotation.class.js +0 -107
  537. package/src/filters/invert_filter.class.js +0 -111
  538. package/src/filters/noise_filter.class.js +0 -134
  539. package/src/filters/pixelate_filter.class.js +0 -137
  540. package/src/filters/removecolor_filter.class.js +0 -173
  541. package/src/filters/resize_filter.class.js +0 -490
  542. package/src/filters/saturate_filter.class.js +0 -119
  543. package/src/filters/vibrance_filter.class.js +0 -122
  544. package/src/filters/webgl_backend.class.js +0 -396
  545. package/src/globalFabric.js +0 -4
  546. package/src/gradient.class.js +0 -490
  547. package/src/intersection.class.js +0 -172
  548. package/src/log.js +0 -11
  549. package/src/mixins/animation.mixin.js +0 -231
  550. package/src/mixins/canvas_dataurl_exporter.mixin.js +0 -97
  551. package/src/mixins/canvas_events.mixin.js +0 -974
  552. package/src/mixins/canvas_gestures.mixin.js +0 -149
  553. package/src/mixins/canvas_grouping.mixin.js +0 -177
  554. package/src/mixins/canvas_serialization.mixin.js +0 -228
  555. package/src/mixins/collection.mixin.js +0 -170
  556. package/src/mixins/default_controls.js +0 -114
  557. package/src/mixins/itext.svg_export.js +0 -241
  558. package/src/mixins/itext_behavior.mixin.js +0 -940
  559. package/src/mixins/itext_click_behavior.mixin.js +0 -278
  560. package/src/mixins/itext_key_behavior.mixin.js +0 -694
  561. package/src/mixins/object.svg_export.js +0 -258
  562. package/src/mixins/object_geometry.mixin.js +0 -683
  563. package/src/mixins/object_interactivity.mixin.js +0 -314
  564. package/src/mixins/object_origin.mixin.js +0 -255
  565. package/src/mixins/object_stacking.mixin.js +0 -80
  566. package/src/mixins/object_straightening.mixin.js +0 -80
  567. package/src/mixins/observable.mixin.js +0 -141
  568. package/src/mixins/shared_methods.mixin.js +0 -94
  569. package/src/mixins/stateful.mixin.js +0 -107
  570. package/src/mixins/text_style.mixin.js +0 -324
  571. package/src/parser.js +0 -1090
  572. package/src/pattern.class.js +0 -189
  573. package/src/point.class.js +0 -337
  574. package/src/shadow.class.js +0 -195
  575. package/src/shapes/active_selection.class.js +0 -155
  576. package/src/shapes/circle.class.js +0 -210
  577. package/src/shapes/ellipse.class.js +0 -181
  578. package/src/shapes/group.class.js +0 -593
  579. package/src/shapes/image.class.js +0 -764
  580. package/src/shapes/itext.class.js +0 -526
  581. package/src/shapes/line.class.js +0 -324
  582. package/src/shapes/object.class.js +0 -2008
  583. package/src/shapes/path.class.js +0 -384
  584. package/src/shapes/polygon.class.js +0 -81
  585. package/src/shapes/polyline.class.js +0 -268
  586. package/src/shapes/rect.class.js +0 -187
  587. package/src/shapes/text.class.js +0 -1696
  588. package/src/shapes/textbox.class.js +0 -461
  589. package/src/shapes/triangle.class.js +0 -93
  590. package/src/static_canvas.class.js +0 -1881
  591. package/src/util/anim_ease.js +0 -398
  592. package/src/util/animate.js +0 -254
  593. package/src/util/animate_color.js +0 -74
  594. package/src/util/dom_event.js +0 -50
  595. package/src/util/dom_misc.js +0 -300
  596. package/src/util/dom_request.js +0 -54
  597. package/src/util/dom_style.js +0 -70
  598. package/src/util/lang_array.js +0 -94
  599. package/src/util/lang_class.js +0 -115
  600. package/src/util/lang_object.js +0 -75
  601. package/src/util/lang_string.js +0 -110
  602. package/src/util/misc.js +0 -1330
  603. package/src/util/named_accessors.mixin.js +0 -428
  604. package/src/util/path.js +0 -829
@@ -0,0 +1,1038 @@
1
+ import { cache } from '../../cache';
2
+ import { config } from '../../config';
3
+ import { halfPI, PiBy180 } from '../../constants';
4
+ import type { TMat2D, TRadian, TRectBounds } from '../../typedefs';
5
+ import { cos } from '../misc/cos';
6
+ import { multiplyTransformMatrices, transformPoint } from '../misc/matrix';
7
+ import { sin } from '../misc/sin';
8
+ import { toFixed } from '../misc/toFixed';
9
+ import {
10
+ TCurveInfo,
11
+ TComplexPathData,
12
+ TParsedAbsoluteCubicCurveCommand,
13
+ TParsedCubicCurveCommand,
14
+ TPathSegmentInfo,
15
+ TPointAngle,
16
+ TSimpleParsedCommand,
17
+ TSimplePathData,
18
+ TPathSegmentCommandInfo,
19
+ TComplexParsedCommand,
20
+ TPathSegmentInfoCommon,
21
+ TEndPathInfo,
22
+ TParsedArcCommand,
23
+ } from './typedefs';
24
+ import { XY, Point } from '../../Point';
25
+ import { numberRegExStr, rePathCommand } from './regex';
26
+
27
+ /**
28
+ * Commands that may be repeated
29
+ */
30
+ const repeatedCommands: Record<string, string | undefined> = {
31
+ m: 'l',
32
+ M: 'L',
33
+ };
34
+
35
+ /**
36
+ * Convert an arc of a rotated ellipse to a Bezier Curve
37
+ * @param {TRadian} theta1 start of the arc
38
+ * @param {TRadian} theta2 end of the arc
39
+ * @param cosTh cosine of the angle of rotation
40
+ * @param sinTh sine of the angle of rotation
41
+ * @param rx x-axis radius (before rotation)
42
+ * @param ry y-axis radius (before rotation)
43
+ * @param cx1 center x of the ellipse
44
+ * @param cy1 center y of the ellipse
45
+ * @param mT
46
+ * @param fromX starting point of arc x
47
+ * @param fromY starting point of arc y
48
+ */
49
+ const segmentToBezier = (
50
+ theta1: TRadian,
51
+ theta2: TRadian,
52
+ cosTh: number,
53
+ sinTh: number,
54
+ rx: number,
55
+ ry: number,
56
+ cx1: number,
57
+ cy1: number,
58
+ mT: number,
59
+ fromX: number,
60
+ fromY: number
61
+ ): TParsedCubicCurveCommand => {
62
+ const costh1 = cos(theta1),
63
+ sinth1 = sin(theta1),
64
+ costh2 = cos(theta2),
65
+ sinth2 = sin(theta2),
66
+ toX = cosTh * rx * costh2 - sinTh * ry * sinth2 + cx1,
67
+ toY = sinTh * rx * costh2 + cosTh * ry * sinth2 + cy1,
68
+ cp1X = fromX + mT * (-cosTh * rx * sinth1 - sinTh * ry * costh1),
69
+ cp1Y = fromY + mT * (-sinTh * rx * sinth1 + cosTh * ry * costh1),
70
+ cp2X = toX + mT * (cosTh * rx * sinth2 + sinTh * ry * costh2),
71
+ cp2Y = toY + mT * (sinTh * rx * sinth2 - cosTh * ry * costh2);
72
+
73
+ return ['C', cp1X, cp1Y, cp2X, cp2Y, toX, toY];
74
+ };
75
+
76
+ /**
77
+ * Adapted from {@link http://dxr.mozilla.org/mozilla-central/source/dom/svg/SVGPathDataParser.cpp}
78
+ * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here
79
+ * http://mozilla.org/MPL/2.0/
80
+ * @param toX
81
+ * @param toY
82
+ * @param rx
83
+ * @param ry
84
+ * @param {number} large 0 or 1 flag
85
+ * @param {number} sweep 0 or 1 flag
86
+ * @param rotateX
87
+ */
88
+ const arcToSegments = (
89
+ toX: number,
90
+ toY: number,
91
+ rx: number,
92
+ ry: number,
93
+ large: number,
94
+ sweep: number,
95
+ rotateX: TRadian
96
+ ): TParsedAbsoluteCubicCurveCommand[] => {
97
+ let fromX = 0,
98
+ fromY = 0,
99
+ root = 0;
100
+ const PI = Math.PI,
101
+ theta = rotateX * PiBy180,
102
+ sinTheta = sin(theta),
103
+ cosTh = cos(theta),
104
+ px = 0.5 * (-cosTh * toX - sinTheta * toY),
105
+ py = 0.5 * (-cosTh * toY + sinTheta * toX),
106
+ rx2 = rx ** 2,
107
+ ry2 = ry ** 2,
108
+ py2 = py ** 2,
109
+ px2 = px ** 2,
110
+ pl = rx2 * ry2 - rx2 * py2 - ry2 * px2;
111
+ let _rx = Math.abs(rx);
112
+ let _ry = Math.abs(ry);
113
+
114
+ if (pl < 0) {
115
+ const s = Math.sqrt(1 - pl / (rx2 * ry2));
116
+ _rx *= s;
117
+ _ry *= s;
118
+ } else {
119
+ root =
120
+ (large === sweep ? -1.0 : 1.0) * Math.sqrt(pl / (rx2 * py2 + ry2 * px2));
121
+ }
122
+
123
+ const cx = (root * _rx * py) / _ry,
124
+ cy = (-root * _ry * px) / _rx,
125
+ cx1 = cosTh * cx - sinTheta * cy + toX * 0.5,
126
+ cy1 = sinTheta * cx + cosTh * cy + toY * 0.5;
127
+ let mTheta = calcVectorAngle(1, 0, (px - cx) / _rx, (py - cy) / _ry);
128
+ let dtheta = calcVectorAngle(
129
+ (px - cx) / _rx,
130
+ (py - cy) / _ry,
131
+ (-px - cx) / _rx,
132
+ (-py - cy) / _ry
133
+ );
134
+
135
+ if (sweep === 0 && dtheta > 0) {
136
+ dtheta -= 2 * PI;
137
+ } else if (sweep === 1 && dtheta < 0) {
138
+ dtheta += 2 * PI;
139
+ }
140
+
141
+ // Convert into cubic bezier segments <= 90deg
142
+ const segments = Math.ceil(Math.abs((dtheta / PI) * 2)),
143
+ result = new Array(segments),
144
+ mDelta = dtheta / segments,
145
+ mT =
146
+ ((8 / 3) * Math.sin(mDelta / 4) * Math.sin(mDelta / 4)) /
147
+ Math.sin(mDelta / 2);
148
+ let th3 = mTheta + mDelta;
149
+
150
+ for (let i = 0; i < segments; i++) {
151
+ result[i] = segmentToBezier(
152
+ mTheta,
153
+ th3,
154
+ cosTh,
155
+ sinTheta,
156
+ _rx,
157
+ _ry,
158
+ cx1,
159
+ cy1,
160
+ mT,
161
+ fromX,
162
+ fromY
163
+ );
164
+ fromX = result[i][5];
165
+ fromY = result[i][6];
166
+ mTheta = th3;
167
+ th3 += mDelta;
168
+ }
169
+ return result;
170
+ };
171
+
172
+ /**
173
+ * @private
174
+ * Calculate the angle between two vectors
175
+ * @param ux u endpoint x
176
+ * @param uy u endpoint y
177
+ * @param vx v endpoint x
178
+ * @param vy v endpoint y
179
+ */
180
+ const calcVectorAngle = (
181
+ ux: number,
182
+ uy: number,
183
+ vx: number,
184
+ vy: number
185
+ ): TRadian => {
186
+ const ta = Math.atan2(uy, ux),
187
+ tb = Math.atan2(vy, vx);
188
+ if (tb >= ta) {
189
+ return tb - ta;
190
+ } else {
191
+ return 2 * Math.PI - (ta - tb);
192
+ }
193
+ };
194
+
195
+ // functions for the Cubic beizer
196
+ // taken from: https://github.com/konvajs/konva/blob/7.0.5/src/shapes/Path.ts#L350
197
+ const CB1 = (t: number) => t ** 3;
198
+ const CB2 = (t: number) => 3 * t ** 2 * (1 - t);
199
+ const CB3 = (t: number) => 3 * t * (1 - t) ** 2;
200
+ const CB4 = (t: number) => (1 - t) ** 3;
201
+
202
+ /**
203
+ * Calculate bounding box of a cubic Bezier curve
204
+ * Taken from http://jsbin.com/ivomiq/56/edit (no credits available)
205
+ * TODO: can we normalize this with the starting points set at 0 and then translated the bbox?
206
+ * @param {number} begx starting point
207
+ * @param {number} begy
208
+ * @param {number} cp1x first control point
209
+ * @param {number} cp1y
210
+ * @param {number} cp2x second control point
211
+ * @param {number} cp2y
212
+ * @param {number} endx end of bezier
213
+ * @param {number} endy
214
+ * @return {TRectBounds} the rectangular bounds
215
+ */
216
+ export function getBoundsOfCurve(
217
+ begx: number,
218
+ begy: number,
219
+ cp1x: number,
220
+ cp1y: number,
221
+ cp2x: number,
222
+ cp2y: number,
223
+ endx: number,
224
+ endy: number
225
+ ): TRectBounds {
226
+ let argsString: string;
227
+ if (config.cachesBoundsOfCurve) {
228
+ // eslint-disable-next-line
229
+ argsString = [...arguments].join();
230
+ if (cache.boundsOfCurveCache[argsString]) {
231
+ return cache.boundsOfCurveCache[argsString];
232
+ }
233
+ }
234
+
235
+ const sqrt = Math.sqrt,
236
+ abs = Math.abs,
237
+ tvalues = [],
238
+ bounds: [[x: number, y: number], [x: number, y: number]] = [
239
+ [0, 0],
240
+ [0, 0],
241
+ ];
242
+
243
+ let b = 6 * begx - 12 * cp1x + 6 * cp2x;
244
+ let a = -3 * begx + 9 * cp1x - 9 * cp2x + 3 * endx;
245
+ let c = 3 * cp1x - 3 * begx;
246
+
247
+ for (let i = 0; i < 2; ++i) {
248
+ if (i > 0) {
249
+ b = 6 * begy - 12 * cp1y + 6 * cp2y;
250
+ a = -3 * begy + 9 * cp1y - 9 * cp2y + 3 * endy;
251
+ c = 3 * cp1y - 3 * begy;
252
+ }
253
+
254
+ if (abs(a) < 1e-12) {
255
+ if (abs(b) < 1e-12) {
256
+ continue;
257
+ }
258
+ const t = -c / b;
259
+ if (0 < t && t < 1) {
260
+ tvalues.push(t);
261
+ }
262
+ continue;
263
+ }
264
+ const b2ac = b * b - 4 * c * a;
265
+ if (b2ac < 0) {
266
+ continue;
267
+ }
268
+ const sqrtb2ac = sqrt(b2ac);
269
+ const t1 = (-b + sqrtb2ac) / (2 * a);
270
+ if (0 < t1 && t1 < 1) {
271
+ tvalues.push(t1);
272
+ }
273
+ const t2 = (-b - sqrtb2ac) / (2 * a);
274
+ if (0 < t2 && t2 < 1) {
275
+ tvalues.push(t2);
276
+ }
277
+ }
278
+
279
+ let j = tvalues.length;
280
+ const jlen = j;
281
+ const iterator = getPointOnCubicBezierIterator(
282
+ begx,
283
+ begy,
284
+ cp1x,
285
+ cp1y,
286
+ cp2x,
287
+ cp2y,
288
+ endx,
289
+ endy
290
+ );
291
+ while (j--) {
292
+ const { x, y } = iterator(tvalues[j]);
293
+ bounds[0][j] = x;
294
+ bounds[1][j] = y;
295
+ }
296
+
297
+ bounds[0][jlen] = begx;
298
+ bounds[1][jlen] = begy;
299
+ bounds[0][jlen + 1] = endx;
300
+ bounds[1][jlen + 1] = endy;
301
+ const result: TRectBounds = [
302
+ new Point(Math.min(...bounds[0]), Math.min(...bounds[1])),
303
+ new Point(Math.max(...bounds[0]), Math.max(...bounds[1])),
304
+ ];
305
+ if (config.cachesBoundsOfCurve) {
306
+ cache.boundsOfCurveCache[argsString!] = result;
307
+ }
308
+ return result;
309
+ }
310
+
311
+ /**
312
+ * Converts arc to a bunch of cubic Bezier curves
313
+ * @param {number} fx starting point x
314
+ * @param {number} fy starting point y
315
+ * @param {TParsedArcCommand} coords Arc command
316
+ */
317
+ export const fromArcToBeziers = (
318
+ fx: number,
319
+ fy: number,
320
+ [_, rx, ry, rot, large, sweep, tx, ty]: TParsedArcCommand
321
+ ): TParsedAbsoluteCubicCurveCommand[] => {
322
+ const segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);
323
+
324
+ for (let i = 0, len = segsNorm.length; i < len; i++) {
325
+ segsNorm[i][1] += fx;
326
+ segsNorm[i][2] += fy;
327
+ segsNorm[i][3] += fx;
328
+ segsNorm[i][4] += fy;
329
+ segsNorm[i][5] += fx;
330
+ segsNorm[i][6] += fy;
331
+ }
332
+ return segsNorm;
333
+ };
334
+
335
+ /**
336
+ * This function takes a parsed SVG path and makes it simpler for fabricJS logic.
337
+ * Simplification consist of:
338
+ * - All commands converted to absolute (lowercase to uppercase)
339
+ * - S converted to C
340
+ * - T converted to Q
341
+ * - A converted to C
342
+ * @param {TComplexPathData} path the array of commands of a parsed SVG path for `Path`
343
+ * @return {TSimplePathData} the simplified array of commands of a parsed SVG path for `Path`
344
+ * TODO: figure out how to remove the type assertions in a nice way
345
+ */
346
+ export const makePathSimpler = (path: TComplexPathData): TSimplePathData => {
347
+ // x and y represent the last point of the path, AKA the previous command point.
348
+ // we add them to each relative command to make it an absolute comment.
349
+ // we also swap the v V h H with L, because are easier to transform.
350
+ let x = 0,
351
+ y = 0;
352
+ // x1 and y1 represent the last point of the subpath. the subpath is started with
353
+ // m or M command. When a z or Z command is drawn, x and y need to be resetted to
354
+ // the last x1 and y1.
355
+ let x1 = 0,
356
+ y1 = 0;
357
+ // previous will host the letter of the previous command, to handle S and T.
358
+ // controlX and controlY will host the previous reflected control point
359
+ const destinationPath: TSimplePathData = [];
360
+ let previous,
361
+ // placeholders
362
+ controlX = 0,
363
+ controlY = 0;
364
+ for (const parsedCommand of path) {
365
+ const current: TComplexParsedCommand = [...parsedCommand];
366
+ let converted: TSimpleParsedCommand | undefined;
367
+ switch (
368
+ current[0] // first letter
369
+ ) {
370
+ case 'l': // lineto, relative
371
+ current[1] += x;
372
+ current[2] += y;
373
+ // falls through
374
+ case 'L':
375
+ x = current[1];
376
+ y = current[2];
377
+ converted = ['L', x, y];
378
+ break;
379
+ case 'h': // horizontal lineto, relative
380
+ current[1] += x;
381
+ // falls through
382
+ case 'H':
383
+ x = current[1];
384
+ converted = ['L', x, y];
385
+ break;
386
+ case 'v': // vertical lineto, relative
387
+ current[1] += y;
388
+ // falls through
389
+ case 'V':
390
+ y = current[1];
391
+ converted = ['L', x, y];
392
+ break;
393
+ case 'm': // moveTo, relative
394
+ current[1] += x;
395
+ current[2] += y;
396
+ // falls through
397
+ case 'M':
398
+ x = current[1];
399
+ y = current[2];
400
+ x1 = current[1];
401
+ y1 = current[2];
402
+ converted = ['M', x, y];
403
+ break;
404
+ case 'c': // bezierCurveTo, relative
405
+ current[1] += x;
406
+ current[2] += y;
407
+ current[3] += x;
408
+ current[4] += y;
409
+ current[5] += x;
410
+ current[6] += y;
411
+ // falls through
412
+ case 'C':
413
+ controlX = current[3];
414
+ controlY = current[4];
415
+ x = current[5];
416
+ y = current[6];
417
+ converted = ['C', current[1], current[2], controlX, controlY, x, y];
418
+ break;
419
+ case 's': // shorthand cubic bezierCurveTo, relative
420
+ current[1] += x;
421
+ current[2] += y;
422
+ current[3] += x;
423
+ current[4] += y;
424
+ // falls through
425
+ case 'S':
426
+ // would be sScC but since we are swapping sSc for C, we check just that.
427
+ if (previous === 'C') {
428
+ // calculate reflection of previous control points
429
+ controlX = 2 * x - controlX;
430
+ controlY = 2 * y - controlY;
431
+ } else {
432
+ // If there is no previous command or if the previous command was not a C, c, S, or s,
433
+ // the control point is coincident with the current point
434
+ controlX = x;
435
+ controlY = y;
436
+ }
437
+ x = current[3];
438
+ y = current[4];
439
+ converted = ['C', controlX, controlY, current[1], current[2], x, y];
440
+ // converted[3] and converted[4] are NOW the second control point.
441
+ // we keep it for the next reflection.
442
+ controlX = converted[3];
443
+ controlY = converted[4];
444
+ break;
445
+ case 'q': // quadraticCurveTo, relative
446
+ current[1] += x;
447
+ current[2] += y;
448
+ current[3] += x;
449
+ current[4] += y;
450
+ // falls through
451
+ case 'Q':
452
+ controlX = current[1];
453
+ controlY = current[2];
454
+ x = current[3];
455
+ y = current[4];
456
+ converted = ['Q', controlX, controlY, x, y];
457
+ break;
458
+ case 't': // shorthand quadraticCurveTo, relative
459
+ current[1] += x;
460
+ current[2] += y;
461
+ // falls through
462
+ case 'T':
463
+ if (previous === 'Q') {
464
+ // calculate reflection of previous control point
465
+ controlX = 2 * x - controlX;
466
+ controlY = 2 * y - controlY;
467
+ } else {
468
+ // If there is no previous command or if the previous command was not a Q, q, T or t,
469
+ // assume the control point is coincident with the current point
470
+ controlX = x;
471
+ controlY = y;
472
+ }
473
+ x = current[1];
474
+ y = current[2];
475
+ converted = ['Q', controlX, controlY, x, y];
476
+ break;
477
+ case 'a':
478
+ current[6] += x;
479
+ current[7] += y;
480
+ // falls through
481
+ case 'A':
482
+ fromArcToBeziers(x, y, current).forEach((b) => destinationPath.push(b));
483
+ x = current[6];
484
+ y = current[7];
485
+ break;
486
+ case 'z':
487
+ case 'Z':
488
+ x = x1;
489
+ y = y1;
490
+ converted = ['Z'];
491
+ break;
492
+ default:
493
+ }
494
+ if (converted) {
495
+ destinationPath.push(converted);
496
+ previous = converted[0];
497
+ } else {
498
+ previous = '';
499
+ }
500
+ }
501
+ return destinationPath;
502
+ };
503
+
504
+ // todo verify if we can just use the point class here
505
+ /**
506
+ * Calc length from point x1,y1 to x2,y2
507
+ * @param {number} x1 starting point x
508
+ * @param {number} y1 starting point y
509
+ * @param {number} x2 starting point x
510
+ * @param {number} y2 starting point y
511
+ * @return {number} length of segment
512
+ */
513
+ const calcLineLength = (
514
+ x1: number,
515
+ y1: number,
516
+ x2: number,
517
+ y2: number
518
+ ): number => Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
519
+
520
+ /**
521
+ * Get an iterator that takes a percentage and returns a point
522
+ * @param {number} begx
523
+ * @param {number} begy
524
+ * @param {number} cp1x
525
+ * @param {number} cp1y
526
+ * @param {number} cp2x
527
+ * @param {number} cp2y
528
+ * @param {number} endx
529
+ * @param {number} endy
530
+ */
531
+ const getPointOnCubicBezierIterator =
532
+ (
533
+ begx: number,
534
+ begy: number,
535
+ cp1x: number,
536
+ cp1y: number,
537
+ cp2x: number,
538
+ cp2y: number,
539
+ endx: number,
540
+ endy: number
541
+ ) =>
542
+ (pct: number) => {
543
+ const c1 = CB1(pct),
544
+ c2 = CB2(pct),
545
+ c3 = CB3(pct),
546
+ c4 = CB4(pct);
547
+ return new Point(
548
+ endx * c1 + cp2x * c2 + cp1x * c3 + begx * c4,
549
+ endy * c1 + cp2y * c2 + cp1y * c3 + begy * c4
550
+ );
551
+ };
552
+
553
+ const QB1 = (t: number) => t ** 2;
554
+ const QB2 = (t: number) => 2 * t * (1 - t);
555
+ const QB3 = (t: number) => (1 - t) ** 2;
556
+
557
+ const getTangentCubicIterator =
558
+ (
559
+ p1x: number,
560
+ p1y: number,
561
+ p2x: number,
562
+ p2y: number,
563
+ p3x: number,
564
+ p3y: number,
565
+ p4x: number,
566
+ p4y: number
567
+ ) =>
568
+ (pct: number) => {
569
+ const qb1 = QB1(pct),
570
+ qb2 = QB2(pct),
571
+ qb3 = QB3(pct),
572
+ tangentX =
573
+ 3 * (qb3 * (p2x - p1x) + qb2 * (p3x - p2x) + qb1 * (p4x - p3x)),
574
+ tangentY =
575
+ 3 * (qb3 * (p2y - p1y) + qb2 * (p3y - p2y) + qb1 * (p4y - p3y));
576
+ return Math.atan2(tangentY, tangentX);
577
+ };
578
+
579
+ const getPointOnQuadraticBezierIterator =
580
+ (
581
+ p1x: number,
582
+ p1y: number,
583
+ p2x: number,
584
+ p2y: number,
585
+ p3x: number,
586
+ p3y: number
587
+ ) =>
588
+ (pct: number) => {
589
+ const c1 = QB1(pct),
590
+ c2 = QB2(pct),
591
+ c3 = QB3(pct);
592
+ return new Point(
593
+ p3x * c1 + p2x * c2 + p1x * c3,
594
+ p3y * c1 + p2y * c2 + p1y * c3
595
+ );
596
+ };
597
+
598
+ const getTangentQuadraticIterator =
599
+ (
600
+ p1x: number,
601
+ p1y: number,
602
+ p2x: number,
603
+ p2y: number,
604
+ p3x: number,
605
+ p3y: number
606
+ ) =>
607
+ (pct: number) => {
608
+ const invT = 1 - pct,
609
+ tangentX = 2 * (invT * (p2x - p1x) + pct * (p3x - p2x)),
610
+ tangentY = 2 * (invT * (p2y - p1y) + pct * (p3y - p2y));
611
+ return Math.atan2(tangentY, tangentX);
612
+ };
613
+
614
+ // this will run over a path segment (a cubic or quadratic segment) and approximate it
615
+ // with 100 segments. This will good enough to calculate the length of the curve
616
+ const pathIterator = (
617
+ iterator: (pct: number) => Point,
618
+ x1: number,
619
+ y1: number
620
+ ) => {
621
+ let tempP = new Point(x1, y1),
622
+ tmpLen = 0;
623
+ for (let perc = 1; perc <= 100; perc += 1) {
624
+ const p = iterator(perc / 100);
625
+ tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y);
626
+ tempP = p;
627
+ }
628
+ return tmpLen;
629
+ };
630
+
631
+ /**
632
+ * Given a pathInfo, and a distance in pixels, find the percentage from 0 to 1
633
+ * that correspond to that pixels run over the path.
634
+ * The percentage will be then used to find the correct point on the canvas for the path.
635
+ * @param {Array} segInfo fabricJS collection of information on a parsed path
636
+ * @param {number} distance from starting point, in pixels.
637
+ * @return {TPointAngle} info object with x and y ( the point on canvas ) and angle, the tangent on that point;
638
+ */
639
+ const findPercentageForDistance = (
640
+ segInfo: TCurveInfo<'Q' | 'C'>,
641
+ distance: number
642
+ ): TPointAngle => {
643
+ let perc = 0,
644
+ tmpLen = 0,
645
+ tempP: XY = { x: segInfo.x, y: segInfo.y },
646
+ p: XY = { ...tempP },
647
+ nextLen: number,
648
+ nextStep = 0.01,
649
+ lastPerc = 0;
650
+ // nextStep > 0.0001 covers 0.00015625 that 1/64th of 1/100
651
+ // the path
652
+ const iterator = segInfo.iterator,
653
+ angleFinder = segInfo.angleFinder;
654
+ while (tmpLen < distance && nextStep > 0.0001) {
655
+ p = iterator(perc);
656
+ lastPerc = perc;
657
+ nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y);
658
+ // compare tmpLen each cycle with distance, decide next perc to test.
659
+ if (nextLen + tmpLen > distance) {
660
+ // we discard this step and we make smaller steps.
661
+ perc -= nextStep;
662
+ nextStep /= 2;
663
+ } else {
664
+ tempP = p;
665
+ perc += nextStep;
666
+ tmpLen += nextLen;
667
+ }
668
+ }
669
+ return { ...p, angle: angleFinder(lastPerc) };
670
+ };
671
+
672
+ /**
673
+ * Run over a parsed and simplified path and extract some information (length of each command and starting point)
674
+ * @param {TSimplePathData} path parsed path commands
675
+ * @return {TPathSegmentInfo[]} path commands information
676
+ */
677
+ export const getPathSegmentsInfo = (
678
+ path: TSimplePathData
679
+ ): TPathSegmentInfo[] => {
680
+ let totalLength = 0,
681
+ //x2 and y2 are the coords of segment start
682
+ //x1 and y1 are the coords of the current point
683
+ x1 = 0,
684
+ y1 = 0,
685
+ x2 = 0,
686
+ y2 = 0,
687
+ iterator,
688
+ tempInfo: TPathSegmentInfo;
689
+ const info: TPathSegmentInfo[] = [];
690
+ for (const current of path) {
691
+ const basicInfo: TPathSegmentInfoCommon<keyof TPathSegmentCommandInfo> = {
692
+ x: x1,
693
+ y: y1,
694
+ command: current[0],
695
+ length: 0,
696
+ };
697
+ switch (
698
+ current[0] //first letter
699
+ ) {
700
+ case 'M':
701
+ tempInfo = <TPathSegmentInfoCommon<'M'>>basicInfo;
702
+ x2 = x1 = current[1];
703
+ y2 = y1 = current[2];
704
+ break;
705
+ case 'L':
706
+ tempInfo = <TPathSegmentInfoCommon<'L'>>basicInfo;
707
+ tempInfo.length = calcLineLength(x1, y1, current[1], current[2]);
708
+ x1 = current[1];
709
+ y1 = current[2];
710
+ break;
711
+ case 'C':
712
+ iterator = getPointOnCubicBezierIterator(
713
+ x1,
714
+ y1,
715
+ current[1],
716
+ current[2],
717
+ current[3],
718
+ current[4],
719
+ current[5],
720
+ current[6]
721
+ );
722
+ tempInfo = <TCurveInfo<'C'>>basicInfo;
723
+ tempInfo.iterator = iterator;
724
+ tempInfo.angleFinder = getTangentCubicIterator(
725
+ x1,
726
+ y1,
727
+ current[1],
728
+ current[2],
729
+ current[3],
730
+ current[4],
731
+ current[5],
732
+ current[6]
733
+ );
734
+ tempInfo.length = pathIterator(iterator, x1, y1);
735
+
736
+ x1 = current[5];
737
+ y1 = current[6];
738
+ break;
739
+ case 'Q':
740
+ iterator = getPointOnQuadraticBezierIterator(
741
+ x1,
742
+ y1,
743
+ current[1],
744
+ current[2],
745
+ current[3],
746
+ current[4]
747
+ );
748
+ tempInfo = <TCurveInfo<'Q'>>basicInfo;
749
+ tempInfo.iterator = iterator;
750
+ tempInfo.angleFinder = getTangentQuadraticIterator(
751
+ x1,
752
+ y1,
753
+ current[1],
754
+ current[2],
755
+ current[3],
756
+ current[4]
757
+ );
758
+ tempInfo.length = pathIterator(iterator, x1, y1);
759
+ x1 = current[3];
760
+ y1 = current[4];
761
+ break;
762
+ case 'Z':
763
+ // we add those in order to ease calculations later
764
+ tempInfo = <TEndPathInfo>basicInfo;
765
+ tempInfo.destX = x2;
766
+ tempInfo.destY = y2;
767
+ tempInfo.length = calcLineLength(x1, y1, x2, y2);
768
+ x1 = x2;
769
+ y1 = y2;
770
+ break;
771
+ }
772
+ totalLength += tempInfo.length;
773
+ info.push(tempInfo);
774
+ }
775
+ info.push({ length: totalLength, x: x1, y: y1 });
776
+ return info;
777
+ };
778
+
779
+ /**
780
+ * Get the point on the path that is distance along the path
781
+ * @param path
782
+ * @param distance
783
+ * @param infos
784
+ */
785
+ export const getPointOnPath = (
786
+ path: TSimplePathData,
787
+ distance: number,
788
+ infos: TPathSegmentInfo[] = getPathSegmentsInfo(path)
789
+ ): TPointAngle | undefined => {
790
+ let i = 0;
791
+ while (distance - infos[i].length > 0 && i < infos.length - 2) {
792
+ distance -= infos[i].length;
793
+ i++;
794
+ }
795
+ const segInfo = infos[i],
796
+ segPercent = distance / segInfo.length,
797
+ segment = path[i];
798
+
799
+ switch (segInfo.command) {
800
+ case 'M':
801
+ return { x: segInfo.x, y: segInfo.y, angle: 0 };
802
+ case 'Z':
803
+ return {
804
+ ...new Point(segInfo.x, segInfo.y).lerp(
805
+ new Point(segInfo.destX, segInfo.destY),
806
+ segPercent
807
+ ),
808
+ angle: Math.atan2(segInfo.destY - segInfo.y, segInfo.destX - segInfo.x),
809
+ };
810
+ case 'L':
811
+ return {
812
+ ...new Point(segInfo.x, segInfo.y).lerp(
813
+ new Point(segment[1]!, segment[2]!),
814
+ segPercent
815
+ ),
816
+ angle: Math.atan2(segment[2]! - segInfo.y, segment[1]! - segInfo.x),
817
+ };
818
+ case 'C':
819
+ return findPercentageForDistance(segInfo, distance);
820
+ case 'Q':
821
+ return findPercentageForDistance(segInfo, distance);
822
+ default:
823
+ // throw Error('Invalid command');
824
+ }
825
+ };
826
+
827
+ /**
828
+ *
829
+ * @param {string} pathString
830
+ * @return {TComplexPathData} An array of SVG path commands
831
+ * @example <caption>Usage</caption>
832
+ * parsePath('M 3 4 Q 3 5 2 1 4 0 Q 9 12 2 1 4 0') === [
833
+ * ['M', 3, 4],
834
+ * ['Q', 3, 5, 2, 1, 4, 0],
835
+ * ['Q', 9, 12, 2, 1, 4, 0],
836
+ * ];
837
+ *
838
+ */
839
+ export const parsePath = (pathString: string): TComplexPathData => {
840
+ // clean the string
841
+ // add spaces around the numbers
842
+ pathString = pathString
843
+ .replace(new RegExp(`(${numberRegExStr})`, 'gi'), ' $1 ')
844
+ // replace annoying commas and arbitrary whitespace with single spaces
845
+ .replace(/,/gi, ' ')
846
+ .replace(/\s+/gi, ' ');
847
+
848
+ const res: TComplexPathData = [];
849
+ for (const match of pathString.matchAll(new RegExp(rePathCommand, 'gi'))) {
850
+ let matchStr = match[0];
851
+ const chain: TComplexPathData = [];
852
+ let paramArr: RegExpExecArray | null;
853
+ do {
854
+ paramArr = new RegExp(rePathCommand, 'i').exec(matchStr);
855
+ if (!paramArr) {
856
+ break;
857
+ }
858
+ // ignore undefined match groups
859
+ const filteredGroups = paramArr.filter((g) => g);
860
+ // remove the first element from the match array since it's just the whole command
861
+ filteredGroups.shift();
862
+ // if we can't parse the number, just interpret it as a string
863
+ // (since it's probably the path command)
864
+ const command = filteredGroups.map((g) => {
865
+ const numParse = Number.parseFloat(g);
866
+ if (Number.isNaN(numParse)) {
867
+ return g;
868
+ } else {
869
+ return numParse;
870
+ }
871
+ });
872
+ chain.push(command as any);
873
+ // stop now if it's a z command
874
+ if (filteredGroups.length <= 1) {
875
+ break;
876
+ }
877
+ // remove the last part of the chained command
878
+ filteredGroups.shift();
879
+ // ` ?` is to support commands with optional spaces between flags
880
+ matchStr = matchStr.replace(
881
+ new RegExp(`${filteredGroups.join(' ?')} ?$`),
882
+ ''
883
+ );
884
+ } while (paramArr);
885
+ // add the chain, convert multiple m's to l's in the process
886
+ chain.reverse().forEach((c, idx) => {
887
+ const transformed = repeatedCommands[c[0]];
888
+ if (idx > 0 && (transformed == 'l' || transformed == 'L')) {
889
+ c[0] = transformed;
890
+ }
891
+ res.push(c);
892
+ });
893
+ }
894
+ return res;
895
+ };
896
+
897
+ /**
898
+ *
899
+ * Converts points to a smooth SVG path
900
+ * @param {XY[]} points Array of points
901
+ * @param {number} [correction] Apply a correction to the path (usually we use `width / 1000`). If value is undefined 0 is used as the correction value.
902
+ * @return {(string|number)[][]} An array of SVG path commands
903
+ */
904
+ export const getSmoothPathFromPoints = (
905
+ points: Point[],
906
+ correction = 0
907
+ ): TSimplePathData => {
908
+ let p1 = new Point(points[0]),
909
+ p2 = new Point(points[1]),
910
+ multSignX = 1,
911
+ multSignY = 0;
912
+ const path: TSimplePathData = [],
913
+ len = points.length,
914
+ manyPoints = len > 2;
915
+
916
+ if (manyPoints) {
917
+ multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;
918
+ multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1;
919
+ }
920
+ path.push([
921
+ 'M',
922
+ p1.x - multSignX * correction,
923
+ p1.y - multSignY * correction,
924
+ ]);
925
+ let i;
926
+ for (i = 1; i < len; i++) {
927
+ if (!p1.eq(p2)) {
928
+ const midPoint = p1.midPointFrom(p2);
929
+ // p1 is our bezier control point
930
+ // midpoint is our endpoint
931
+ // start point is p(i-1) value.
932
+ path.push(['Q', p1.x, p1.y, midPoint.x, midPoint.y]);
933
+ }
934
+ p1 = points[i];
935
+ if (i + 1 < points.length) {
936
+ p2 = points[i + 1];
937
+ }
938
+ }
939
+ if (manyPoints) {
940
+ multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1;
941
+ multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1;
942
+ }
943
+ path.push([
944
+ 'L',
945
+ p1.x + multSignX * correction,
946
+ p1.y + multSignY * correction,
947
+ ]);
948
+ return path;
949
+ };
950
+
951
+ /**
952
+ * Transform a path by transforming each segment.
953
+ * it has to be a simplified path or it won't work.
954
+ * WARNING: this depends from pathOffset for correct operation
955
+ * @param {TSimplePathData} path fabricJS parsed and simplified path commands
956
+ * @param {TMat2D} transform matrix that represent the transformation
957
+ * @param {Point} [pathOffset] `Path.pathOffset`
958
+ * @returns {TSimplePathData} the transformed path
959
+ */
960
+ export const transformPath = (
961
+ path: TSimplePathData,
962
+ transform: TMat2D,
963
+ pathOffset: Point
964
+ ): TSimplePathData => {
965
+ if (pathOffset) {
966
+ transform = multiplyTransformMatrices(transform, [
967
+ 1,
968
+ 0,
969
+ 0,
970
+ 1,
971
+ -pathOffset.x,
972
+ -pathOffset.y,
973
+ ]);
974
+ }
975
+ return path.map((pathSegment) => {
976
+ const newSegment: TSimpleParsedCommand = [...pathSegment];
977
+ for (let i = 1; i < pathSegment.length - 1; i += 2) {
978
+ // TODO: is there a way to get around casting to any?
979
+ const { x, y } = transformPoint(
980
+ {
981
+ x: pathSegment[i] as number,
982
+ y: pathSegment[i + 1] as number,
983
+ },
984
+ transform
985
+ );
986
+ newSegment[i] = x;
987
+ newSegment[i + 1] = y;
988
+ }
989
+ return newSegment;
990
+ });
991
+ };
992
+
993
+ /**
994
+ * Returns an array of path commands to create a regular polygon
995
+ * @param {number} numVertexes
996
+ * @param {number} radius
997
+ * @returns {TSimplePathData} An array of SVG path commands
998
+ */
999
+ export const getRegularPolygonPath = (
1000
+ numVertexes: number,
1001
+ radius: number
1002
+ ): TSimplePathData => {
1003
+ const interiorAngle = (Math.PI * 2) / numVertexes;
1004
+ // rotationAdjustment rotates the path by 1/2 the interior angle so that the polygon always has a flat side on the bottom
1005
+ // This isn't strictly necessary, but it's how we tend to think of and expect polygons to be drawn
1006
+ let rotationAdjustment = -halfPI;
1007
+ if (numVertexes % 2 === 0) {
1008
+ rotationAdjustment += interiorAngle / 2;
1009
+ }
1010
+ const d = new Array(numVertexes + 1);
1011
+ for (let i = 0; i < numVertexes; i++) {
1012
+ const rad = i * interiorAngle + rotationAdjustment;
1013
+ const { x, y } = new Point(cos(rad), sin(rad)).scalarMultiply(radius);
1014
+ d[i] = [i === 0 ? 'M' : 'L', x, y];
1015
+ }
1016
+ d[numVertexes] = ['Z'];
1017
+ return d;
1018
+ };
1019
+
1020
+ /**
1021
+ * Join path commands to go back to svg format
1022
+ * @param {TSimplePathData} pathData fabricJS parsed path commands
1023
+ * @param {number} fractionDigits number of fraction digits to "leave"
1024
+ * @return {String} joined path 'M 0 0 L 20 30'
1025
+ */
1026
+ export const joinPath = (pathData: TSimplePathData, fractionDigits?: number) =>
1027
+ pathData
1028
+ .map((segment) => {
1029
+ return segment
1030
+ .map((arg, i) => {
1031
+ if (i === 0) return arg;
1032
+ return fractionDigits === undefined
1033
+ ? arg
1034
+ : toFixed(arg, fractionDigits);
1035
+ })
1036
+ .join(' ');
1037
+ })
1038
+ .join(' ');