fabric 7.0.0 → 7.2.0

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 (323) hide show
  1. package/.husky/pre-commit +1 -0
  2. package/CHANGELOG.md +21 -0
  3. package/dist/extensions/cropping_controls/croppingControls.d.ts +16 -0
  4. package/dist/extensions/cropping_controls/croppingControls.d.ts.map +1 -0
  5. package/dist/extensions/cropping_controls/croppingHandlers.d.ts +39 -0
  6. package/dist/extensions/cropping_controls/croppingHandlers.d.ts.map +1 -0
  7. package/dist/extensions/cropping_controls/enterCropMode.d.ts +7 -0
  8. package/dist/extensions/cropping_controls/enterCropMode.d.ts.map +1 -0
  9. package/dist/extensions/cropping_controls/renderCornerControl.d.ts +14 -0
  10. package/dist/extensions/cropping_controls/renderCornerControl.d.ts.map +1 -0
  11. package/dist/extensions/index.d.ts +3 -0
  12. package/dist/extensions/index.d.ts.map +1 -1
  13. package/dist/fabric.d.ts +1 -0
  14. package/dist/fabric.d.ts.map +1 -1
  15. package/dist/index.js +628 -537
  16. package/dist/index.js.map +1 -1
  17. package/dist/index.min.js +1 -1
  18. package/dist/index.min.js.map +1 -1
  19. package/dist/index.min.mjs +1 -1
  20. package/dist/index.min.mjs.map +1 -1
  21. package/dist/index.mjs +628 -537
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/index.node.cjs +628 -537
  24. package/dist/index.node.cjs.map +1 -1
  25. package/dist/index.node.mjs +628 -537
  26. package/dist/index.node.mjs.map +1 -1
  27. package/dist/package.json.min.mjs +1 -1
  28. package/dist/package.json.mjs +1 -1
  29. package/dist/src/EventTypeDefs.d.ts +5 -0
  30. package/dist/src/EventTypeDefs.d.ts.map +1 -1
  31. package/dist/src/Pattern/Pattern.d.ts.map +1 -1
  32. package/dist/src/Pattern/Pattern.min.mjs +1 -1
  33. package/dist/src/Pattern/Pattern.min.mjs.map +1 -1
  34. package/dist/src/Pattern/Pattern.mjs +2 -1
  35. package/dist/src/Pattern/Pattern.mjs.map +1 -1
  36. package/dist/src/Shadow.d.ts +1 -1
  37. package/dist/src/Shadow.d.ts.map +1 -1
  38. package/dist/src/Shadow.min.mjs +1 -1
  39. package/dist/src/Shadow.min.mjs.map +1 -1
  40. package/dist/src/Shadow.mjs +5 -4
  41. package/dist/src/Shadow.mjs.map +1 -1
  42. package/dist/src/canvas/CanvasOptions.d.ts.map +1 -1
  43. package/dist/src/canvas/CanvasOptions.min.mjs.map +1 -1
  44. package/dist/src/canvas/CanvasOptions.mjs.map +1 -1
  45. package/dist/src/canvas/SelectableCanvas.d.ts +2 -0
  46. package/dist/src/canvas/SelectableCanvas.d.ts.map +1 -1
  47. package/dist/src/canvas/SelectableCanvas.min.mjs +1 -1
  48. package/dist/src/canvas/SelectableCanvas.min.mjs.map +1 -1
  49. package/dist/src/canvas/SelectableCanvas.mjs +33 -13
  50. package/dist/src/canvas/SelectableCanvas.mjs.map +1 -1
  51. package/dist/src/canvas/StaticCanvas.d.ts.map +1 -1
  52. package/dist/src/canvas/StaticCanvas.min.mjs +1 -1
  53. package/dist/src/canvas/StaticCanvas.min.mjs.map +1 -1
  54. package/dist/src/canvas/StaticCanvas.mjs +3 -1
  55. package/dist/src/canvas/StaticCanvas.mjs.map +1 -1
  56. package/dist/src/canvas/StaticCanvasOptions.d.ts.map +1 -1
  57. package/dist/src/canvas/StaticCanvasOptions.min.mjs.map +1 -1
  58. package/dist/src/canvas/StaticCanvasOptions.mjs.map +1 -1
  59. package/dist/src/constants.d.ts +1 -0
  60. package/dist/src/constants.d.ts.map +1 -1
  61. package/dist/src/constants.min.mjs.map +1 -1
  62. package/dist/src/constants.mjs.map +1 -1
  63. package/dist/src/controls/Control.d.ts +22 -1
  64. package/dist/src/controls/Control.d.ts.map +1 -1
  65. package/dist/src/controls/Control.min.mjs +1 -1
  66. package/dist/src/controls/Control.min.mjs.map +1 -1
  67. package/dist/src/controls/Control.mjs +45 -1
  68. package/dist/src/controls/Control.mjs.map +1 -1
  69. package/dist/src/controls/changeWidth.d.ts +22 -0
  70. package/dist/src/controls/changeWidth.d.ts.map +1 -1
  71. package/dist/src/controls/changeWidth.min.mjs +1 -1
  72. package/dist/src/controls/changeWidth.min.mjs.map +1 -1
  73. package/dist/src/controls/changeWidth.mjs +46 -18
  74. package/dist/src/controls/changeWidth.mjs.map +1 -1
  75. package/dist/src/controls/controlRendering.d.ts.map +1 -1
  76. package/dist/src/controls/controlRendering.min.mjs +1 -1
  77. package/dist/src/controls/controlRendering.min.mjs.map +1 -1
  78. package/dist/src/controls/controlRendering.mjs +18 -34
  79. package/dist/src/controls/controlRendering.mjs.map +1 -1
  80. package/dist/src/controls/index.d.ts +2 -1
  81. package/dist/src/controls/index.d.ts.map +1 -1
  82. package/dist/src/controls/index.min.mjs +1 -1
  83. package/dist/src/controls/index.mjs +1 -1
  84. package/dist/src/gradient/Gradient.d.ts.map +1 -1
  85. package/dist/src/gradient/Gradient.min.mjs +1 -1
  86. package/dist/src/gradient/Gradient.min.mjs.map +1 -1
  87. package/dist/src/gradient/Gradient.mjs +19 -6
  88. package/dist/src/gradient/Gradient.mjs.map +1 -1
  89. package/dist/src/shapes/Circle.d.ts.map +1 -1
  90. package/dist/src/shapes/Circle.min.mjs +1 -1
  91. package/dist/src/shapes/Circle.min.mjs.map +1 -1
  92. package/dist/src/shapes/Circle.mjs +10 -7
  93. package/dist/src/shapes/Circle.mjs.map +1 -1
  94. package/dist/src/shapes/Ellipse.d.ts.map +1 -1
  95. package/dist/src/shapes/Ellipse.min.mjs +1 -1
  96. package/dist/src/shapes/Ellipse.min.mjs.map +1 -1
  97. package/dist/src/shapes/Ellipse.mjs +2 -1
  98. package/dist/src/shapes/Ellipse.mjs.map +1 -1
  99. package/dist/src/shapes/Group.d.ts.map +1 -1
  100. package/dist/src/shapes/Group.min.mjs +1 -1
  101. package/dist/src/shapes/Group.min.mjs.map +1 -1
  102. package/dist/src/shapes/Group.mjs +2 -1
  103. package/dist/src/shapes/Group.mjs.map +1 -1
  104. package/dist/src/shapes/IText/IText.d.ts.map +1 -1
  105. package/dist/src/shapes/IText/IText.min.mjs.map +1 -1
  106. package/dist/src/shapes/IText/IText.mjs.map +1 -1
  107. package/dist/src/shapes/Image.d.ts +1 -1
  108. package/dist/src/shapes/Image.d.ts.map +1 -1
  109. package/dist/src/shapes/Image.min.mjs +1 -1
  110. package/dist/src/shapes/Image.min.mjs.map +1 -1
  111. package/dist/src/shapes/Image.mjs +4 -3
  112. package/dist/src/shapes/Image.mjs.map +1 -1
  113. package/dist/src/shapes/Line.d.ts.map +1 -1
  114. package/dist/src/shapes/Line.min.mjs +1 -1
  115. package/dist/src/shapes/Line.min.mjs.map +1 -1
  116. package/dist/src/shapes/Line.mjs +6 -10
  117. package/dist/src/shapes/Line.mjs.map +1 -1
  118. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.d.ts.map +1 -1
  119. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.min.mjs +1 -1
  120. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.min.mjs.map +1 -1
  121. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.mjs +5 -4
  122. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.mjs.map +1 -1
  123. package/dist/src/shapes/Object/InteractiveObject.d.ts.map +1 -1
  124. package/dist/src/shapes/Object/InteractiveObject.min.mjs.map +1 -1
  125. package/dist/src/shapes/Object/InteractiveObject.mjs.map +1 -1
  126. package/dist/src/shapes/Object/Object.d.ts.map +1 -1
  127. package/dist/src/shapes/Object/Object.min.mjs +1 -1
  128. package/dist/src/shapes/Object/Object.min.mjs.map +1 -1
  129. package/dist/src/shapes/Object/Object.mjs +3 -0
  130. package/dist/src/shapes/Object/Object.mjs.map +1 -1
  131. package/dist/src/shapes/Object/ObjectGeometry.min.mjs +1 -1
  132. package/dist/src/shapes/Object/ObjectGeometry.min.mjs.map +1 -1
  133. package/dist/src/shapes/Object/ObjectGeometry.mjs +1 -1
  134. package/dist/src/shapes/Object/ObjectGeometry.mjs.map +1 -1
  135. package/dist/src/shapes/Object/types/FabricObjectProps.d.ts.map +1 -1
  136. package/dist/src/shapes/Object/types/ObjectProps.d.ts.map +1 -1
  137. package/dist/src/shapes/Path.d.ts.map +1 -1
  138. package/dist/src/shapes/Path.min.mjs.map +1 -1
  139. package/dist/src/shapes/Path.mjs +1 -2
  140. package/dist/src/shapes/Path.mjs.map +1 -1
  141. package/dist/src/shapes/Polyline.d.ts.map +1 -1
  142. package/dist/src/shapes/Polyline.min.mjs +1 -1
  143. package/dist/src/shapes/Polyline.min.mjs.map +1 -1
  144. package/dist/src/shapes/Polyline.mjs +10 -6
  145. package/dist/src/shapes/Polyline.mjs.map +1 -1
  146. package/dist/src/shapes/Rect.d.ts.map +1 -1
  147. package/dist/src/shapes/Rect.min.mjs +1 -1
  148. package/dist/src/shapes/Rect.min.mjs.map +1 -1
  149. package/dist/src/shapes/Rect.mjs +2 -1
  150. package/dist/src/shapes/Rect.mjs.map +1 -1
  151. package/dist/src/shapes/Text/StyledText.d.ts.map +1 -1
  152. package/dist/src/shapes/Text/StyledText.min.mjs.map +1 -1
  153. package/dist/src/shapes/Text/StyledText.mjs +0 -3
  154. package/dist/src/shapes/Text/StyledText.mjs.map +1 -1
  155. package/dist/src/shapes/Text/Text.d.ts.map +1 -1
  156. package/dist/src/shapes/Text/Text.min.mjs.map +1 -1
  157. package/dist/src/shapes/Text/Text.mjs.map +1 -1
  158. package/dist/src/shapes/Text/TextSVGExportMixin.d.ts.map +1 -1
  159. package/dist/src/shapes/Text/TextSVGExportMixin.min.mjs +1 -1
  160. package/dist/src/shapes/Text/TextSVGExportMixin.min.mjs.map +1 -1
  161. package/dist/src/shapes/Text/TextSVGExportMixin.mjs +5 -6
  162. package/dist/src/shapes/Text/TextSVGExportMixin.mjs.map +1 -1
  163. package/dist/src/shapes/Textbox.d.ts.map +1 -1
  164. package/dist/src/shapes/Textbox.min.mjs.map +1 -1
  165. package/dist/src/shapes/Textbox.mjs.map +1 -1
  166. package/dist/src/shapes/Triangle.d.ts.map +1 -1
  167. package/dist/src/shapes/Triangle.min.mjs.map +1 -1
  168. package/dist/src/shapes/Triangle.mjs.map +1 -1
  169. package/dist/src/util/lang_string.d.ts +1 -1
  170. package/dist/src/util/lang_string.d.ts.map +1 -1
  171. package/dist/src/util/lang_string.min.mjs +1 -1
  172. package/dist/src/util/lang_string.min.mjs.map +1 -1
  173. package/dist/src/util/lang_string.mjs +1 -1
  174. package/dist/src/util/lang_string.mjs.map +1 -1
  175. package/dist/src/util/misc/svgParsing.d.ts.map +1 -1
  176. package/dist/src/util/misc/svgParsing.min.mjs +1 -1
  177. package/dist/src/util/misc/svgParsing.min.mjs.map +1 -1
  178. package/dist/src/util/misc/svgParsing.mjs +2 -1
  179. package/dist/src/util/misc/svgParsing.mjs.map +1 -1
  180. package/dist-extensions/cropping_controls/croppingControls.mjs +140 -0
  181. package/dist-extensions/cropping_controls/croppingControls.mjs.map +1 -0
  182. package/dist-extensions/cropping_controls/croppingHandlers.mjs +228 -0
  183. package/dist-extensions/cropping_controls/croppingHandlers.mjs.map +1 -0
  184. package/dist-extensions/cropping_controls/enterCropMode.mjs +38 -0
  185. package/dist-extensions/cropping_controls/enterCropMode.mjs.map +1 -0
  186. package/dist-extensions/cropping_controls/renderCornerControl.mjs +45 -0
  187. package/dist-extensions/cropping_controls/renderCornerControl.mjs.map +1 -0
  188. package/dist-extensions/extensions/cropping_controls/croppingControls.d.ts +16 -0
  189. package/dist-extensions/extensions/cropping_controls/croppingControls.d.ts.map +1 -0
  190. package/dist-extensions/extensions/cropping_controls/croppingHandlers.d.ts +39 -0
  191. package/dist-extensions/extensions/cropping_controls/croppingHandlers.d.ts.map +1 -0
  192. package/dist-extensions/extensions/cropping_controls/enterCropMode.d.ts +7 -0
  193. package/dist-extensions/extensions/cropping_controls/enterCropMode.d.ts.map +1 -0
  194. package/dist-extensions/extensions/cropping_controls/renderCornerControl.d.ts +14 -0
  195. package/dist-extensions/extensions/cropping_controls/renderCornerControl.d.ts.map +1 -0
  196. package/dist-extensions/extensions/index.d.ts +3 -0
  197. package/dist-extensions/extensions/index.d.ts.map +1 -1
  198. package/dist-extensions/fabric-extensions.min.js +1 -1
  199. package/dist-extensions/fabric-extensions.min.js.map +1 -1
  200. package/dist-extensions/fabric.d.ts +1 -0
  201. package/dist-extensions/fabric.d.ts.map +1 -1
  202. package/dist-extensions/index.mjs +3 -0
  203. package/dist-extensions/index.mjs.map +1 -1
  204. package/dist-extensions/src/EventTypeDefs.d.ts +5 -0
  205. package/dist-extensions/src/EventTypeDefs.d.ts.map +1 -1
  206. package/dist-extensions/src/Pattern/Pattern.d.ts.map +1 -1
  207. package/dist-extensions/src/Shadow.d.ts +1 -1
  208. package/dist-extensions/src/Shadow.d.ts.map +1 -1
  209. package/dist-extensions/src/canvas/CanvasOptions.d.ts.map +1 -1
  210. package/dist-extensions/src/canvas/SelectableCanvas.d.ts +2 -0
  211. package/dist-extensions/src/canvas/SelectableCanvas.d.ts.map +1 -1
  212. package/dist-extensions/src/canvas/StaticCanvas.d.ts.map +1 -1
  213. package/dist-extensions/src/canvas/StaticCanvasOptions.d.ts.map +1 -1
  214. package/dist-extensions/src/constants.d.ts +1 -0
  215. package/dist-extensions/src/constants.d.ts.map +1 -1
  216. package/dist-extensions/src/controls/Control.d.ts +22 -1
  217. package/dist-extensions/src/controls/Control.d.ts.map +1 -1
  218. package/dist-extensions/src/controls/changeWidth.d.ts +22 -0
  219. package/dist-extensions/src/controls/changeWidth.d.ts.map +1 -1
  220. package/dist-extensions/src/controls/controlRendering.d.ts.map +1 -1
  221. package/dist-extensions/src/controls/index.d.ts +2 -1
  222. package/dist-extensions/src/controls/index.d.ts.map +1 -1
  223. package/dist-extensions/src/gradient/Gradient.d.ts.map +1 -1
  224. package/dist-extensions/src/shapes/Circle.d.ts.map +1 -1
  225. package/dist-extensions/src/shapes/Ellipse.d.ts.map +1 -1
  226. package/dist-extensions/src/shapes/Group.d.ts.map +1 -1
  227. package/dist-extensions/src/shapes/IText/IText.d.ts.map +1 -1
  228. package/dist-extensions/src/shapes/Image.d.ts.map +1 -1
  229. package/dist-extensions/src/shapes/Line.d.ts.map +1 -1
  230. package/dist-extensions/src/shapes/Object/FabricObjectSVGExportMixin.d.ts.map +1 -1
  231. package/dist-extensions/src/shapes/Object/InteractiveObject.d.ts.map +1 -1
  232. package/dist-extensions/src/shapes/Object/Object.d.ts.map +1 -1
  233. package/dist-extensions/src/shapes/Object/types/FabricObjectProps.d.ts.map +1 -1
  234. package/dist-extensions/src/shapes/Object/types/ObjectProps.d.ts.map +1 -1
  235. package/dist-extensions/src/shapes/Path.d.ts +1 -1
  236. package/dist-extensions/src/shapes/Path.d.ts.map +1 -1
  237. package/dist-extensions/src/shapes/Polyline.d.ts.map +1 -1
  238. package/dist-extensions/src/shapes/Rect.d.ts.map +1 -1
  239. package/dist-extensions/src/shapes/Text/StyledText.d.ts.map +1 -1
  240. package/dist-extensions/src/shapes/Text/Text.d.ts.map +1 -1
  241. package/dist-extensions/src/shapes/Text/TextSVGExportMixin.d.ts.map +1 -1
  242. package/dist-extensions/src/shapes/Textbox.d.ts.map +1 -1
  243. package/dist-extensions/src/shapes/Triangle.d.ts.map +1 -1
  244. package/dist-extensions/src/util/lang_string.d.ts +1 -1
  245. package/dist-extensions/src/util/lang_string.d.ts.map +1 -1
  246. package/dist-extensions/src/util/misc/svgParsing.d.ts.map +1 -1
  247. package/eslint.config.mjs +2 -0
  248. package/extensions/cropping_controls/croppingControls.spec.ts +115 -0
  249. package/extensions/cropping_controls/croppingControls.ts +150 -0
  250. package/extensions/cropping_controls/croppingHandlers.spec.ts +579 -0
  251. package/extensions/cropping_controls/croppingHandlers.ts +285 -0
  252. package/extensions/cropping_controls/enterCropMode.ts +30 -0
  253. package/extensions/cropping_controls/renderCornerControl.ts +53 -0
  254. package/extensions/index.ts +9 -0
  255. package/fabric.ts +1 -0
  256. package/package.json +17 -8
  257. package/src/ClassRegistry.spec.ts +18 -19
  258. package/src/EventTypeDefs.ts +15 -11
  259. package/src/Pattern/Pattern.spec.ts +12 -0
  260. package/src/Pattern/Pattern.ts +3 -2
  261. package/src/Shadow.ts +9 -8
  262. package/src/brushes/PencilBrush.spec.ts +11 -11
  263. package/src/canvas/Canvas-dispose.spec.ts +8 -7
  264. package/src/canvas/Canvas.spec.ts +27 -29
  265. package/src/canvas/CanvasOptions.ts +2 -1
  266. package/src/canvas/SelectableCanvas.ts +38 -15
  267. package/src/canvas/StaticCanvas.spec.ts +20 -0
  268. package/src/canvas/StaticCanvas.ts +7 -4
  269. package/src/canvas/StaticCanvasOptions.ts +1 -3
  270. package/src/constants.ts +1 -0
  271. package/src/controls/Control.spec.ts +102 -0
  272. package/src/controls/Control.ts +71 -2
  273. package/src/controls/changeHeight.spec.ts +147 -0
  274. package/src/controls/changeWidth.ts +68 -35
  275. package/src/controls/controlRendering.ts +20 -48
  276. package/src/controls/index.ts +7 -1
  277. package/src/gradient/Gradient.spec.ts +101 -46
  278. package/src/gradient/Gradient.ts +27 -14
  279. package/src/shapes/Circle.spec.ts +10 -39
  280. package/src/shapes/Circle.ts +11 -11
  281. package/src/shapes/Ellipse.spec.ts +8 -37
  282. package/src/shapes/Ellipse.ts +7 -7
  283. package/src/shapes/Group.ts +3 -3
  284. package/src/shapes/IText/IText-click-behavior.spec.ts +36 -49
  285. package/src/shapes/IText/IText.ts +5 -6
  286. package/src/shapes/IText/ITextKeyBehavior.test.ts +0 -1
  287. package/src/shapes/IText/__snapshots__/ITextBehavior.test.ts.snap +6 -6
  288. package/src/shapes/Image.spec.ts +17 -33
  289. package/src/shapes/Image.ts +15 -11
  290. package/src/shapes/Line.spec.ts +4 -30
  291. package/src/shapes/Line.ts +11 -16
  292. package/src/shapes/Object/FabricObjectSVGExportMixin.ts +11 -4
  293. package/src/shapes/Object/InteractiveObject.ts +4 -4
  294. package/src/shapes/Object/Object.ts +6 -5
  295. package/src/shapes/Object/ObjectGeometry.spec.ts +15 -0
  296. package/src/shapes/Object/ObjectGeometry.ts +1 -1
  297. package/src/shapes/Object/objectSvgExport.spec.ts +112 -0
  298. package/src/shapes/Object/types/FabricObjectProps.ts +1 -4
  299. package/src/shapes/Object/types/ObjectProps.ts +1 -3
  300. package/src/shapes/Path.spec.ts +4 -27
  301. package/src/shapes/Path.ts +2 -4
  302. package/src/shapes/Polygon.spec.ts +4 -31
  303. package/src/shapes/Polyline.spec.ts +4 -31
  304. package/src/shapes/Polyline.ts +11 -12
  305. package/src/shapes/Rect.spec.ts +25 -33
  306. package/src/shapes/Rect.ts +7 -7
  307. package/src/shapes/Text/StyledText.ts +0 -3
  308. package/src/shapes/Text/Text.spec.ts +3 -32
  309. package/src/shapes/Text/Text.ts +5 -6
  310. package/src/shapes/Text/TextSVGExportMixin.spec.ts +9 -0
  311. package/src/shapes/Text/TextSVGExportMixin.ts +14 -16
  312. package/src/shapes/Text/__snapshots__/Text.spec.ts.snap +1 -1
  313. package/src/shapes/Text/__snapshots__/TextSVGExportMixin.spec.ts.snap +1 -1
  314. package/src/shapes/Textbox.spec.ts +5 -5
  315. package/src/shapes/Textbox.ts +6 -5
  316. package/src/shapes/Triangle.ts +4 -4
  317. package/src/shapes/__snapshots__/Image.spec.ts.snap +4 -4
  318. package/src/shapes/__snapshots__/Textbox.spec.ts.snap +5 -5
  319. package/src/util/lang_string.ts +3 -2
  320. package/src/util/misc/svgParsing.ts +2 -1
  321. package/tsconfig.spec.json +1 -0
  322. package/vitest.config.ts +12 -2
  323. package/vitest.extend.ts +6 -2
