@printine/designer 0.1.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 (199) hide show
  1. package/README.md +146 -0
  2. package/dist/DesignerRuntimeContext.d.ts +3 -0
  3. package/dist/PrintineDesigner.d.ts +9 -0
  4. package/dist/api/client.d.ts +8 -0
  5. package/dist/api/client.js +82 -0
  6. package/dist/api/common-endpoints.d.ts +12 -0
  7. package/dist/api/design-endpoints.d.ts +18 -0
  8. package/dist/api/endpoints.d.ts +33 -0
  9. package/dist/api/endpoints.js +46 -0
  10. package/dist/api/files-endpoints.d.ts +1 -0
  11. package/dist/assets/icons/aspect_ratio.d.ts +3 -0
  12. package/dist/assets/icons/delete.d.ts +3 -0
  13. package/dist/assets/icons/fit_screen.d.ts +3 -0
  14. package/dist/assets/icons/index.d.ts +11 -0
  15. package/dist/assets/icons/loading_1.d.ts +3 -0
  16. package/dist/assets/icons/loading_2.d.ts +3 -0
  17. package/dist/assets/icons/loading_3.d.ts +3 -0
  18. package/dist/assets/icons/pan.d.ts +3 -0
  19. package/dist/assets/icons/setting.d.ts +3 -0
  20. package/dist/assets/icons/text_color.d.ts +3 -0
  21. package/dist/assets/icons/text_h.d.ts +3 -0
  22. package/dist/assets/icons/text_v.d.ts +3 -0
  23. package/dist/bundled-assets.d.ts +4 -0
  24. package/dist/components/add-design.d.ts +8 -0
  25. package/dist/components/assets-dialog.d.ts +21 -0
  26. package/dist/components/canvas-context-menu.d.ts +6 -0
  27. package/dist/components/color-picker/index.d.ts +10 -0
  28. package/dist/components/context.d.ts +24 -0
  29. package/dist/components/design.d.ts +9 -0
  30. package/dist/components/fonts.d.ts +26 -0
  31. package/dist/components/image-crop.d.ts +4 -0
  32. package/dist/components/image-edit.d.ts +1 -0
  33. package/dist/components/layout/aside.d.ts +3 -0
  34. package/dist/components/layout/bottom-nav/element-menu-sheet.d.ts +11 -0
  35. package/dist/components/layout/bottom-nav/element-sheet.d.ts +11 -0
  36. package/dist/components/layout/bottom-nav/index.d.ts +1 -0
  37. package/dist/components/layout/header.d.ts +5 -0
  38. package/dist/components/loading.d.ts +3 -0
  39. package/dist/components/menus/ai.d.ts +5 -0
  40. package/dist/components/menus/background.d.ts +6 -0
  41. package/dist/components/menus/clipart.d.ts +6 -0
  42. package/dist/components/menus/files.d.ts +7 -0
  43. package/dist/components/menus/image.d.ts +8 -0
  44. package/dist/components/menus/index.d.ts +13 -0
  45. package/dist/components/menus/layer.d.ts +5 -0
  46. package/dist/components/menus/product.d.ts +3 -0
  47. package/dist/components/menus/sca.d.ts +5 -0
  48. package/dist/components/menus/shapes.d.ts +6 -0
  49. package/dist/components/menus/templates.d.ts +6 -0
  50. package/dist/components/menus/text-effects.d.ts +5 -0
  51. package/dist/components/menus/text.d.ts +6 -0
  52. package/dist/components/placement-tab.d.ts +7 -0
  53. package/dist/components/preview/3d.d.ts +7 -0
  54. package/dist/components/preview/graphic.d.ts +7 -0
  55. package/dist/components/preview/index.d.ts +18 -0
  56. package/dist/components/preview/open.d.ts +7 -0
  57. package/dist/components/preview/real-time/3d.d.ts +12 -0
  58. package/dist/components/preview/real-time/graphic.d.ts +18 -0
  59. package/dist/components/preview/real-time/index.d.ts +11 -0
  60. package/dist/components/scale-tools.d.ts +7 -0
  61. package/dist/components/semi-deisgn-config.d.ts +13 -0
  62. package/dist/components/semi-design-link.d.ts +9 -0
  63. package/dist/components/store.d.ts +1 -0
  64. package/dist/components/toolbar.d.ts +2 -0
  65. package/dist/config-D2qm60gf.js +16 -0
  66. package/dist/contracts/api-design.d.ts +176 -0
  67. package/dist/contracts/design.d.ts +86 -0
  68. package/dist/design-7zRpRtv9.js +20331 -0
  69. package/dist/engine/canvas-designer.d.ts +101 -0
  70. package/dist/engine/canvas-designer.js +313 -0
  71. package/dist/engine/constants.d.ts +27 -0
  72. package/dist/engine/constants.js +148 -0
  73. package/dist/engine/editor.d.ts +186 -0
  74. package/dist/engine/editor.js +734 -0
  75. package/dist/engine/events.d.ts +34 -0
  76. package/dist/engine/events.js +7 -0
  77. package/dist/engine/extensions/curved-text.d.ts +59 -0
  78. package/dist/engine/fabric.d.ts +4 -0
  79. package/dist/engine/fabric.js +187 -0
  80. package/dist/engine/history.d.ts +27 -0
  81. package/dist/engine/history.js +56 -0
  82. package/dist/engine/managers/event.d.ts +101 -0
  83. package/dist/engine/managers/event.js +410 -0
  84. package/dist/engine/managers/resize.d.ts +24 -0
  85. package/dist/engine/managers/resize.js +63 -0
  86. package/dist/engine/managers/snapline.d.ts +70 -0
  87. package/dist/engine/managers/snapline.js +124 -0
  88. package/dist/engine/managers/workspace.d.ts +26 -0
  89. package/dist/engine/managers/workspace.js +53 -0
  90. package/dist/engine/processors/image.d.ts +88 -0
  91. package/dist/engine/processors/image.js +473 -0
  92. package/dist/engine/processors/template.d.ts +45 -0
  93. package/dist/engine/processors/template.js +314 -0
  94. package/dist/engine/processors/text.d.ts +74 -0
  95. package/dist/engine/processors/text.js +215 -0
  96. package/dist/engine/semi-export-editor.d.ts +199 -0
  97. package/dist/engine/types.d.ts +28 -0
  98. package/dist/engine/utils/common.d.ts +25 -0
  99. package/dist/engine/utils/common.js +68 -0
  100. package/dist/engine/utils/dialog.d.ts +25 -0
  101. package/dist/engine/utils/font.d.ts +5 -0
  102. package/dist/engine/utils/font.js +39 -0
  103. package/dist/engine/utils/image.d.ts +8 -0
  104. package/dist/engine/utils/image.js +50 -0
  105. package/dist/engine/utils/loading.d.ts +17 -0
  106. package/dist/engine/utils/loading.js +71 -0
  107. package/dist/engine/utils/measure.d.ts +6 -0
  108. package/dist/engine/utils/measure.js +6 -0
  109. package/dist/engine/utils/mockup.d.ts +59 -0
  110. package/dist/engine/utils/setting.d.ts +4 -0
  111. package/dist/engine/utils/setting.js +73 -0
  112. package/dist/fabric-types.d.ts +59 -0
  113. package/dist/full-designer.js +14 -0
  114. package/dist/hooks/pagination.d.ts +19 -0
  115. package/dist/hooks/use-adobe-express.d.ts +50 -0
  116. package/dist/hooks/use-before-unload.d.ts +1 -0
  117. package/dist/hooks/use-image-drop.d.ts +18 -0
  118. package/dist/hooks/use-oss-upload.d.ts +34 -0
  119. package/dist/hooks/use-screen.d.ts +1 -0
  120. package/dist/i18n/index.d.ts +12 -0
  121. package/dist/images/design/asset_empty.png +0 -0
  122. package/dist/images/design/design/background.svg +3 -0
  123. package/dist/images/design/design/color-picker.svg +15 -0
  124. package/dist/images/design/design/computer.svg +1 -0
  125. package/dist/images/design/design/copy.svg +1 -0
  126. package/dist/images/design/design/image.svg +10 -0
  127. package/dist/images/design/design/line.svg +1 -0
  128. package/dist/images/design/design/text.svg +1 -0
  129. package/dist/images/design/design/title.svg +1 -0
  130. package/dist/images/design/empty.png +0 -0
  131. package/dist/images/design/layer_empty.png +0 -0
  132. package/dist/images/design/menu/ai.svg +1 -0
  133. package/dist/images/design/menu/back.svg +4 -0
  134. package/dist/images/design/menu/background.svg +6 -0
  135. package/dist/images/design/menu/clipart.svg +6 -0
  136. package/dist/images/design/menu/file.svg +4 -0
  137. package/dist/images/design/menu/fill.svg +1 -0
  138. package/dist/images/design/menu/image.svg +7 -0
  139. package/dist/images/design/menu/layer.svg +6 -0
  140. package/dist/images/design/menu/product.svg +3 -0
  141. package/dist/images/design/menu/sca.svg +5 -0
  142. package/dist/images/design/menu/shapes.svg +5 -0
  143. package/dist/images/design/menu/templates.svg +6 -0
  144. package/dist/images/design/menu/text.svg +6 -0
  145. package/dist/images/design/menu/uploads.svg +7 -0
  146. package/dist/images/design/spinner.svg +3 -0
  147. package/dist/images/design/spinners.svg +17 -0
  148. package/dist/images/design/transparent_pattern.svg +5 -0
  149. package/dist/index.d.ts +39 -0
  150. package/dist/index.js +127 -0
  151. package/dist/lib/analytics.d.ts +17 -0
  152. package/dist/lib/cn.d.ts +3 -0
  153. package/dist/lib/common.d.ts +16 -0
  154. package/dist/lib/config.d.ts +14 -0
  155. package/dist/lib/navigation.d.ts +2 -0
  156. package/dist/renderer/ThreeDPreview.d.ts +14 -0
  157. package/dist/renderer/sticker.js +1731 -0
  158. package/dist/renderer/three-d-preview.js +32 -0
  159. package/dist/state/designer-store.d.ts +43 -0
  160. package/dist/state/designer-store.js +85 -0
  161. package/dist/style.css +1 -0
  162. package/dist/types.d.ts +184 -0
  163. package/dist/ui/accordion.d.ts +7 -0
  164. package/dist/ui/button-group.d.ts +11 -0
  165. package/dist/ui/button.d.ts +10 -0
  166. package/dist/ui/checkbox.d.ts +4 -0
  167. package/dist/ui/command.d.ts +18 -0
  168. package/dist/ui/confirm-dialog.d.ts +15 -0
  169. package/dist/ui/context-menu.d.ts +25 -0
  170. package/dist/ui/dialog.d.ts +15 -0
  171. package/dist/ui/drawer.d.ts +15 -0
  172. package/dist/ui/editable-combobox.d.ts +10 -0
  173. package/dist/ui/hint.d.ts +8 -0
  174. package/dist/ui/image.d.ts +24 -0
  175. package/dist/ui/input-group.d.ts +16 -0
  176. package/dist/ui/input-with-addon.d.ts +17 -0
  177. package/dist/ui/input.d.ts +3 -0
  178. package/dist/ui/label.d.ts +4 -0
  179. package/dist/ui/loading-button.d.ts +15 -0
  180. package/dist/ui/popover.d.ts +9 -0
  181. package/dist/ui/scroll-area.d.ts +5 -0
  182. package/dist/ui/select.d.ts +22 -0
  183. package/dist/ui/separator.d.ts +4 -0
  184. package/dist/ui/shared-loading-button.d.ts +20 -0
  185. package/dist/ui/simple-dialog.d.ts +19 -0
  186. package/dist/ui/simple-popover.d.ts +13 -0
  187. package/dist/ui/simple-select.d.ts +20 -0
  188. package/dist/ui/skeleton.d.ts +2 -0
  189. package/dist/ui/slider.d.ts +4 -0
  190. package/dist/ui/spinner-box.d.ts +12 -0
  191. package/dist/ui/spinner.d.ts +2 -0
  192. package/dist/ui/switch.d.ts +6 -0
  193. package/dist/ui/tab/index.d.ts +15 -0
  194. package/dist/ui/textarea.d.ts +3 -0
  195. package/dist/ui/tooltip.d.ts +7 -0
  196. package/dist/workers/image-resize.worker.d.ts +1 -0
  197. package/dist/workers/mockup.worker.d.ts +5 -0
  198. package/dist/workers/render.worker.d.ts +1 -0
  199. package/package.json +201 -0
@@ -0,0 +1,410 @@
1
+ import "../fabric.js";
2
+ import A from "lodash-es/debounce";
3
+ import P from "lodash-es/throttle";
4
+ import { HistoryManager as D } from "../history.js";
5
+ import { SnaplineManager as L } from "./snapline.js";
6
+ import { TextProcessor as T } from "../processors/text.js";
7
+ import { toVerticalStack as z } from "../utils/common.js";
8
+ import { useDesignerStore as R } from "../../state/designer-store.js";
9
+ import { fabric as x } from "fabric";
10
+ class V {
11
+ constructor(t, o) {
12
+ this.eventHandlers = /* @__PURE__ */ new Map(), this.isDragging = !1, this.isSpacePressed = !1, this.lastPostion = { x: 0, y: 0 }, this.hammerCanvas = null, this.updateCurrentState = (d) => new Promise((v) => {
13
+ this.disableHistory(), this.editor.canvas.loadFromJSON(d, () => {
14
+ this.editor.relinkClipPaths(), this.editor.canvas.renderAll(), v(!0), this.events.emit("design:objectChange"), setTimeout(() => {
15
+ this.enableHistory();
16
+ }, 300);
17
+ });
18
+ }), this.editor = t, this.events = t.events, this.alignmentManager = new L(), this.historyManager = o, this.enableCavansPan().enableHistory().enableRightClick().enableAlignment().enableSelection().enableLayerChange().enableRotationIndicator().enableTextChanged();
19
+ }
20
+ updateHistoryManager(t) {
21
+ this.historyManager = t;
22
+ }
23
+ /**
24
+ * 画布缩放
25
+ * viewportTransform [水平缩放, 垂直倾斜或旋转, 横向倾斜或旋转, 垂直缩放, 水平平移, 垂直平移]
26
+ */
27
+ enableCanvasZoom() {
28
+ const v = (h) => {
29
+ const s = h.e.deltaY;
30
+ let e = this.editor.canvas.getZoom();
31
+ s < 0 ? e += 0.05 : e -= 0.05, e = Math.max(0.2, Math.min(5, e));
32
+ const r = new x.Point(h.e.offsetX, h.e.offsetY);
33
+ this.editor.canvas.zoomToPoint(r, e), h.e.preventDefault(), h.e.stopPropagation();
34
+ };
35
+ return this.editor.canvas.on("mouse:wheel", v), this.eventHandlers.set("zoom", [{ event: "mouse:wheel", handler: v }]), this;
36
+ }
37
+ /** Attaches an optional Hammer.js manager so a host can opt into touch gestures. */
38
+ setTouchGestureManager(t) {
39
+ return this.hammerCanvas = t, this;
40
+ }
41
+ /**
42
+ * 触摸缩放画布(需要先注入 Hammer.js 管理器)
43
+ */
44
+ enableTouchZoom(t = {}) {
45
+ const { minScale: o = 0.2, maxScale: d = 3 } = t;
46
+ if (!this.hammerCanvas) return this;
47
+ let v = 1;
48
+ return this.hammerCanvas.get("pinch").set({ enable: !0 }), this.hammerCanvas.on("pinchstart", () => {
49
+ v = this.editor.canvas.getZoom();
50
+ }), this.hammerCanvas.on("pinch", (h) => {
51
+ const s = Math.max(o, Math.min(d, v * h.scale)), e = h.center, c = this.editor.canvas.getElement().getBoundingClientRect(), i = new x.Point(e.x - c.left, e.y - c.top);
52
+ this.editor.canvas.zoomToPoint(i, s), h.srcEvent && h.srcEvent.preventDefault();
53
+ }), this;
54
+ }
55
+ /**
56
+ * 单指触摸移动画布
57
+ */
58
+ enableTouchPan() {
59
+ return this.hammerCanvas ? (this.hammerCanvas.get("pan").set({
60
+ pointers: 1
61
+ }), this.hammerCanvas.get("press").set({ pointers: 1, time: 500 }), this.hammerCanvas.on("press", (t) => {
62
+ this.isDragging = !0, this.lastPostion.x = t.center.x, this.lastPostion.y = t.center.y;
63
+ }), this.hammerCanvas.on("pan", (t) => {
64
+ if (!this.isDragging) return;
65
+ const o = t.center.x - this.lastPostion.x, d = t.center.y - this.lastPostion.y;
66
+ this.lastPostion.x = t.center.x, this.lastPostion.y = t.center.y;
67
+ const v = this.editor.canvas.viewportTransform;
68
+ v[4] += o, v[5] += d, this.editor.canvas.setViewportTransform(v);
69
+ }), this.hammerCanvas.on("pressup", () => {
70
+ this.isDragging = !1;
71
+ }), this) : this;
72
+ }
73
+ /**
74
+ * 更新画布鼠标样式
75
+ */
76
+ updateCursor(t) {
77
+ this.editor.canvas.defaultCursor = t, this.editor.canvas.setCursor(t);
78
+ }
79
+ /**
80
+ * 画布平移、键盘快捷键、hover 高亮
81
+ */
82
+ enableCavansPan() {
83
+ const t = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"], o = A((n) => {
84
+ this.editor.canvas.fire("object:modified", {
85
+ target: n
86
+ });
87
+ }, 500), d = (n) => {
88
+ if (document.activeElement?.tagName === "INPUT" || document.activeElement?.tagName === "TEXTAREA" || document.activeElement?.isContentEditable) return;
89
+ const f = n.metaKey || n.ctrlKey;
90
+ if (n.code === "Space" && !n.repeat)
91
+ this.isSpacePressed = !0, this.events.emit("design:updateGrabState", !0), this.updateCursor("grab");
92
+ else if (n.code === "Delete" || n.code === "Backspace")
93
+ this.editor.canvas.getActiveObjects().length > 0 && n.preventDefault(), this.editor.deleteObject();
94
+ else if (f && !n.shiftKey && n.key === "z") {
95
+ const l = this.historyManager.undo();
96
+ l && this.updateCurrentState(l);
97
+ } else if (f && n.shiftKey && n.key === "z") {
98
+ const l = this.historyManager.redo();
99
+ l && this.updateCurrentState(l);
100
+ } else if (t.includes(n.code)) {
101
+ const l = this.editor.activeObject;
102
+ if (!l) return;
103
+ n.preventDefault();
104
+ const p = this.editor.canvas.viewportTransform[0] || 1;
105
+ let S = 0, w = 0;
106
+ n.code === "ArrowLeft" && (S -= p), n.code === "ArrowRight" && (S += p), n.code === "ArrowUp" && (w -= p), n.code === "ArrowDown" && (w += p), (S !== 0 || w !== 0) && (l?.set({
107
+ left: (l?.left || 0) + S,
108
+ top: (l?.top || 0) + w
109
+ }), this.alignmentManager.snapToObjectGuideLines(this.editor.canvas, l), this.editor.canvas.requestRenderAll(), o(l));
110
+ } else f && n.key.toLowerCase() === "a" ? (n.preventDefault(), this.events.emit("design:editorCommand", "SELECT_ALL")) : f && n.key.toLowerCase() === "c" ? (n.preventDefault(), this.events.emit("design:editorCommand", "COPY")) : f && n.key.toLowerCase() === "v" && (n.preventDefault(), this.events.emit("design:editorCommand", "PASTE"));
111
+ }, v = (n) => {
112
+ n.code === "Space" ? (this.isSpacePressed = !1, this.events.emit("design:updateGrabState", !1), this.updateCursor("default")) : t.includes(n.code) && (this.alignmentManager.clearGuideLines(), this.editor.canvas.requestRenderAll());
113
+ };
114
+ let h = !1;
115
+ const s = (n) => {
116
+ if (this.isSpacePressed) {
117
+ n.target || (this.isDragging = !0, this.updateCursor("grabbing"), this.lastPostion.x = n.e.clientX, this.lastPostion.y = n.e.clientY);
118
+ return;
119
+ }
120
+ n.target && (h = !0, a());
121
+ };
122
+ let e = null;
123
+ const r = 2, c = "#3540a5", i = (n) => {
124
+ e = n, e.setCoords(), this.editor.canvas.requestRenderAll();
125
+ }, a = () => {
126
+ e && (e = null, this.editor.canvas.requestRenderAll());
127
+ }, g = () => {
128
+ if (!e || this.editor.canvas.getActiveObjects().some((b) => b === e || b.id === e?.id)) return;
129
+ e.setCoords();
130
+ const u = e.aCoords;
131
+ if (!u) return;
132
+ const { tl: f, tr: l, br: E, bl: p } = u, S = this.editor.canvas.viewportTransform || x.iMatrix, w = [f, l, E, p].map((b) => x.util.transformPoint(new x.Point(b.x, b.y), S)), y = this.editor.canvas.getContext();
133
+ y.save(), y.beginPath(), w.forEach((b, _) => {
134
+ _ === 0 ? y.moveTo(b.x, b.y) : y.lineTo(b.x, b.y);
135
+ }), y.closePath(), y.lineWidth = r, y.strokeStyle = c, y.stroke(), y.restore();
136
+ }, m = (n) => {
137
+ if (this.isDragging && this.isSpacePressed) {
138
+ const u = n.e, f = this.editor.canvas.viewportTransform;
139
+ f[4] += u.clientX - this.lastPostion.x, f[5] += u.clientY - this.lastPostion.y, this.lastPostion.x = u.clientX, this.lastPostion.y = u.clientY, this.editor.canvas.requestRenderAll();
140
+ } else {
141
+ if (h) return;
142
+ const u = this.editor.canvas.getActiveObjects();
143
+ if (u.length && n.target && u.some((E) => E === n.target || E.id === n.target.id))
144
+ return;
145
+ const f = n.target?.isMoving;
146
+ if (n.transform || f) {
147
+ a();
148
+ return;
149
+ }
150
+ const l = n.target ?? (u.length === 0 ? this.editor.canvas.findTarget(n.e, !1) : void 0);
151
+ if (l && l.selectable) {
152
+ if (u.some((p) => p === l || p.id === l.id)) {
153
+ a();
154
+ return;
155
+ }
156
+ l.id !== e?.id && i(l);
157
+ } else
158
+ a();
159
+ }
160
+ }, C = () => {
161
+ this.isDragging && (this.isDragging = !1, this.updateCursor("grab")), h = !1, this.alignmentManager.clearGuideLines();
162
+ };
163
+ return window.addEventListener("keydown", d), window.addEventListener("keyup", v), this.editor.canvas.on("mouse:down", s), this.editor.canvas.on("mouse:move", m), this.editor.canvas.on("mouse:up", C), this.editor.canvas.on("selection:created", a), this.editor.canvas.on("selection:updated", a), this.editor.canvas.on("after:render", g), this.eventHandlers.set("pan", [
164
+ { event: "mouse:down", handler: s },
165
+ { event: "mouse:move", handler: m },
166
+ { event: "mouse:up", handler: C },
167
+ { event: "keydown", handler: d },
168
+ { event: "keyup", handler: v },
169
+ { event: "selection:created", handler: a },
170
+ { event: "selection:updated", handler: a },
171
+ { event: "after:render", handler: g }
172
+ ]), this;
173
+ }
174
+ /**
175
+ * 解除历史记录事件监听
176
+ */
177
+ disableHistory() {
178
+ ["object:modified", "object:added", "object:removed"].forEach((o) => this.editor.canvas.off(o));
179
+ }
180
+ /**
181
+ * 历史记录
182
+ */
183
+ enableHistory(t = {}) {
184
+ const o = [...D.DEFAULT_SAVE_PROPERTIES, ...t.properties || []], d = ["object:added", "object:removed", "object:modified", "editing:exited"], v = (e) => {
185
+ if (e.target.excludeHistory) return;
186
+ const r = this.editor.canvas.toJSON(o);
187
+ r.objects.forEach((c) => {
188
+ c.type.includes("i-text") && Object.keys(T.DEFAULT_TEXT_CONFIG).forEach((i) => {
189
+ c[i] !== T.DEFAULT_TEXT_CONFIG[i] && (c[i] = T.DEFAULT_TEXT_CONFIG[i]);
190
+ });
191
+ }), this.historyManager.add(r), this.events.emit("design:objectChange");
192
+ }, h = P((e) => {
193
+ !e.target || !e.target.type?.includes("i-text") || R.setState({ activeObjects: [e.target] });
194
+ }, 100), s = A(v, 500);
195
+ return d.forEach((e) => {
196
+ this.editor.canvas.on(e, s), this.eventHandlers.has("history") || this.eventHandlers.set("history", []), this.eventHandlers.get("history").push({
197
+ event: e,
198
+ handler: s
199
+ });
200
+ }), this.editor.canvas.on("object:modified", h), this.eventHandlers.set("activeText", [{ event: "object:modified", handler: h }]), this;
201
+ }
202
+ /**
203
+ * 竖排文字编辑时的文本重排
204
+ */
205
+ enableTextChanged() {
206
+ const t = (s) => {
207
+ const e = new Array(s.length + 1);
208
+ let r = "", c = 0, i = 0;
209
+ for (; i <= s.length && (e[i] = c, i !== s.length); ) {
210
+ const a = s[i];
211
+ if (a === `
212
+ `) {
213
+ if (s[i + 1] === "​" && s[i + 2] === `
214
+ `) {
215
+ r += `
216
+ `, c += 1, e[i + 1] = c, e[i + 2] = c, i += 3;
217
+ continue;
218
+ }
219
+ i += 1;
220
+ continue;
221
+ }
222
+ r += a, c += 1, i += 1;
223
+ }
224
+ return { raw: r, stackedToRaw: e };
225
+ }, o = (s) => {
226
+ const e = new Array(s.length + 1);
227
+ let r = 0;
228
+ for (let c = 0; c < s.length; c++) {
229
+ if (e[c] = r, s[c] === `
230
+ `) {
231
+ r += 3;
232
+ continue;
233
+ }
234
+ r += 1;
235
+ const a = c + 1 < s.length ? s[c + 1] : void 0;
236
+ typeof a < "u" && a !== `
237
+ ` && (r += 1);
238
+ }
239
+ return e[s.length] = r, e;
240
+ }, d = (s, e, r, c) => {
241
+ const i = Math.max(0, Math.min(r, s.length));
242
+ return c === "left" && i > 0 && s[i - 1] !== `
243
+ ` ? (e[i - 1] ?? 0) + 1 : e[i] ?? 0;
244
+ }, v = (s, e) => {
245
+ const r = e.value ?? "", c = e.selectionStart ?? 0, i = e.selectionEnd ?? c, a = s.__prevStacked, g = s.__prevSelStart, m = s.__prevSelEnd, C = typeof a == "string" ? r.length - a.length : 0, n = typeof a == "string" ? C < 0 : !1, u = n && typeof g == "number" && typeof m == "number" ? c < g && i <= m : !1, { raw: f, stackedToRaw: l } = t(r);
246
+ s.__rawText = f;
247
+ const E = z(f), p = o(f), S = Math.max(0, Math.min(c, l.length - 1)), w = Math.max(0, Math.min(i, l.length - 1)), y = l[S] ?? 0, b = l[w] ?? y, _ = Math.max(0, Math.min(y, f.length)), H = Math.max(0, Math.min(b, f.length)), M = n ? "left" : S > 0 && r[S - 1] === `
248
+ ` ? "right" : "left", k = n ? "left" : w > 0 && r[w - 1] === `
249
+ ` ? "right" : "left", O = d(f, p, _, M), j = d(f, p, H, k);
250
+ e.value = E, e.setSelectionRange(O, j), s.updateFromTextArea?.(), s.__prevStacked = e.value ?? "", s.__prevSelStart = e.selectionStart ?? 0, s.__prevSelEnd = e.selectionEnd ?? s.__prevSelStart, s.__lastEditWasBackspace = u;
251
+ }, h = (s) => {
252
+ const e = s.target;
253
+ if (e?.type?.includes("i-text") && !(e.orientation !== "vertical" || !e.isEditing || e.__isReflowing)) {
254
+ e.__isReflowing = !0;
255
+ try {
256
+ const r = e.hiddenTextarea;
257
+ if (!r) return;
258
+ const c = r;
259
+ if (c.__verticalKeydownBound || (c.__verticalKeydownBound = !0, r.addEventListener(
260
+ "keydown",
261
+ (i) => {
262
+ const a = e;
263
+ if (!a?.isEditing || a.orientation !== "vertical" || a.inCompositionMode || i.key !== "Enter") return;
264
+ i.preventDefault(), i.stopPropagation();
265
+ const g = `
266
+
267
+ `, m = i.target, C = m.selectionStart ?? 0, n = m.selectionEnd ?? C, u = (m.value || "").slice(0, C), f = (m.value || "").slice(n);
268
+ m.value = u + g + f;
269
+ const l = C + g.length;
270
+ if (m.setSelectionRange(l, l), !a.__isReflowing) {
271
+ a.__isReflowing = !0;
272
+ try {
273
+ v(a, m), this.editor.canvas.requestRenderAll();
274
+ } finally {
275
+ a.__isReflowing = !1;
276
+ }
277
+ }
278
+ },
279
+ { passive: !1 }
280
+ )), e.inCompositionMode) {
281
+ e.__pendingVerticalNormalize = !0;
282
+ const i = r;
283
+ i.__verticalCompositionBound || (i.__verticalCompositionBound = !0, r.addEventListener(
284
+ "compositionend",
285
+ () => {
286
+ setTimeout(() => {
287
+ const a = e;
288
+ if (!(!a?.isEditing || a.orientation !== "vertical") && !a.__isReflowing) {
289
+ a.__isReflowing = !0;
290
+ try {
291
+ const g = a.hiddenTextarea;
292
+ if (!g) return;
293
+ v(a, g), a.__pendingVerticalNormalize = !1, this.editor.canvas.requestRenderAll();
294
+ } finally {
295
+ a.__isReflowing = !1;
296
+ }
297
+ }
298
+ }, 0);
299
+ },
300
+ { passive: !0 }
301
+ ));
302
+ return;
303
+ }
304
+ v(e, r), this.editor.canvas.requestRenderAll();
305
+ } finally {
306
+ e.__isReflowing = !1;
307
+ }
308
+ }
309
+ };
310
+ return this.editor.canvas.on("text:changed", h), this.eventHandlers.set("textChanged", [{ event: "text:changed", handler: h }]), this;
311
+ }
312
+ /**
313
+ * 对象对齐、控制器缩放显示对齐辅助线
314
+ */
315
+ enableAlignment() {
316
+ const t = (d) => {
317
+ d.target.excludeHistory || this.alignmentManager.snapToGuidelines(this.editor.canvas, d.target, this.editor.workspaceManager.dimension);
318
+ }, o = () => {
319
+ this.alignmentManager.drawGuideLines(this.editor.canvas.getContext());
320
+ };
321
+ return this.editor.canvas.on("after:render", o), this.editor.canvas.on("object:moving", t), this.editor.canvas.on("object:scaling", t), this.eventHandlers.set("alignment", [
322
+ { event: "after:render", handler: o },
323
+ { event: "object:moving", handler: t },
324
+ { event: "object:scaling", handler: t }
325
+ ]), this;
326
+ }
327
+ enableSelection() {
328
+ const t = (o) => {
329
+ R.setState({ activeObjects: o.selected || [] });
330
+ };
331
+ return this.editor.canvas.on("selection:created", t), this.editor.canvas.on("selection:updated", t), this.editor.canvas.on("selection:cleared", t), this.eventHandlers.set("selection", [
332
+ { event: "selection:created", handler: t },
333
+ { event: "selection:updated", handler: t },
334
+ { event: "selection:cleared", handler: t }
335
+ ]), this;
336
+ }
337
+ /**
338
+ * 图层信息变动
339
+ */
340
+ enableLayerChange() {
341
+ const t = P(() => {
342
+ this.events.emit("design:layerChange");
343
+ }, 300);
344
+ return this.editor.canvas.on("after:render", t), this.eventHandlers.set("layerChange", [{ event: "after:render", handler: t }]), this;
345
+ }
346
+ /**
347
+ * 对象旋转时显示旋转角度
348
+ */
349
+ enableRotationIndicator() {
350
+ let t = null;
351
+ const o = (v) => {
352
+ const h = v.target;
353
+ if (!h) return;
354
+ let s = Math.round(h.angle || 0) % 360;
355
+ s < 0 && (s += 360), t || (t = document.createElement("div"), t.style.cssText = `
356
+ position: fixed;
357
+ background: #3540a5;
358
+ color: #fff;
359
+ padding: 4px 8px;
360
+ border-radius: 4px;
361
+ font-size: 12px;
362
+ font-weight: 500;
363
+ pointer-events: none;
364
+ z-index: 9999;
365
+ box-shadow: 0 2px 8px rgba(0,0,0,0.15);
366
+ `, document.body.appendChild(t)), t.textContent = `${s}°`;
367
+ const e = this.editor.canvas.getZoom(), r = this.editor.canvas.viewportTransform || [1, 0, 0, 1, 0, 0], i = this.editor.canvas.getElement().getBoundingClientRect(), a = i.left + (h.left + r[4]) * e, g = i.top + (h.top + r[5]) * e - 40;
368
+ t.style.left = `${a}px`, t.style.top = `${g}px`, t.style.transform = "translateX(-50%)";
369
+ };
370
+ this.editor.canvas.on("object:rotating", o);
371
+ const d = () => {
372
+ t && (document.body.removeChild(t), t = null);
373
+ };
374
+ return this.editor.canvas.on("object:modified", d), this.editor.canvas.on("selection:cleared", d), this.editor.canvas.on("mouse:up", d), this.eventHandlers.set("rotationIndicator", [
375
+ { event: "object:rotating", handler: o },
376
+ { event: "object:modified", handler: d },
377
+ { event: "selection:cleared", handler: d },
378
+ { event: "mouse:up", handler: d }
379
+ ]), this;
380
+ }
381
+ /**
382
+ * 移除所有的事件监听
383
+ */
384
+ removeAllEventListeners() {
385
+ this.eventHandlers.forEach((t) => {
386
+ t.forEach((o) => {
387
+ ["keydown", "keyup"].includes(o.event) ? window.removeEventListener(o.event, o.handler) : this.editor.canvas.off(o.event, o.handler);
388
+ });
389
+ }), this.hammerCanvas && (this.hammerCanvas.destroy(), this.hammerCanvas = null);
390
+ }
391
+ /**
392
+ * 右键点击识别选中元素
393
+ */
394
+ enableRightClick() {
395
+ const t = (o) => {
396
+ if (o.button === 3)
397
+ if (o.target) {
398
+ if (this.editor.canvas.getActiveObjects().includes(o.target))
399
+ return;
400
+ this.editor.canvas.setActiveObject(o.target), this.editor.canvas.requestRenderAll();
401
+ } else
402
+ this.editor.canvas.discardActiveObject(), this.editor.canvas.requestRenderAll();
403
+ };
404
+ return this.editor.canvas.on("mouse:down", t), this.eventHandlers.set("rightClick", [{ event: "mouse:down", handler: t }]), this;
405
+ }
406
+ }
407
+ export {
408
+ V as EventManager,
409
+ V as default
410
+ };
@@ -0,0 +1,24 @@
1
+ import { fabric } from 'fabric';
2
+ import type { RenderableBox } from '../types';
3
+ export interface ResizeEditor {
4
+ canvas: fabric.Canvas;
5
+ workspaceManager: {
6
+ workspace?: fabric.Object;
7
+ dimension: RenderableBox;
8
+ };
9
+ }
10
+ /** Keeps the Fabric canvas, overlay and printable workspace in sync with its host element. */
11
+ export declare class ResizeManager {
12
+ private readonly editor;
13
+ private readonly resizeObserver;
14
+ constructor(editor: ResizeEditor, target: HTMLDivElement);
15
+ private resizeCanvasBackground;
16
+ resizeWorkspace(): void;
17
+ resizeObjects(previousWorkspace: {
18
+ width: number;
19
+ height: number;
20
+ left: number;
21
+ top: number;
22
+ }): void;
23
+ destroy(): void;
24
+ }
@@ -0,0 +1,63 @@
1
+ import { fabric as c } from "fabric";
2
+ import { debounce as M } from "lodash-es";
3
+ import { designerEventBus as T } from "../events.js";
4
+ class S {
5
+ constructor(t, e) {
6
+ this.editor = t;
7
+ const r = (a) => {
8
+ const { width: s, height: n } = a[0].contentRect;
9
+ if (s === this.editor.canvas.width || !this.editor.workspaceManager.workspace) return;
10
+ const h = this.editor.workspaceManager.dimension;
11
+ this.editor.canvas.setDimensions({ width: s, height: n }), this.resizeCanvasBackground({ width: s, height: n }), this.resizeWorkspace(), this.resizeObjects(h), this.editor.canvas.requestRenderAll();
12
+ };
13
+ this.resizeObserver = new ResizeObserver(M(r, 100)), this.resizeObserver.observe(e);
14
+ }
15
+ resizeCanvasBackground(t) {
16
+ const e = this.editor.canvas.overlayImage;
17
+ if (!e) return;
18
+ const r = window.innerWidth < 768 ? 0.9 : 0.85, a = Math.min(t.width, t.height) * r, s = Math.min(a / e.width, a / e.height);
19
+ s !== e.scaleX && (this.editor.canvas.setViewportTransform([1, 0, 0, 1, 0, 0]), T.emit("design:changeScale", s)), e.set({
20
+ scaleX: s,
21
+ scaleY: s,
22
+ left: (t.width - e.width * s) / 2,
23
+ top: (t.height - e.height * s) / 2
24
+ }), e.setCoords();
25
+ }
26
+ resizeWorkspace() {
27
+ const t = this.editor.canvas.clipPath;
28
+ if (!t) return;
29
+ const e = this.editor.canvas.overlayImage?.scaleX || 1, r = {
30
+ left: (this.editor.canvas.width - t.width * e) / 2,
31
+ top: (this.editor.canvas.height - t.height * e) / 2,
32
+ scaleX: e,
33
+ scaleY: e
34
+ };
35
+ this.editor.workspaceManager.workspace.set(r), this.editor.canvas.clipPath?.set(r), this.editor.canvas.renderAll();
36
+ }
37
+ resizeObjects(t) {
38
+ const { width: e, height: r, left: a, top: s } = this.editor.workspaceManager.dimension, n = e / t.width, h = r / t.height, p = /* @__PURE__ */ new Set();
39
+ this.editor.canvas.getObjects().forEach((i) => {
40
+ let l = i.left, f = i.top, o;
41
+ if (i.group) {
42
+ o = i.group;
43
+ const d = c.util.transformPoint(new c.Point(l, f), o.calcTransformMatrix());
44
+ l = d.x, f = d.y;
45
+ }
46
+ const z = (l - t.left) / t.width, X = (f - t.top) / t.height, g = a + z * e, w = s + X * r, v = i.scaleX || 1, m = i.scaleY || 1;
47
+ if (o) {
48
+ const d = c.util.invertTransform(o.calcTransformMatrix()), u = c.util.transformPoint(new c.Point(g, w), d);
49
+ i.set({ left: u.x, top: u.y, scaleX: v * n, scaleY: m * h }), p.add(o);
50
+ } else
51
+ i.set({ left: g, top: w, scaleX: v * n, scaleY: m * h });
52
+ i.setCoords();
53
+ }), p.forEach((i) => {
54
+ i.addWithUpdate(), i.setCoords();
55
+ });
56
+ }
57
+ destroy() {
58
+ this.resizeObserver.disconnect();
59
+ }
60
+ }
61
+ export {
62
+ S as ResizeManager
63
+ };
@@ -0,0 +1,70 @@
1
+ import type { fabric } from 'fabric';
2
+ import '../../fabric-types';
3
+ import type { RenderableBox, Size } from '../types';
4
+ interface LinePositions {
5
+ left: number;
6
+ right: number;
7
+ top: number;
8
+ bottom: number;
9
+ centerX: number;
10
+ centerY: number;
11
+ }
12
+ export interface BoundingPoints extends Size {
13
+ left: number;
14
+ top: number;
15
+ right: number;
16
+ bottom: number;
17
+ centerX: number;
18
+ centerY: number;
19
+ }
20
+ interface ObjectGuideLine {
21
+ pos: number;
22
+ start: number;
23
+ end: number;
24
+ }
25
+ /** Canvas-workspace and object-to-object alignment helpers. */
26
+ export declare class SnaplineManager {
27
+ horizontalLine: {
28
+ top: number[];
29
+ centerX: number[];
30
+ bottom: number[];
31
+ } | null;
32
+ verticalLine: {
33
+ left: number[];
34
+ centerY: number[];
35
+ right: number[];
36
+ } | null;
37
+ objectsVerticalLines: ObjectGuideLine[];
38
+ objectsHorizontalLines: ObjectGuideLine[];
39
+ snapThreshold: number;
40
+ snapThresholdForObject: number;
41
+ isSnapping: boolean;
42
+ snappedLineTypes: {
43
+ left: boolean;
44
+ top: boolean;
45
+ bottom: boolean;
46
+ right: boolean;
47
+ centerX: boolean;
48
+ centerY: boolean;
49
+ };
50
+ clearGuideLines(): void;
51
+ drawGuideLines(context: CanvasRenderingContext2D): void;
52
+ private drawAlignLine;
53
+ private drawObjectGuideLine;
54
+ showGuideLines(guidePositions: LinePositions): void;
55
+ snapToGuidelines(canvas: fabric.Canvas, object: fabric.Object, targetDimension: RenderableBox): void;
56
+ snapToObjectGuideLines(canvas: fabric.Canvas, object: fabric.Object): void;
57
+ private calcGuidePositions;
58
+ private calcObjectDimensions;
59
+ private generateGuideLines;
60
+ private checkSnapConditions;
61
+ checkSnapConditionsForAllObjects({ canvas, currentObject, currentObjectDimension, snap }: {
62
+ canvas: fabric.Canvas;
63
+ currentObject: fabric.Object;
64
+ currentObjectDimension: BoundingPoints;
65
+ snap?: boolean;
66
+ }): void;
67
+ private addVerticalObjectLines;
68
+ private addHorizontalObjectLines;
69
+ }
70
+ export {};