@@ -0,0 +1,228 @@
1
+ import { controlsUtils, util, Point } from 'fabric';
2
+
3
+ const {
4
+ wrapWithFixedAnchor,
5
+ wrapWithFireEvent
6
+ } = controlsUtils;
7
+
8
+ /**
9
+ * Wrap controlsUtils.changeObjectWidth with image constrains
10
+ */
11
+ const changeImageWidth = (eventData, transform, x, y) => {
12
+ const {
13
+ target
14
+ } = transform;
15
+ const {
16
+ width
17
+ } = target;
18
+ const image = target;
19
+ const modified = controlsUtils.changeObjectWidth(eventData, transform, x, y);
20
+ const availableWidth = image._element.width - image.cropX;
21
+ if (modified) {
22
+ if (image.width > availableWidth) {
23
+ image.width = availableWidth;
24
+ }
25
+ if (image.width < 1) {
26
+ image.width = 1;
27
+ }
28
+ }
29
+ return width !== image.width;
30
+ };
31
+ const changeCropWidth = wrapWithFireEvent('CROPPING', wrapWithFixedAnchor(changeImageWidth));
32
+
33
+ /**
34
+ * Wrap controlsUtils.changeObjectHeight with image constrains
35
+ */
36
+ const changeImageHeight = (eventData, transform, x, y) => {
37
+ const {
38
+ target
39
+ } = transform;
40
+ const {
41
+ height
42
+ } = target;
43
+ const image = target;
44
+ const modified = controlsUtils.changeObjectHeight(eventData, transform, x, y);
45
+ const availableHeight = image._element.height - image.cropY;
46
+ if (modified) {
47
+ if (image.height > availableHeight) {
48
+ image.height = availableHeight;
49
+ }
50
+ if (image.height < 1) {
51
+ image.height = 1;
52
+ }
53
+ }
54
+ return height !== image.height;
55
+ };
56
+ const changeCropHeight = wrapWithFireEvent('CROPPING', wrapWithFixedAnchor(changeImageHeight));
57
+ const changeImageCropX = (eventData, transform, x, y) => {
58
+ const {
59
+ target
60
+ } = transform;
61
+ const image = target;
62
+ const {
63
+ width,
64
+ cropX
65
+ } = image;
66
+ const modified = controlsUtils.changeObjectWidth(eventData, transform, x, y);
67
+ let newCropX = cropX + width - image.width;
68
+ image.width = width;
69
+ if (modified) {
70
+ if (newCropX < 0) {
71
+ newCropX = 0;
72
+ }
73
+ image.cropX = newCropX;
74
+ // calculate new width on the base of how much crop we have now
75
+ image.width += cropX - newCropX;
76
+ }
77
+ return newCropX !== cropX;
78
+ };
79
+ const changeImageCropY = (eventData, transform, x, y) => {
80
+ const {
81
+ target
82
+ } = transform;
83
+ const image = target;
84
+ const {
85
+ height,
86
+ cropY
87
+ } = image;
88
+ const modified = controlsUtils.changeObjectHeight(eventData, transform, x, y);
89
+ let newCropY = cropY + height - image.height;
90
+ image.height = height;
91
+ if (modified) {
92
+ if (newCropY < 0) {
93
+ newCropY = 0;
94
+ }
95
+ image.cropY = newCropY;
96
+ image.height += cropY - newCropY;
97
+ }
98
+ return newCropY !== cropY;
99
+ };
100
+ const changeCropX = wrapWithFireEvent('CROPPING', wrapWithFixedAnchor(changeImageCropX));
101
+ const changeCropY = wrapWithFireEvent('CROPPING', wrapWithFixedAnchor(changeImageCropY));
102
+
103
+ /**
104
+ * A function to counter the move action and change cropX/cropY of an image
105
+ * Keep the image steady, but moves it inside its own cropping rectangle
106
+ */
107
+ const cropPanMoveHandler = _ref => {
108
+ let {
109
+ transform
110
+ } = _ref;
111
+ // this makes the image pan too fast.
112
+ const {
113
+ target,
114
+ original
115
+ } = transform;
116
+ const fabricImage = target;
117
+ const p = new Point(target.left - original.left, target.top - original.top).transform(util.invertTransform(util.createRotateMatrix({
118
+ angle: fabricImage.getTotalAngle()
119
+ })));
120
+ let cropX = original.cropX - p.x / fabricImage.scaleX;
121
+ let cropY = original.cropY - p.y / fabricImage.scaleY;
122
+ const {
123
+ width,
124
+ height,
125
+ _element
126
+ } = fabricImage;
127
+ if (cropX < 0) {
128
+ cropX = 0;
129
+ }
130
+ if (cropY < 0) {
131
+ cropY = 0;
132
+ }
133
+ if (cropX + width > _element.width) {
134
+ cropX = _element.width - width;
135
+ }
136
+ if (cropY + height > _element.height) {
137
+ cropY = _element.height - height;
138
+ }
139
+ fabricImage.cropX = cropX;
140
+ fabricImage.cropY = cropY;
141
+ fabricImage.left = original.left;
142
+ fabricImage.top = original.top;
143
+ };
144
+
145
+ /**
146
+ * This position handler works only for this specific use case.
147
+ * It does not support padding nor offset, and it reduces all possible positions
148
+ * to the main 4 corners only.
149
+ * Any position that is < 0 is the extreme left/top, the rest are right/bottom
150
+ */
151
+ function ghostScalePositionHandler(dim,
152
+ // currentDimension
153
+ finalMatrix, fabricObject
154
+ // currentControl: Control,
155
+ ) {
156
+ const matrix = fabricObject.calcTransformMatrix();
157
+ const vpt = fabricObject.getViewportTransform();
158
+ const _finalMatrix = util.multiplyTransformMatrices(vpt, matrix);
159
+ let x = 0;
160
+ let y = 0;
161
+ if (this.x < 0) {
162
+ x = -fabricObject.width / 2 - fabricObject.cropX;
163
+ } else {
164
+ x = fabricObject.getElement().width - fabricObject.width / 2 - fabricObject.cropX;
165
+ }
166
+ if (this.y < 0) {
167
+ y = -fabricObject.height / 2 - fabricObject.cropY;
168
+ } else {
169
+ y = fabricObject.getElement().height - fabricObject.height / 2 - fabricObject.cropY;
170
+ }
171
+ return new Point(x, y).transform(_finalMatrix);
172
+ }
173
+ const calcScale = (currentPoint, height, width) => Math.min(Math.abs(currentPoint.x / width), Math.abs(currentPoint.y / height));
174
+
175
+ /**
176
+ * Action handler generator that handles scaling of an image in crop mode.
177
+ * The goal is to keep the current bounding box steady.
178
+ * So this action handler has its own calculations for a dynamic anchor point
179
+ */
180
+ const scaleEquallyCropGenerator = (cx, cy) => (eventData, transform, x, y) => {
181
+ const {
182
+ target
183
+ } = transform;
184
+ const {
185
+ width: fullWidth,
186
+ height: fullHeight
187
+ } = target.getElement();
188
+ const remainderX = fullWidth - target.width - target.cropX;
189
+ const remainderY = fullHeight - target.height - target.cropY;
190
+ const anchorOriginX = cx < 0 ? 1 + remainderX / target.width : -target.cropX / target.width;
191
+ const anchorOriginY = cy < 0 ? 1 + remainderY / target.height : -target.cropY / target.height;
192
+ const constraint = target.translateToOriginPoint(target.getCenterPoint(), anchorOriginX, anchorOriginY);
193
+ const newPoint = controlsUtils.getLocalPoint(transform, anchorOriginX, anchorOriginY, x, y);
194
+ const scale = calcScale(newPoint, fullHeight, fullWidth);
195
+ const scaleChangeX = scale / target.scaleX;
196
+ const scaleChangeY = scale / target.scaleY;
197
+ const scaledRemainderX = remainderX / scaleChangeX;
198
+ const scaledRemainderY = remainderY / scaleChangeY;
199
+ const newWidth = target.width / scaleChangeX;
200
+ const newHeight = target.height / scaleChangeY;
201
+ const newCropX = cx < 0 ? fullWidth - newWidth - scaledRemainderX : target.cropX / scaleChangeX;
202
+ const newCropY = cy < 0 ? fullHeight - newHeight - scaledRemainderY : target.cropY / scaleChangeY;
203
+ if ((cx < 0 ? scaledRemainderX : newCropX) + newWidth > fullWidth || (cy < 0 ? scaledRemainderY : newCropY) + newHeight > fullHeight) {
204
+ return false;
205
+ }
206
+ target.scaleX = scale;
207
+ target.scaleY = scale;
208
+ target.width = newWidth;
209
+ target.height = newHeight;
210
+ target.cropX = newCropX;
211
+ target.cropY = newCropY;
212
+ const newAnchorOriginX = cx < 0 ? 1 + scaledRemainderX / newWidth : -newCropX / newWidth;
213
+ const newAnchorOriginY = cy < 0 ? 1 + scaledRemainderY / newHeight : -newCropY / newHeight;
214
+ target.setPositionByOrigin(constraint, newAnchorOriginX, newAnchorOriginY);
215
+ return true;
216
+ };
217
+ function renderGhostImage(_ref2) {
218
+ let {
219
+ ctx
220
+ } = _ref2;
221
+ const alpha = ctx.globalAlpha;
222
+ ctx.globalAlpha *= 0.5;
223
+ ctx.drawImage(this._element, -this.width / 2 - this.cropX, -this.height / 2 - this.cropY);
224
+ ctx.globalAlpha = alpha;
225
+ }
226
+
227
+ export { changeCropHeight, changeCropWidth, changeCropX, changeCropY, changeImageCropX, changeImageCropY, changeImageHeight, changeImageWidth, cropPanMoveHandler, ghostScalePositionHandler, renderGhostImage, scaleEquallyCropGenerator };
228
+ //# sourceMappingURL=croppingHandlers.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"croppingHandlers.mjs","sources":["../../extensions/cropping_controls/croppingHandlers.ts"],"sourcesContent":["import type {\n TModificationEvents,\n Transform,\n TransformActionHandler,\n FabricImage,\n ObjectEvents,\n Control,\n TMat2D,\n} from 'fabric';\nimport { controlsUtils, Point, util } from 'fabric';\n\nconst { wrapWithFixedAnchor, wrapWithFireEvent } = controlsUtils;\n\n/**\n * Wrap controlsUtils.changeObjectWidth with image constrains\n */\nexport const changeImageWidth: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n const { target } = transform;\n const { width } = target;\n const image = target as FabricImage;\n const modified = controlsUtils.changeObjectWidth(eventData, transform, x, y);\n const availableWidth = image._element.width - image.cropX;\n if (modified) {\n if (image.width > availableWidth) {\n image.width = availableWidth;\n }\n if (image.width < 1) {\n image.width = 1;\n }\n }\n return width !== image.width;\n};\n\nexport const changeCropWidth = wrapWithFireEvent(\n 'CROPPING' as TModificationEvents,\n wrapWithFixedAnchor(changeImageWidth),\n);\n\n/**\n * Wrap controlsUtils.changeObjectHeight with image constrains\n */\nexport const changeImageHeight: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n const { target } = transform;\n const { height } = target;\n const image = target as FabricImage;\n const modified = controlsUtils.changeObjectHeight(eventData, transform, x, y);\n const availableHeight = image._element.height - image.cropY;\n if (modified) {\n if (image.height > availableHeight) {\n image.height = availableHeight;\n }\n if (image.height < 1) {\n image.height = 1;\n }\n }\n return height !== image.height;\n};\n\nexport const changeCropHeight = wrapWithFireEvent(\n 'CROPPING' as TModificationEvents,\n wrapWithFixedAnchor(changeImageHeight),\n);\n\nexport const changeImageCropX: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n const { target } = transform;\n const image = target as FabricImage;\n const { width, cropX } = image;\n const modified = controlsUtils.changeObjectWidth(eventData, transform, x, y);\n let newCropX = cropX + width - image.width;\n image.width = width;\n if (modified) {\n if (newCropX < 0) {\n newCropX = 0;\n }\n image.cropX = newCropX;\n // calculate new width on the base of how much crop we have now\n image.width += cropX - newCropX;\n }\n return newCropX !== cropX;\n};\n\nexport const changeImageCropY: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n const { target } = transform;\n const image = target as FabricImage;\n const { height, cropY } = image;\n const modified = controlsUtils.changeObjectHeight(eventData, transform, x, y);\n let newCropY = cropY + height - image.height;\n image.height = height;\n if (modified) {\n if (newCropY < 0) {\n newCropY = 0;\n }\n image.cropY = newCropY;\n image.height += cropY - newCropY;\n }\n return newCropY !== cropY;\n};\n\nexport const changeCropX = wrapWithFireEvent(\n 'CROPPING' as TModificationEvents,\n wrapWithFixedAnchor(changeImageCropX),\n);\n\nexport const changeCropY = wrapWithFireEvent(\n 'CROPPING' as TModificationEvents,\n wrapWithFixedAnchor(changeImageCropY),\n);\n\n/**\n * A function to counter the move action and change cropX/cropY of an image\n * Keep the image steady, but moves it inside its own cropping rectangle\n */\nexport const cropPanMoveHandler = ({ transform }: ObjectEvents['moving']) => {\n // this makes the image pan too fast.\n const { target, original } = transform as Transform;\n const fabricImage = target as FabricImage;\n const p = new Point(\n target.left - original.left,\n target.top - original.top,\n ).transform(\n util.invertTransform(\n util.createRotateMatrix({ angle: fabricImage.getTotalAngle() }),\n ),\n );\n let cropX = original.cropX! - p.x / fabricImage.scaleX;\n let cropY = original.cropY! - p.y / fabricImage.scaleY;\n const { width, height, _element } = fabricImage;\n if (cropX < 0) {\n cropX = 0;\n }\n if (cropY < 0) {\n cropY = 0;\n }\n if (cropX + width > _element.width) {\n cropX = _element.width - width;\n }\n if (cropY + height > _element.height) {\n cropY = _element.height - height;\n }\n fabricImage.cropX = cropX;\n fabricImage.cropY = cropY;\n fabricImage.left = original.left;\n fabricImage.top = original.top;\n};\n\n/**\n * This position handler works only for this specific use case.\n * It does not support padding nor offset, and it reduces all possible positions\n * to the main 4 corners only.\n * Any position that is < 0 is the extreme left/top, the rest are right/bottom\n */\nexport function ghostScalePositionHandler(\n this: Control,\n dim: Point, // currentDimension\n finalMatrix: TMat2D,\n fabricObject: FabricImage,\n // currentControl: Control,\n) {\n const matrix = fabricObject.calcTransformMatrix();\n const vpt = fabricObject.getViewportTransform();\n const _finalMatrix = util.multiplyTransformMatrices(vpt, matrix);\n\n let x = 0;\n let y = 0;\n if (this.x < 0) {\n x = -fabricObject.width / 2 - fabricObject.cropX;\n } else {\n x =\n fabricObject.getElement().width -\n fabricObject.width / 2 -\n fabricObject.cropX;\n }\n\n if (this.y < 0) {\n y = -fabricObject.height / 2 - fabricObject.cropY;\n } else {\n y =\n fabricObject.getElement().height -\n fabricObject.height / 2 -\n fabricObject.cropY;\n }\n return new Point(x, y).transform(_finalMatrix);\n}\n\nconst calcScale = (currentPoint: Point, height: number, width: number) =>\n Math.min(Math.abs(currentPoint.x / width), Math.abs(currentPoint.y / height));\n\n/**\n * Action handler generator that handles scaling of an image in crop mode.\n * The goal is to keep the current bounding box steady.\n * So this action handler has its own calculations for a dynamic anchor point\n */\nexport const scaleEquallyCropGenerator =\n (cx: number, cy: number): TransformActionHandler =>\n (eventData, transform, x, y) => {\n const { target } = transform as unknown as { target: FabricImage };\n const { width: fullWidth, height: fullHeight } = target.getElement();\n const remainderX = fullWidth - target.width - target.cropX;\n const remainderY = fullHeight - target.height - target.cropY;\n const anchorOriginX =\n cx < 0 ? 1 + remainderX / target.width : -target.cropX / target.width;\n const anchorOriginY =\n cy < 0 ? 1 + remainderY / target.height : -target.cropY / target.height;\n const constraint = target.translateToOriginPoint(\n target.getCenterPoint(),\n anchorOriginX,\n anchorOriginY,\n );\n const newPoint = controlsUtils.getLocalPoint(\n transform,\n anchorOriginX,\n anchorOriginY,\n x,\n y,\n );\n const scale = calcScale(newPoint, fullHeight, fullWidth);\n const scaleChangeX = scale / target.scaleX;\n const scaleChangeY = scale / target.scaleY;\n const scaledRemainderX = remainderX / scaleChangeX;\n const scaledRemainderY = remainderY / scaleChangeY;\n const newWidth = target.width / scaleChangeX;\n const newHeight = target.height / scaleChangeY;\n const newCropX =\n cx < 0\n ? fullWidth - newWidth - scaledRemainderX\n : target.cropX / scaleChangeX;\n const newCropY =\n cy < 0\n ? fullHeight - newHeight - scaledRemainderY\n : target.cropY / scaleChangeY;\n\n if (\n (cx < 0 ? scaledRemainderX : newCropX) + newWidth > fullWidth ||\n (cy < 0 ? scaledRemainderY : newCropY) + newHeight > fullHeight\n ) {\n return false;\n }\n\n target.scaleX = scale;\n target.scaleY = scale;\n target.width = newWidth;\n target.height = newHeight;\n target.cropX = newCropX;\n target.cropY = newCropY;\n const newAnchorOriginX =\n cx < 0 ? 1 + scaledRemainderX / newWidth : -newCropX / newWidth;\n const newAnchorOriginY =\n cy < 0 ? 1 + scaledRemainderY / newHeight : -newCropY / newHeight;\n target.setPositionByOrigin(constraint, newAnchorOriginX, newAnchorOriginY);\n return true;\n };\n\nexport function renderGhostImage(\n this: FabricImage,\n { ctx }: { ctx: CanvasRenderingContext2D },\n) {\n const alpha = ctx.globalAlpha;\n ctx.globalAlpha *= 0.5;\n ctx.drawImage(\n this._element,\n -this.width / 2 - this.cropX,\n -this.height / 2 - this.cropY,\n );\n ctx.globalAlpha = alpha;\n}\n"],"names":["wrapWithFixedAnchor","wrapWithFireEvent","controlsUtils","changeImageWidth","eventData","transform","x","y","target","width","image","modified","changeObjectWidth","availableWidth","_element","cropX","changeCropWidth","changeImageHeight","height","changeObjectHeight","availableHeight","cropY","changeCropHeight","changeImageCropX","newCropX","changeImageCropY","newCropY","changeCropX","changeCropY","cropPanMoveHandler","_ref","original","fabricImage","p","Point","left","top","util","invertTransform","createRotateMatrix","angle","getTotalAngle","scaleX","scaleY","ghostScalePositionHandler","dim","finalMatrix","fabricObject","matrix","calcTransformMatrix","vpt","getViewportTransform","_finalMatrix","multiplyTransformMatrices","getElement","calcScale","currentPoint","Math","min","abs","scaleEquallyCropGenerator","cx","cy","fullWidth","fullHeight","remainderX","remainderY","anchorOriginX","anchorOriginY","constraint","translateToOriginPoint","getCenterPoint","newPoint","getLocalPoint","scale","scaleChangeX","scaleChangeY","scaledRemainderX","scaledRemainderY","newWidth","newHeight","newAnchorOriginX","newAnchorOriginY","setPositionByOrigin","renderGhostImage","_ref2","ctx","alpha","globalAlpha","drawImage"],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { createImageCroppingControls } from './croppingControls.mjs';
2
+ import { cropPanMoveHandler, renderGhostImage } from './croppingHandlers.mjs';
3
+
4
+ /**
5
+ * Coordinates the change to image to enter crop mode and returns
6
+ * a function to exit crop mode
7
+ */
8
+ const enterCropMode = function enterCropMode(_ref) {
9
+ var _fabricImage$canvas2;
10
+ let {
11
+ target
12
+ } = _ref;
13
+ const fabricImage = target;
14
+ const {
15
+ controls,
16
+ padding
17
+ } = fabricImage;
18
+ fabricImage.padding = 0;
19
+ fabricImage.controls = createImageCroppingControls();
20
+ fabricImage.on('moving', cropPanMoveHandler);
21
+ fabricImage.on('before:render', renderGhostImage);
22
+ fabricImage.setCoords();
23
+ const exitCropMode = () => {
24
+ var _fabricImage$canvas;
25
+ fabricImage.padding = padding;
26
+ fabricImage.off('moving', cropPanMoveHandler);
27
+ fabricImage.off('before:render', renderGhostImage);
28
+ fabricImage.controls = controls;
29
+ fabricImage.setCoords();
30
+ fabricImage.once('mousedblclick', enterCropMode);
31
+ (_fabricImage$canvas = fabricImage.canvas) === null || _fabricImage$canvas === void 0 || _fabricImage$canvas.requestRenderAll();
32
+ };
33
+ fabricImage.once('mousedblclick', exitCropMode);
34
+ (_fabricImage$canvas2 = fabricImage.canvas) === null || _fabricImage$canvas2 === void 0 || _fabricImage$canvas2.requestRenderAll();
35
+ };
36
+
37
+ export { enterCropMode };
38
+ //# sourceMappingURL=enterCropMode.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enterCropMode.mjs","sources":["../../extensions/cropping_controls/enterCropMode.ts"],"sourcesContent":["import { type FabricImage, type TPointerEventInfo } from 'fabric';\nimport { createImageCroppingControls } from './croppingControls';\nimport { cropPanMoveHandler, renderGhostImage } from './croppingHandlers';\n/**\n * Coordinates the change to image to enter crop mode and returns\n * a function to exit crop mode\n */\nexport const enterCropMode = function enterCropMode(\n this: (args: TPointerEventInfo) => void,\n { target }: TPointerEventInfo,\n) {\n const fabricImage = target as FabricImage;\n const { controls, padding } = fabricImage;\n fabricImage.padding = 0;\n fabricImage.controls = createImageCroppingControls();\n fabricImage.on('moving', cropPanMoveHandler);\n fabricImage.on('before:render', renderGhostImage);\n fabricImage.setCoords();\n const exitCropMode = () => {\n fabricImage.padding = padding;\n fabricImage.off('moving', cropPanMoveHandler);\n fabricImage.off('before:render', renderGhostImage);\n fabricImage.controls = controls;\n fabricImage.setCoords();\n fabricImage.once('mousedblclick', enterCropMode);\n fabricImage.canvas?.requestRenderAll();\n };\n fabricImage.once('mousedblclick', exitCropMode);\n fabricImage.canvas?.requestRenderAll();\n};\n"],"names":["enterCropMode","_ref","_fabricImage$canvas2","target","fabricImage","controls","padding","createImageCroppingControls","on","cropPanMoveHandler","renderGhostImage","setCoords","exitCropMode","_fabricImage$canvas","off","once","canvas","requestRenderAll"],"mappings":";;;AAGA;AACA;AACA;AACA;MACaA,aAAa,GAAG,SAASA,aAAaA,CAAAC,IAAA,EAGjD;AAAA,EAAA,IAAAC,oBAAA;EAAA,IADA;AAAEC,IAAAA;AAA0B,GAAC,GAAAF,IAAA;EAE7B,MAAMG,WAAW,GAAGD,MAAqB;EACzC,MAAM;IAAEE,QAAQ;AAAEC,IAAAA;AAAQ,GAAC,GAAGF,WAAW;EACzCA,WAAW,CAACE,OAAO,GAAG,CAAC;AACvBF,EAAAA,WAAW,CAACC,QAAQ,GAAGE,2BAA2B,EAAE;AACpDH,EAAAA,WAAW,CAACI,EAAE,CAAC,QAAQ,EAAEC,kBAAkB,CAAC;AAC5CL,EAAAA,WAAW,CAACI,EAAE,CAAC,eAAe,EAAEE,gBAAgB,CAAC;EACjDN,WAAW,CAACO,SAAS,EAAE;EACvB,MAAMC,YAAY,GAAGA,MAAM;AAAA,IAAA,IAAAC,mBAAA;IACzBT,WAAW,CAACE,OAAO,GAAGA,OAAO;AAC7BF,IAAAA,WAAW,CAACU,GAAG,CAAC,QAAQ,EAAEL,kBAAkB,CAAC;AAC7CL,IAAAA,WAAW,CAACU,GAAG,CAAC,eAAe,EAAEJ,gBAAgB,CAAC;IAClDN,WAAW,CAACC,QAAQ,GAAGA,QAAQ;IAC/BD,WAAW,CAACO,SAAS,EAAE;AACvBP,IAAAA,WAAW,CAACW,IAAI,CAAC,eAAe,EAAEf,aAAa,CAAC;AAChD,IAAA,CAAAa,mBAAA,GAAAT,WAAW,CAACY,MAAM,MAAA,IAAA,IAAAH,mBAAA,KAAA,MAAA,IAAlBA,mBAAA,CAAoBI,gBAAgB,EAAE;EACxC,CAAC;AACDb,EAAAA,WAAW,CAACW,IAAI,CAAC,eAAe,EAAEH,YAAY,CAAC;AAC/C,EAAA,CAAAV,oBAAA,GAAAE,WAAW,CAACY,MAAM,MAAA,IAAA,IAAAd,oBAAA,KAAA,MAAA,IAAlBA,oBAAA,CAAoBe,gBAAgB,EAAE;AACxC;;;;"}
@@ -0,0 +1,45 @@
1
+ import { util } from 'fabric';
2
+
3
+ const {
4
+ degreesToRadians
5
+ } = util;
6
+
7
+ /**
8
+ * Render a control for the main corners of a cropping image
9
+ * This function is written to respect object properties like transparentCorners, cornerSize
10
+ * cornerColor, cornerStrokeColor
11
+ * plus the addition of offsetY and offsetX.
12
+ * @param {CanvasRenderingContext2D} ctx context to render on
13
+ * @param {Number} left x coordinate where the control center should be
14
+ * @param {Number} top y coordinate where the control center should be
15
+ * @param {Object} styleOverride override for FabricObject controls style
16
+ * @param {FabricObject} fabricObject the fabric object for which we are rendering controls
17
+ */
18
+ function renderCornerControl(ctx, left, top, styleOverride, fabricObject) {
19
+ ctx.save();
20
+ const {
21
+ stroke,
22
+ xSize,
23
+ ySize,
24
+ opName
25
+ } = this.commonRenderProps(ctx, left, top, fabricObject, styleOverride),
26
+ xSizeBy2 = xSize / 2,
27
+ ySizeBy2 = ySize / 2;
28
+ // angle is relative to canvas plane
29
+ ctx.rotate(degreesToRadians(this.angle));
30
+ ctx.beginPath();
31
+ ctx.moveTo(-ySizeBy2, 0);
32
+ ctx.lineTo(-ySizeBy2, xSizeBy2);
33
+ ctx.lineTo(ySizeBy2, xSizeBy2);
34
+ ctx.lineTo(ySizeBy2, ySizeBy2);
35
+ ctx.lineTo(xSizeBy2, ySizeBy2);
36
+ ctx.lineTo(xSizeBy2, -ySizeBy2);
37
+ ctx.lineTo(-ySizeBy2, -ySizeBy2);
38
+ ctx.closePath();
39
+ ctx[opName]();
40
+ stroke && ctx.stroke();
41
+ ctx.restore();
42
+ }
43
+
44
+ export { renderCornerControl };
45
+ //# sourceMappingURL=renderCornerControl.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderCornerControl.mjs","sources":["../../extensions/cropping_controls/renderCornerControl.ts"],"sourcesContent":["import {\n type ControlRenderingStyleOverride,\n type InteractiveFabricObject,\n util,\n type Control,\n} from 'fabric';\n\nconst { degreesToRadians } = util;\n\n/**\n * Render a control for the main corners of a cropping image\n * This function is written to respect object properties like transparentCorners, cornerSize\n * cornerColor, cornerStrokeColor\n * plus the addition of offsetY and offsetX.\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Number} left x coordinate where the control center should be\n * @param {Number} top y coordinate where the control center should be\n * @param {Object} styleOverride override for FabricObject controls style\n * @param {FabricObject} fabricObject the fabric object for which we are rendering controls\n */\nexport function renderCornerControl(\n this: Control,\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride,\n fabricObject: InteractiveFabricObject,\n) {\n ctx.save();\n const { stroke, xSize, ySize, opName } = this.commonRenderProps(\n ctx,\n left,\n top,\n fabricObject,\n styleOverride,\n ),\n xSizeBy2 = xSize / 2,\n ySizeBy2 = ySize / 2;\n // angle is relative to canvas plane\n ctx.rotate(degreesToRadians(this.angle));\n ctx.beginPath();\n ctx.moveTo(-ySizeBy2, 0);\n ctx.lineTo(-ySizeBy2, xSizeBy2);\n ctx.lineTo(ySizeBy2, xSizeBy2);\n ctx.lineTo(ySizeBy2, ySizeBy2);\n ctx.lineTo(xSizeBy2, ySizeBy2);\n ctx.lineTo(xSizeBy2, -ySizeBy2);\n ctx.lineTo(-ySizeBy2, -ySizeBy2);\n ctx.closePath();\n ctx[opName]();\n stroke && ctx.stroke();\n ctx.restore();\n}\n"],"names":["degreesToRadians","util","renderCornerControl","ctx","left","top","styleOverride","fabricObject","save","stroke","xSize","ySize","opName","commonRenderProps","xSizeBy2","ySizeBy2","rotate","angle","beginPath","moveTo","lineTo","closePath","restore"],"mappings":";;AAOA,MAAM;AAAEA,EAAAA;AAAiB,CAAC,GAAGC,IAAI;;AAEjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,mBAAmBA,CAEjCC,GAA6B,EAC7BC,IAAY,EACZC,GAAW,EACXC,aAA4C,EAC5CC,YAAqC,EACrC;EACAJ,GAAG,CAACK,IAAI,EAAE;EACV,MAAM;MAAEC,MAAM;MAAEC,KAAK;MAAEC,KAAK;AAAEC,MAAAA;AAAO,KAAC,GAAG,IAAI,CAACC,iBAAiB,CAC3DV,GAAG,EACHC,IAAI,EACJC,GAAG,EACHE,YAAY,EACZD,aACF,CAAC;IACDQ,QAAQ,GAAGJ,KAAK,GAAG,CAAC;IACpBK,QAAQ,GAAGJ,KAAK,GAAG,CAAC;AACtB;EACAR,GAAG,CAACa,MAAM,CAAChB,gBAAgB,CAAC,IAAI,CAACiB,KAAK,CAAC,CAAC;EACxCd,GAAG,CAACe,SAAS,EAAE;AACff,EAAAA,GAAG,CAACgB,MAAM,CAAC,CAACJ,QAAQ,EAAE,CAAC,CAAC;AACxBZ,EAAAA,GAAG,CAACiB,MAAM,CAAC,CAACL,QAAQ,EAAED,QAAQ,CAAC;AAC/BX,EAAAA,GAAG,CAACiB,MAAM,CAACL,QAAQ,EAAED,QAAQ,CAAC;AAC9BX,EAAAA,GAAG,CAACiB,MAAM,CAACL,QAAQ,EAAEA,QAAQ,CAAC;AAC9BZ,EAAAA,GAAG,CAACiB,MAAM,CAACN,QAAQ,EAAEC,QAAQ,CAAC;AAC9BZ,EAAAA,GAAG,CAACiB,MAAM,CAACN,QAAQ,EAAE,CAACC,QAAQ,CAAC;EAC/BZ,GAAG,CAACiB,MAAM,CAAC,CAACL,QAAQ,EAAE,CAACA,QAAQ,CAAC;EAChCZ,GAAG,CAACkB,SAAS,EAAE;AACflB,EAAAA,GAAG,CAACS,MAAM,CAAC,EAAE;AACbH,EAAAA,MAAM,IAAIN,GAAG,CAACM,MAAM,EAAE;EACtBN,GAAG,CAACmB,OAAO,EAAE;AACf;;;;"}
@@ -0,0 +1,16 @@
1
+ import { Control } from 'fabric';
2
+ export declare const createImageCroppingControls: () => {
3
+ tls: Control;
4
+ brs: Control;
5
+ trs: Control;
6
+ bls: Control;
7
+ mlc: Control;
8
+ mrc: Control;
9
+ mbc: Control;
10
+ mtc: Control;
11
+ tlc: Control;
12
+ trc: Control;
13
+ blc: Control;
14
+ brc: Control;
15
+ };
16
+ //# sourceMappingURL=croppingControls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"croppingControls.d.ts","sourceRoot":"","sources":["../../../extensions/cropping_controls/croppingControls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAiB,MAAM,QAAQ,CAAC;AAehD,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;CAsItC,CAAC"}
@@ -0,0 +1,39 @@
1
+ import type { Transform, TransformActionHandler, FabricImage, ObjectEvents, Control, TMat2D } from 'fabric';
2
+ import { Point } from 'fabric';
3
+ /**
4
+ * Wrap controlsUtils.changeObjectWidth with image constrains
5
+ */
6
+ export declare const changeImageWidth: TransformActionHandler;
7
+ export declare const changeCropWidth: TransformActionHandler<Transform>;
8
+ /**
9
+ * Wrap controlsUtils.changeObjectHeight with image constrains
10
+ */
11
+ export declare const changeImageHeight: TransformActionHandler;
12
+ export declare const changeCropHeight: TransformActionHandler<Transform>;
13
+ export declare const changeImageCropX: TransformActionHandler;
14
+ export declare const changeImageCropY: TransformActionHandler;
15
+ export declare const changeCropX: TransformActionHandler<Transform>;
16
+ export declare const changeCropY: TransformActionHandler<Transform>;
17
+ /**
18
+ * A function to counter the move action and change cropX/cropY of an image
19
+ * Keep the image steady, but moves it inside its own cropping rectangle
20
+ */
21
+ export declare const cropPanMoveHandler: ({ transform }: ObjectEvents["moving"]) => void;
22
+ /**
23
+ * This position handler works only for this specific use case.
24
+ * It does not support padding nor offset, and it reduces all possible positions
25
+ * to the main 4 corners only.
26
+ * Any position that is < 0 is the extreme left/top, the rest are right/bottom
27
+ */
28
+ export declare function ghostScalePositionHandler(this: Control, dim: Point, // currentDimension
29
+ finalMatrix: TMat2D, fabricObject: FabricImage): Point;
30
+ /**
31
+ * Action handler generator that handles scaling of an image in crop mode.
32
+ * The goal is to keep the current bounding box steady.
33
+ * So this action handler has its own calculations for a dynamic anchor point
34
+ */
35
+ export declare const scaleEquallyCropGenerator: (cx: number, cy: number) => TransformActionHandler;
36
+ export declare function renderGhostImage(this: FabricImage, { ctx }: {
37
+ ctx: CanvasRenderingContext2D;
38
+ }): void;
39
+ //# sourceMappingURL=croppingHandlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"croppingHandlers.d.ts","sourceRoot":"","sources":["../../../extensions/cropping_controls/croppingHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,SAAS,EACT,sBAAsB,EACtB,WAAW,EACX,YAAY,EACZ,OAAO,EACP,MAAM,EACP,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAiB,KAAK,EAAQ,MAAM,QAAQ,CAAC;AAIpD;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,sBAoB9B,CAAC;AAEF,eAAO,MAAM,eAAe,mCAG3B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,sBAoB/B,CAAC;AAEF,eAAO,MAAM,gBAAgB,mCAG5B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,sBAqB9B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,sBAoB9B,CAAC;AAEF,eAAO,MAAM,WAAW,mCAGvB,CAAC;AAEF,eAAO,MAAM,WAAW,mCAGvB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,eAAe,YAAY,CAAC,QAAQ,CAAC,SA+BvE,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,KAAK,EAAE,mBAAmB;AAC/B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,WAAW,SA2B1B;AAKD;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GACnC,IAAI,MAAM,EAAE,IAAI,MAAM,KAAG,sBAyDzB,CAAC;AAEJ,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,WAAW,EACjB,EAAE,GAAG,EAAE,EAAE;IAAE,GAAG,EAAE,wBAAwB,CAAA;CAAE,QAU3C"}
@@ -0,0 +1,7 @@
1
+ import { type TPointerEventInfo } from 'fabric';
2
+ /**
3
+ * Coordinates the change to image to enter crop mode and returns
4
+ * a function to exit crop mode
5
+ */
6
+ export declare const enterCropMode: (this: (args: TPointerEventInfo) => void, { target }: TPointerEventInfo) => void;
7
+ //# sourceMappingURL=enterCropMode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enterCropMode.d.ts","sourceRoot":"","sources":["../../../extensions/cropping_controls/enterCropMode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAGlE;;;GAGG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,EACvC,YAAY,iBAAiB,SAoB9B,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { type ControlRenderingStyleOverride, type InteractiveFabricObject, type Control } from 'fabric';
2
+ /**
3
+ * Render a control for the main corners of a cropping image
4
+ * This function is written to respect object properties like transparentCorners, cornerSize
5
+ * cornerColor, cornerStrokeColor
6
+ * plus the addition of offsetY and offsetX.
7
+ * @param {CanvasRenderingContext2D} ctx context to render on
8
+ * @param {Number} left x coordinate where the control center should be
9
+ * @param {Number} top y coordinate where the control center should be
10
+ * @param {Object} styleOverride override for FabricObject controls style
11
+ * @param {FabricObject} fabricObject the fabric object for which we are rendering controls
12
+ */
13
+ export declare function renderCornerControl(this: Control, ctx: CanvasRenderingContext2D, left: number, top: number, styleOverride: ControlRenderingStyleOverride, fabricObject: InteractiveFabricObject): void;
14
+ //# sourceMappingURL=renderCornerControl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderCornerControl.d.ts","sourceRoot":"","sources":["../../../extensions/cropping_controls/renderCornerControl.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,6BAA6B,EAClC,KAAK,uBAAuB,EAE5B,KAAK,OAAO,EACb,MAAM,QAAQ,CAAC;AAIhB;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,wBAAwB,EAC7B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,6BAA6B,EAC5C,YAAY,EAAE,uBAAuB,QA0BtC"}
@@ -3,4 +3,7 @@ export type * from './aligning_guidelines/typedefs';
3
3
  export { originUpdaterWrapper, installOriginWrapperUpdater, } from './data_updaters/origins';
4
4
  export { gradientUpdaterWrapper, installGradientUpdater, } from './data_updaters/gradient';
5
5
  export { addGestures, pinchEventHandler, rotateEventHandler, } from './westures_integration';
6
+ export { createImageCroppingControls } from './cropping_controls/croppingControls';
7
+ export { changeCropY, changeCropX, changeCropWidth, changeCropHeight, } from './cropping_controls/croppingHandlers';
8
+ export { enterCropMode } from './cropping_controls/enterCropMode';
6
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../extensions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,mBAAmB,gCAAgC,CAAC;AAEpD,OAAO,EACL,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../extensions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,mBAAmB,gCAAgC,CAAC;AAEpD,OAAO,EACL,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EACL,WAAW,EACX,WAAW,EACX,eAAe,EACf,gBAAgB,GACjB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC"}
@@ -1,2 +1,2 @@
1
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("fabric"),require("westures")):"function"==typeof define&&define.amd?define(["exports","fabric","westures"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).fabricExtensions={},t.fabric,t.westures)}(this,function(t,e,i){"use strict";function n(t,e,i){return(e=function(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var i=t[Symbol.toPrimitive];if(void 0!==i){var n=i.call(t,e);if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:e+""}(e))in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}function r(t,e){return Math.abs(t-e)}function s(t,e,i){let n=1/0,s=[];for(const o of e){const e=r(t[i],o[i]);n>e&&(s=[],n=e),n==e&&s.push(o)}return{dis:n,arr:s}}function o(t){const{target:e,isScale:i,isUniform:n,corner:r,point:o,diagonalPoint:a,list:c,isCenter:l}=t,{dis:h,arr:f}=s(o,c,"x");if(h>this.margin/this.canvas.getZoom())return[];let d=f[f.length-1].x-o.x;d*=r.includes("l")?-1:1;const{width:g,height:u,scaleX:v,scaleY:p}=e,m=v*g+(e.strokeUniform?0:e.strokeWidth),b=(d+m)/m;if(0==b)return[];if(i?(e.set("scaleX",v*b),n&&e.set("scaleY",p*b)):(e.set("width",g*b),n&&e.set("height",u*b)),l)e.setRelativeXY(a,"center","center");else{const t=this.contraryOriginMap;e.setRelativeXY(a,...t[r])}return e.setCoords(),f.map(t=>({origin:o,target:t}))}function a(t){const{target:e,isScale:i,isUniform:n,corner:r,point:o,diagonalPoint:a,list:c,isCenter:l}=t,{dis:h,arr:f}=s(o,c,"y");if(h>this.margin/this.canvas.getZoom())return[];let d=f[f.length-1].y-o.y;d*=r.includes("t")?-1:1;const{width:g,height:u,scaleX:v,scaleY:p}=e,m=p*u+(e.strokeUniform?0:e.strokeWidth),b=(d+m)/m;if(0==b)return[];if(i?(e.set("scaleY",p*b),n&&e.set("scaleX",v*b)):(e.set("height",u*b),n&&e.set("width",g*b)),l)e.setRelativeXY(a,"center","center");else{const t=this.contraryOriginMap;e.setRelativeXY(a,...t[r])}return e.setCoords(),f.map(t=>({origin:o,target:t}))}function c(t,e){const i=this.canvas.getTopContext(),n=this.canvas.viewportTransform,r=this.canvas.getZoom();i.save(),i.transform(...n),i.lineWidth=this.width/r,this.lineDash&&i.setLineDash(this.lineDash),i.strokeStyle=this.color,i.beginPath(),i.moveTo(t.x,t.y),i.lineTo(e.x,e.y),i.stroke(),this.lineDash&&i.setLineDash([]),this.drawX(t,-1),this.drawX(e,1),i.restore()}function l(t,e){const i=this.canvas.getTopContext(),n=this.canvas.getZoom(),r=this.xSize/n;i.save(),i.translate(t.x,t.y),i.beginPath(),i.moveTo(-r,-r),i.lineTo(r,r),i.moveTo(r,-r),i.lineTo(-r,r),i.stroke(),i.restore()}function h(t){const e=this.canvas.getTopContext(),i=this.canvas.viewportTransform,n=this.canvas.getZoom();e.save(),e.transform(...i),e.lineWidth=this.width/n,e.strokeStyle=this.color;for(const e of t)this.drawX(e,0);e.restore()}function f(){const t=[];if(!this.closeVLine)for(const e of this.verticalLines)t.push(JSON.parse(e));if(!this.closeHLine)for(const e of this.horizontalLines)t.push(JSON.parse(e));const e=t.map(t=>t.target);h.call(this,e)}function d(){if(!this.closeVLine)for(const t of this.verticalLines){const{origin:i,target:n}=JSON.parse(t),r=new e.Point(n.x,i.y);this.drawLine(r,n)}}function g(){if(!this.closeHLine)for(const t of this.horizontalLines){const{origin:i,target:n}=JSON.parse(t),r=new e.Point(i.x,n.y);this.drawLine(r,n)}}function u(t,e){const i=t.getCoords();i.push(t.getCenterPoint());const n={target:t,list:i,points:e,margin:this.margin/this.canvas.getZoom()};return{vLines:p({...n,type:"x"}),hLines:p({...n,type:"y"})}}const v=[["left","top"],["right","top"],["right","bottom"],["left","bottom"],["center","center"]];function p(t){const{target:e,list:i,points:n,margin:r,type:o}=t,a=[],c=[];let l=1/0;for(const t of i){const e=s(t,n,o);c.push(e),l>e.dis&&(l=e.dis)}if(l>r)return a;let h=!1;for(let t=0;t<i.length;t++){if(c[t].dis!=l)continue;for(const e of c[t].arr)a.push({origin:i[t],target:e});if(h)continue;h=!0;const n=c[t].arr[0][o]-i[t][o];i.forEach(t=>{t[o]+=n}),e.setXY(i[t],...v[t]),e.setCoords()}return a}function m(t){const i=new Set,n=t.canvas;if(!n)return i;const r=t instanceof e.ActiveSelection?t.getObjects():[t];return n.forEachObject(t=>{t.isOnScreen()&&t.visible&&(t.constructor!=e.Group?i.add(t):y(i,t))}),b(i,r),i}function b(t,i){for(const n of i)n.constructor==e.Group?b(t,n.getObjects()):t.delete(n)}function y(t,i){const n=i.getObjects();for(const i of n)i.visible&&(i.constructor!=e.Group?t.add(i):y(t,i))}const w=function(t){let i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"left",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"top";return async function(r){const{originX:s=i,originY:o=n}=r;delete r.originX,delete r.originY;for(var a=arguments.length,c=new Array(a>1?a-1:0),l=1;l<a;l++)c[l-1]=arguments[l];const h=await t.call(this,r,...c),f=new e.Point(h.left,h.top);return h.setPositionByOrigin(f,s,o),h}},O=t=>async function(i){const{colorStops:n}=i,r=null==n?void 0:n.map(t=>{let{color:i,opacity:n,offset:r}=t;if(void 0===n||1===n)return{color:i,offset:r};return{color:new e.Color(i).setAlpha(n).toRgba(),offset:r}});return await t.call(this,{...i,colorStops:r})};t.AligningGuidelines=class{constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};n(this,"canvas",void 0),n(this,"horizontalLines",new Set),n(this,"verticalLines",new Set),n(this,"cacheMap",new Map),n(this,"onlyDrawPoint",!1),n(this,"contraryOriginMap",{tl:["right","bottom"],tr:["left","bottom"],br:["left","top"],bl:["right","top"],mt:["center","bottom"],mr:["left","center"],mb:["center","top"],ml:["right","center"]}),n(this,"xSize",2.4),n(this,"lineDash",void 0),n(this,"margin",4),n(this,"width",1),n(this,"color","rgba(255,0,0,0.9)"),n(this,"closeVLine",!1),n(this,"closeHLine",!1),this.canvas=t,Object.assign(this,e),this.mouseUp=this.mouseUp.bind(this),this.scalingOrResizing=this.scalingOrResizing.bind(this),this.moving=this.moving.bind(this),this.beforeRender=this.beforeRender.bind(this),this.afterRender=this.afterRender.bind(this),this.initBehavior()}initBehavior(){this.canvas.on("mouse:up",this.mouseUp),this.canvas.on("object:resizing",this.scalingOrResizing),this.canvas.on("object:scaling",this.scalingOrResizing),this.canvas.on("object:moving",this.moving),this.canvas.on("before:render",this.beforeRender),this.canvas.on("after:render",this.afterRender)}getObjectsByTarget(t){return m(t)}getPointMap(t){return function(t){const e=t.getCoords();return{tl:e[0],tr:e[1],br:e[2],bl:e[3],mt:e[0].add(e[1]).scalarDivide(2),mr:e[1].add(e[2]).scalarDivide(2),mb:e[2].add(e[3]).scalarDivide(2),ml:e[3].add(e[0]).scalarDivide(2)}}(t)}getContraryMap(t){return function(t){var e;const i=null!==(e=t.aCoords)&&void 0!==e?e:t.calcACoords();return{tl:i.br,tr:i.bl,br:i.tl,bl:i.tr,mt:i.br.add(i.bl).scalarDivide(2),mr:i.bl.add(i.tl).scalarDivide(2),mb:i.tl.add(i.tr).scalarDivide(2),ml:i.tr.add(i.br).scalarDivide(2)}}(t)}getCaCheMapValue(t){const e=[t.calcTransformMatrix().toString(),t.width,t.height].join(),i=this.cacheMap.get(e);if(i)return i;const n=t.getCoords();return n.push(t.getCenterPoint()),this.cacheMap.set(e,n),n}drawLine(t,e){c.call(this,t,e)}drawX(t,e){l.call(this,t,e)}mouseUp(){this.verticalLines.clear(),this.horizontalLines.clear(),this.cacheMap.clear(),this.canvas.requestRenderAll()}scalingOrResizing(t){const i=t.target;i.setCoords();const n=String(t.transform.action).startsWith("scale");this.verticalLines.clear(),this.horizontalLines.clear();const r=this.getObjectsByTarget(i);let s=t.transform.corner;i.flipX&&(s.includes("l")?s=s.replace("l","r"):s.includes("r")&&(s=s.replace("r","l"))),i.flipY&&(s.includes("t")?s=s.replace("t","b"):s.includes("b")&&(s=s.replace("b","t")));const c=this.getPointMap(i);if(!(s in c))return;if(this.onlyDrawPoint=s.includes("m"),this.onlyDrawPoint){if(i.getTotalAngle()%90!=0)return}const l=this.getContraryMap(i),h=c[s];let f=l[s];const d="center"==t.transform.original.originX&&"center"==t.transform.original.originY;if(d){const t=i.group?h.transform(e.util.invertTransform(i.group.calcTransformMatrix())):h;f=f.add(t).scalarDivide(2)}const g=t.e[this.canvas.uniScaleKey];let u=this.canvas.uniformScaling&&!g||!this.canvas.uniformScaling&&g;this.onlyDrawPoint&&(u=!1);const v=[];for(const t of r){const e=this.getCaCheMapValue(t);v.push(...e)}const p={target:i,point:h,diagonalPoint:f,corner:s,list:v,isScale:n,isUniform:u,isCenter:d},m=this.onlyDrawPoint&&(s.includes("t")||s.includes("b")),b=this.onlyDrawPoint&&(s.includes("l")||s.includes("r")),y=m?[]:o.call(this,p),w=b?[]:a.call(this,p);y.forEach(t=>{this.verticalLines.add(JSON.stringify(t))}),w.forEach(t=>{this.horizontalLines.add(JSON.stringify(t))})}moving(t){const e=t.target;e.setCoords(),this.onlyDrawPoint=!1,this.verticalLines.clear(),this.horizontalLines.clear();const i=this.getObjectsByTarget(e),n=[];for(const t of i)n.push(...this.getCaCheMapValue(t));const{vLines:r,hLines:s}=u.call(this,e,n);r.forEach(t=>{this.verticalLines.add(JSON.stringify(t))}),s.forEach(t=>{this.horizontalLines.add(JSON.stringify(t))})}beforeRender(){this.canvas.clearContext(this.canvas.contextTop)}afterRender(){this.onlyDrawPoint?f.call(this):(d.call(this),g.call(this))}dispose(){this.canvas.off("mouse:up",this.mouseUp),this.canvas.off("object:resizing",this.scalingOrResizing),this.canvas.off("object:scaling",this.scalingOrResizing),this.canvas.off("object:moving",this.moving),this.canvas.off("before:render",this.beforeRender),this.canvas.off("after:render",this.afterRender)}},t.addGestures=t=>{const e=new i.Region(t.upperCanvasEl);t.addOrRemove(function(t){for(var e=arguments.length,i=new Array(e>1?e-1:0),n=1;n<e;n++)i[n-1]=arguments[n];return t.removeEventListener(...i)}),e.addGesture((t=>new i.Rotate(t.upperCanvasEl,e=>{let{rotation:i,event:n}=e;t.fireEventFromPointerEvent(n,"rotate","rotate",{rotation:i})}))(t)),e.addGesture((t=>new i.Pinch(t.upperCanvasEl,e=>{let{scale:i,event:n}=e;t.fireEventFromPointerEvent(n,"pinch","pinch",{scale:i})}))(t)),e.addGesture((t=>new i.Tap(t.upperCanvasEl,e=>{let{event:i}=e;t.fireEventFromPointerEvent(i,"mouse:tripleclick","mousetripleclick",void 0),i.preventDefault()},{numTaps:3,maxRetain:400}))(t)),e.addGesture((t=>new i.Tap(t.upperCanvasEl,e=>{let{event:i}=e;t.fireEventFromPointerEvent(i,"mouse:dblclick","mousedblclick",void 0),i.preventDefault()},{numTaps:2,maxRetain:300}))(t)),t.addOrRemove(function(t){for(var e=arguments.length,i=new Array(e>1?e-1:0),n=1;n<e;n++)i[n-1]=arguments[n];return t.addEventListener(...i)},!0)},t.gradientUpdaterWrapper=O,t.installGradientUpdater=()=>{e.Gradient.fromObject=O(e.Gradient.fromObject)},t.installOriginWrapperUpdater=(t,i)=>{e.BaseFabricObject._fromObject=w(e.BaseFabricObject._fromObject,t,i),e.FabricImage.fromObject=w(e.FabricImage.fromObject,t,i),e.Group.fromObject=w(e.Group.fromObject,t,i)},t.originUpdaterWrapper=w,t.pinchEventHandler=function(t){let{scale:e,target:i,scenePoint:n}=t;i&&this.getActiveObject()===i?(i.scaleX*=e,i.scaleY*=e):this.zoomToPoint(n,this.getZoom()*e)},t.rotateEventHandler=function(t){let{rotation:i,target:n}=t;n&&this.getActiveObject()===n&&n.rotate(n.angle+e.util.radiansToDegrees(i))}});
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("fabric"),require("westures")):"function"==typeof define&&define.amd?define(["exports","fabric","westures"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).fabricExtensions={},t.fabric,t.westures)}(this,function(t,e,n){"use strict";function i(t,e,n){return(e=function(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var i=n.call(t,e);if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:e+""}(e))in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function r(t,e){return Math.abs(t-e)}function o(t,e,n){let i=1/0,o=[];for(const s of e){const e=r(t[n],s[n]);i>e&&(o=[],i=e),i==e&&o.push(s)}return{dis:i,arr:o}}function s(t){const{target:e,isScale:n,isUniform:i,corner:r,point:s,diagonalPoint:a,list:c,isCenter:l}=t,{dis:h,arr:d}=o(s,c,"x");if(h>this.margin/this.canvas.getZoom())return[];let g=d[d.length-1].x-s.x;g*=r.includes("l")?-1:1;const{width:f,height:u,scaleX:p,scaleY:m}=e,v=p*f+(e.strokeUniform?0:e.strokeWidth),b=(g+v)/v;if(0==b)return[];if(n?(e.set("scaleX",p*b),i&&e.set("scaleY",m*b)):(e.set("width",f*b),i&&e.set("height",u*b)),l)e.setRelativeXY(a,"center","center");else{const t=this.contraryOriginMap;e.setRelativeXY(a,...t[r])}return e.setCoords(),d.map(t=>({origin:s,target:t}))}function a(t){const{target:e,isScale:n,isUniform:i,corner:r,point:s,diagonalPoint:a,list:c,isCenter:l}=t,{dis:h,arr:d}=o(s,c,"y");if(h>this.margin/this.canvas.getZoom())return[];let g=d[d.length-1].y-s.y;g*=r.includes("t")?-1:1;const{width:f,height:u,scaleX:p,scaleY:m}=e,v=m*u+(e.strokeUniform?0:e.strokeWidth),b=(g+v)/v;if(0==b)return[];if(n?(e.set("scaleY",m*b),i&&e.set("scaleX",p*b)):(e.set("height",u*b),i&&e.set("width",f*b)),l)e.setRelativeXY(a,"center","center");else{const t=this.contraryOriginMap;e.setRelativeXY(a,...t[r])}return e.setCoords(),d.map(t=>({origin:s,target:t}))}function c(t,e){const n=this.canvas.getTopContext(),i=this.canvas.viewportTransform,r=this.canvas.getZoom();n.save(),n.transform(...i),n.lineWidth=this.width/r,this.lineDash&&n.setLineDash(this.lineDash),n.strokeStyle=this.color,n.beginPath(),n.moveTo(t.x,t.y),n.lineTo(e.x,e.y),n.stroke(),this.lineDash&&n.setLineDash([]),this.drawX(t,-1),this.drawX(e,1),n.restore()}function l(t,e){const n=this.canvas.getTopContext(),i=this.canvas.getZoom(),r=this.xSize/i;n.save(),n.translate(t.x,t.y),n.beginPath(),n.moveTo(-r,-r),n.lineTo(r,r),n.moveTo(r,-r),n.lineTo(-r,r),n.stroke(),n.restore()}function h(t){const e=this.canvas.getTopContext(),n=this.canvas.viewportTransform,i=this.canvas.getZoom();e.save(),e.transform(...n),e.lineWidth=this.width/i,e.strokeStyle=this.color;for(const e of t)this.drawX(e,0);e.restore()}function d(){const t=[];if(!this.closeVLine)for(const e of this.verticalLines)t.push(JSON.parse(e));if(!this.closeHLine)for(const e of this.horizontalLines)t.push(JSON.parse(e));const e=t.map(t=>t.target);h.call(this,e)}function g(){if(!this.closeVLine)for(const t of this.verticalLines){const{origin:n,target:i}=JSON.parse(t),r=new e.Point(i.x,n.y);this.drawLine(r,i)}}function f(){if(!this.closeHLine)for(const t of this.horizontalLines){const{origin:n,target:i}=JSON.parse(t),r=new e.Point(n.x,i.y);this.drawLine(r,i)}}function u(t,e){const n=t.getCoords();n.push(t.getCenterPoint());const i={target:t,list:n,points:e,margin:this.margin/this.canvas.getZoom()};return{vLines:m({...i,type:"x"}),hLines:m({...i,type:"y"})}}const p=[["left","top"],["right","top"],["right","bottom"],["left","bottom"],["center","center"]];function m(t){const{target:e,list:n,points:i,margin:r,type:s}=t,a=[],c=[];let l=1/0;for(const t of n){const e=o(t,i,s);c.push(e),l>e.dis&&(l=e.dis)}if(l>r)return a;let h=!1;for(let t=0;t<n.length;t++){if(c[t].dis!=l)continue;for(const e of c[t].arr)a.push({origin:n[t],target:e});if(h)continue;h=!0;const i=c[t].arr[0][s]-n[t][s];n.forEach(t=>{t[s]+=i}),e.setXY(n[t],...p[t]),e.setCoords()}return a}function v(t){const n=new Set,i=t.canvas;if(!i)return n;const r=t instanceof e.ActiveSelection?t.getObjects():[t];return i.forEachObject(t=>{t.isOnScreen()&&t.visible&&(t.constructor!=e.Group?n.add(t):w(n,t))}),b(n,r),n}function b(t,n){for(const i of n)i.constructor==e.Group?b(t,i.getObjects()):t.delete(i)}function w(t,n){const i=n.getObjects();for(const n of i)n.visible&&(n.constructor!=e.Group?t.add(n):w(t,n))}const y=function(t){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"left",i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"top";return async function(r){const{originX:o=n,originY:s=i}=r;delete r.originX,delete r.originY;for(var a=arguments.length,c=new Array(a>1?a-1:0),l=1;l<a;l++)c[l-1]=arguments[l];const h=await t.call(this,r,...c),d=new e.Point(h.left,h.top);return h.setPositionByOrigin(d,o,s),h}},C=t=>async function(n){const{colorStops:i}=n,r=null==i?void 0:i.map(t=>{let{color:n,opacity:i,offset:r}=t;if(void 0===i||1===i)return{color:n,offset:r};return{color:new e.Color(n).setAlpha(i).toRgba(),offset:r}});return await t.call(this,{...n,colorStops:r})};const{wrapWithFixedAnchor:O,wrapWithFireEvent:P}=e.controlsUtils,x=P("CROPPING",O((t,n,i,r)=>{const{target:o}=n,{width:s}=o,a=o,c=e.controlsUtils.changeObjectWidth(t,n,i,r),l=a._element.width-a.cropX;return c&&(a.width>l&&(a.width=l),a.width<1&&(a.width=1)),s!==a.width})),S=P("CROPPING",O((t,n,i,r)=>{const{target:o}=n,{height:s}=o,a=o,c=e.controlsUtils.changeObjectHeight(t,n,i,r),l=a._element.height-a.cropY;return c&&(a.height>l&&(a.height=l),a.height<1&&(a.height=1)),s!==a.height})),T=P("CROPPING",O((t,n,i,r)=>{const{target:o}=n,s=o,{width:a,cropX:c}=s,l=e.controlsUtils.changeObjectWidth(t,n,i,r);let h=c+a-s.width;return s.width=a,l&&(h<0&&(h=0),s.cropX=h,s.width+=c-h),h!==c})),X=P("CROPPING",O((t,n,i,r)=>{const{target:o}=n,s=o,{height:a,cropY:c}=s,l=e.controlsUtils.changeObjectHeight(t,n,i,r);let h=c+a-s.height;return s.height=a,l&&(h<0&&(h=0),s.cropY=h,s.height+=c-h),h!==c})),z=t=>{let{transform:n}=t;const{target:i,original:r}=n,o=i,s=new e.Point(i.left-r.left,i.top-r.top).transform(e.util.invertTransform(e.util.createRotateMatrix({angle:o.getTotalAngle()})));let a=r.cropX-s.x/o.scaleX,c=r.cropY-s.y/o.scaleY;const{width:l,height:h,_element:d}=o;a<0&&(a=0),c<0&&(c=0),a+l>d.width&&(a=d.width-l),c+h>d.height&&(c=d.height-h),o.cropX=a,o.cropY=c,o.left=r.left,o.top=r.top};function R(t,n,i){const r=i.calcTransformMatrix(),o=i.getViewportTransform(),s=e.util.multiplyTransformMatrices(o,r);let a=0,c=0;return a=this.x<0?-i.width/2-i.cropX:i.getElement().width-i.width/2-i.cropX,c=this.y<0?-i.height/2-i.cropY:i.getElement().height-i.height/2-i.cropY,new e.Point(a,c).transform(s)}const Y=(t,n)=>(i,r,o,s)=>{const{target:a}=r,{width:c,height:l}=a.getElement(),h=c-a.width-a.cropX,d=l-a.height-a.cropY,g=t<0?1+h/a.width:-a.cropX/a.width,f=n<0?1+d/a.height:-a.cropY/a.height,u=a.translateToOriginPoint(a.getCenterPoint(),g,f),p=e.controlsUtils.getLocalPoint(r,g,f,o,s),m=(v=p,b=l,w=c,Math.min(Math.abs(v.x/w),Math.abs(v.y/b)));var v,b,w;const y=m/a.scaleX,C=m/a.scaleY,O=h/y,P=d/C,x=a.width/y,S=a.height/C,T=t<0?c-x-O:a.cropX/y,X=n<0?l-S-P:a.cropY/C;if((t<0?O:T)+x>c||(n<0?P:X)+S>l)return!1;a.scaleX=m,a.scaleY=m,a.width=x,a.height=S,a.cropX=T,a.cropY=X;const z=t<0?1+O/x:-T/x,R=n<0?1+P/S:-X/S;return a.setPositionByOrigin(u,z,R),!0};function H(t){let{ctx:e}=t;const n=e.globalAlpha;e.globalAlpha*=.5,e.drawImage(this._element,-this.width/2-this.cropX,-this.height/2-this.cropY),e.globalAlpha=n}const{degreesToRadians:j}=e.util;function L(t,e,n,i,r){t.save();const{stroke:o,xSize:s,ySize:a,opName:c}=this.commonRenderProps(t,e,n,r,i),l=s/2,h=a/2;t.rotate(j(this.angle)),t.beginPath(),t.moveTo(-h,0),t.lineTo(-h,l),t.lineTo(h,l),t.lineTo(h,h),t.lineTo(l,h),t.lineTo(l,-h),t.lineTo(-h,-h),t.closePath(),t[c](),o&&t.stroke(),t.restore()}const{scaleCursorStyleHandler:E}=e.controlsUtils,A=()=>"crop",D=()=>({tls:new e.Control({x:-.5,y:-.5,cursorStyleHandler:E,positionHandler:R,actionHandler:Y(-.5,-.5)}),brs:new e.Control({x:.5,y:.5,cursorStyleHandler:E,positionHandler:R,actionHandler:Y(.5,.5)}),trs:new e.Control({x:.5,y:-.5,cursorStyleHandler:E,positionHandler:R,actionHandler:Y(.5,-.5)}),bls:new e.Control({x:-.5,y:.5,cursorStyleHandler:E,positionHandler:R,actionHandler:Y(-.5,.5)}),mlc:new e.Control({x:-.5,y:0,sizeX:4,sizeY:20,cursorStyleHandler:E,actionHandler:T,getActionName:A}),mrc:new e.Control({x:.5,y:0,sizeX:4,sizeY:20,cursorStyleHandler:E,actionHandler:x,getActionName:A}),mbc:new e.Control({x:0,y:.5,sizeX:20,sizeY:4,cursorStyleHandler:E,actionHandler:S,getActionName:A}),mtc:new e.Control({x:0,y:-.5,sizeX:20,sizeY:4,cursorStyleHandler:E,actionHandler:X,getActionName:A}),tlc:new e.Control({angle:0,x:-.5,y:-.5,sizeX:20,sizeY:4,render:L,cursorStyleHandler:E,actionHandler:function(){const t=T(...arguments),e=X(...arguments);return t||e},getActionName:A}),trc:new e.Control({angle:90,x:.5,y:-.5,sizeX:20,sizeY:4,render:L,cursorStyleHandler:E,actionHandler:function(){const t=x(...arguments),e=X(...arguments);return t||e},getActionName:A}),blc:new e.Control({angle:270,x:-.5,y:.5,sizeX:20,sizeY:4,render:L,cursorStyleHandler:E,actionHandler:function(){const t=S(...arguments),e=T(...arguments);return t||e},getActionName:A}),brc:new e.Control({angle:180,x:.5,y:.5,sizeX:20,sizeY:4,render:L,cursorStyleHandler:E,actionHandler:function(){const t=S(...arguments),e=x(...arguments);return t||e},getActionName:A})});t.AligningGuidelines=class{constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};i(this,"canvas",void 0),i(this,"horizontalLines",new Set),i(this,"verticalLines",new Set),i(this,"cacheMap",new Map),i(this,"onlyDrawPoint",!1),i(this,"contraryOriginMap",{tl:["right","bottom"],tr:["left","bottom"],br:["left","top"],bl:["right","top"],mt:["center","bottom"],mr:["left","center"],mb:["center","top"],ml:["right","center"]}),i(this,"xSize",2.4),i(this,"lineDash",void 0),i(this,"margin",4),i(this,"width",1),i(this,"color","rgba(255,0,0,0.9)"),i(this,"closeVLine",!1),i(this,"closeHLine",!1),this.canvas=t,Object.assign(this,e),this.mouseUp=this.mouseUp.bind(this),this.scalingOrResizing=this.scalingOrResizing.bind(this),this.moving=this.moving.bind(this),this.beforeRender=this.beforeRender.bind(this),this.afterRender=this.afterRender.bind(this),this.initBehavior()}initBehavior(){this.canvas.on("mouse:up",this.mouseUp),this.canvas.on("object:resizing",this.scalingOrResizing),this.canvas.on("object:scaling",this.scalingOrResizing),this.canvas.on("object:moving",this.moving),this.canvas.on("before:render",this.beforeRender),this.canvas.on("after:render",this.afterRender)}getObjectsByTarget(t){return v(t)}getPointMap(t){return function(t){const e=t.getCoords();return{tl:e[0],tr:e[1],br:e[2],bl:e[3],mt:e[0].add(e[1]).scalarDivide(2),mr:e[1].add(e[2]).scalarDivide(2),mb:e[2].add(e[3]).scalarDivide(2),ml:e[3].add(e[0]).scalarDivide(2)}}(t)}getContraryMap(t){return function(t){var e;const n=null!==(e=t.aCoords)&&void 0!==e?e:t.calcACoords();return{tl:n.br,tr:n.bl,br:n.tl,bl:n.tr,mt:n.br.add(n.bl).scalarDivide(2),mr:n.bl.add(n.tl).scalarDivide(2),mb:n.tl.add(n.tr).scalarDivide(2),ml:n.tr.add(n.br).scalarDivide(2)}}(t)}getCaCheMapValue(t){const e=[t.calcTransformMatrix().toString(),t.width,t.height].join(),n=this.cacheMap.get(e);if(n)return n;const i=t.getCoords();return i.push(t.getCenterPoint()),this.cacheMap.set(e,i),i}drawLine(t,e){c.call(this,t,e)}drawX(t,e){l.call(this,t,e)}mouseUp(){this.verticalLines.clear(),this.horizontalLines.clear(),this.cacheMap.clear(),this.canvas.requestRenderAll()}scalingOrResizing(t){const n=t.target;n.setCoords();const i=String(t.transform.action).startsWith("scale");this.verticalLines.clear(),this.horizontalLines.clear();const r=this.getObjectsByTarget(n);let o=t.transform.corner;n.flipX&&(o.includes("l")?o=o.replace("l","r"):o.includes("r")&&(o=o.replace("r","l"))),n.flipY&&(o.includes("t")?o=o.replace("t","b"):o.includes("b")&&(o=o.replace("b","t")));const c=this.getPointMap(n);if(!(o in c))return;if(this.onlyDrawPoint=o.includes("m"),this.onlyDrawPoint){if(n.getTotalAngle()%90!=0)return}const l=this.getContraryMap(n),h=c[o];let d=l[o];const g="center"==t.transform.original.originX&&"center"==t.transform.original.originY;if(g){const t=n.group?h.transform(e.util.invertTransform(n.group.calcTransformMatrix())):h;d=d.add(t).scalarDivide(2)}const f=t.e[this.canvas.uniScaleKey];let u=this.canvas.uniformScaling&&!f||!this.canvas.uniformScaling&&f;this.onlyDrawPoint&&(u=!1);const p=[];for(const t of r){const e=this.getCaCheMapValue(t);p.push(...e)}const m={target:n,point:h,diagonalPoint:d,corner:o,list:p,isScale:i,isUniform:u,isCenter:g},v=this.onlyDrawPoint&&(o.includes("t")||o.includes("b")),b=this.onlyDrawPoint&&(o.includes("l")||o.includes("r")),w=v?[]:s.call(this,m),y=b?[]:a.call(this,m);w.forEach(t=>{this.verticalLines.add(JSON.stringify(t))}),y.forEach(t=>{this.horizontalLines.add(JSON.stringify(t))})}moving(t){const e=t.target;e.setCoords(),this.onlyDrawPoint=!1,this.verticalLines.clear(),this.horizontalLines.clear();const n=this.getObjectsByTarget(e),i=[];for(const t of n)i.push(...this.getCaCheMapValue(t));const{vLines:r,hLines:o}=u.call(this,e,i);r.forEach(t=>{this.verticalLines.add(JSON.stringify(t))}),o.forEach(t=>{this.horizontalLines.add(JSON.stringify(t))})}beforeRender(){this.canvas.clearContext(this.canvas.contextTop)}afterRender(){this.onlyDrawPoint?d.call(this):(g.call(this),f.call(this))}dispose(){this.canvas.off("mouse:up",this.mouseUp),this.canvas.off("object:resizing",this.scalingOrResizing),this.canvas.off("object:scaling",this.scalingOrResizing),this.canvas.off("object:moving",this.moving),this.canvas.off("before:render",this.beforeRender),this.canvas.off("after:render",this.afterRender)}},t.addGestures=t=>{const e=new n.Region(t.upperCanvasEl);t.addOrRemove(function(t){for(var e=arguments.length,n=new Array(e>1?e-1:0),i=1;i<e;i++)n[i-1]=arguments[i];return t.removeEventListener(...n)}),e.addGesture((t=>new n.Rotate(t.upperCanvasEl,e=>{let{rotation:n,event:i}=e;t.fireEventFromPointerEvent(i,"rotate","rotate",{rotation:n})}))(t)),e.addGesture((t=>new n.Pinch(t.upperCanvasEl,e=>{let{scale:n,event:i}=e;t.fireEventFromPointerEvent(i,"pinch","pinch",{scale:n})}))(t)),e.addGesture((t=>new n.Tap(t.upperCanvasEl,e=>{let{event:n}=e;t.fireEventFromPointerEvent(n,"mouse:tripleclick","mousetripleclick",void 0),n.preventDefault()},{numTaps:3,maxRetain:400}))(t)),e.addGesture((t=>new n.Tap(t.upperCanvasEl,e=>{let{event:n}=e;t.fireEventFromPointerEvent(n,"mouse:dblclick","mousedblclick",void 0),n.preventDefault()},{numTaps:2,maxRetain:300}))(t)),t.addOrRemove(function(t){for(var e=arguments.length,n=new Array(e>1?e-1:0),i=1;i<e;i++)n[i-1]=arguments[i];return t.addEventListener(...n)},!0)},t.changeCropHeight=S,t.changeCropWidth=x,t.changeCropX=T,t.changeCropY=X,t.createImageCroppingControls=D,t.enterCropMode=function t(e){var n;let{target:i}=e;const r=i,{controls:o,padding:s}=r;r.padding=0,r.controls=D(),r.on("moving",z),r.on("before:render",H),r.setCoords();r.once("mousedblclick",()=>{var e;r.padding=s,r.off("moving",z),r.off("before:render",H),r.controls=o,r.setCoords(),r.once("mousedblclick",t),null===(e=r.canvas)||void 0===e||e.requestRenderAll()}),null===(n=r.canvas)||void 0===n||n.requestRenderAll()},t.gradientUpdaterWrapper=C,t.installGradientUpdater=()=>{e.Gradient.fromObject=C(e.Gradient.fromObject)},t.installOriginWrapperUpdater=(t,n)=>{e.BaseFabricObject._fromObject=y(e.BaseFabricObject._fromObject,t,n),e.FabricImage.fromObject=y(e.FabricImage.fromObject,t,n),e.Group.fromObject=y(e.Group.fromObject,t,n)},t.originUpdaterWrapper=y,t.pinchEventHandler=function(t){let{scale:e,target:n,scenePoint:i}=t;n&&this.getActiveObject()===n?(n.scaleX*=e,n.scaleY*=e):this.zoomToPoint(i,this.getZoom()*e)},t.rotateEventHandler=function(t){let{rotation:n,target:i}=t;i&&this.getActiveObject()===i&&i.rotate(i.angle+e.util.radiansToDegrees(n))}});
2
2
  //# sourceMappingURL=fabric-extensions.min.js.map