@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.
- package/README.md +146 -0
- package/dist/DesignerRuntimeContext.d.ts +3 -0
- package/dist/PrintineDesigner.d.ts +9 -0
- package/dist/api/client.d.ts +8 -0
- package/dist/api/client.js +82 -0
- package/dist/api/common-endpoints.d.ts +12 -0
- package/dist/api/design-endpoints.d.ts +18 -0
- package/dist/api/endpoints.d.ts +33 -0
- package/dist/api/endpoints.js +46 -0
- package/dist/api/files-endpoints.d.ts +1 -0
- package/dist/assets/icons/aspect_ratio.d.ts +3 -0
- package/dist/assets/icons/delete.d.ts +3 -0
- package/dist/assets/icons/fit_screen.d.ts +3 -0
- package/dist/assets/icons/index.d.ts +11 -0
- package/dist/assets/icons/loading_1.d.ts +3 -0
- package/dist/assets/icons/loading_2.d.ts +3 -0
- package/dist/assets/icons/loading_3.d.ts +3 -0
- package/dist/assets/icons/pan.d.ts +3 -0
- package/dist/assets/icons/setting.d.ts +3 -0
- package/dist/assets/icons/text_color.d.ts +3 -0
- package/dist/assets/icons/text_h.d.ts +3 -0
- package/dist/assets/icons/text_v.d.ts +3 -0
- package/dist/bundled-assets.d.ts +4 -0
- package/dist/components/add-design.d.ts +8 -0
- package/dist/components/assets-dialog.d.ts +21 -0
- package/dist/components/canvas-context-menu.d.ts +6 -0
- package/dist/components/color-picker/index.d.ts +10 -0
- package/dist/components/context.d.ts +24 -0
- package/dist/components/design.d.ts +9 -0
- package/dist/components/fonts.d.ts +26 -0
- package/dist/components/image-crop.d.ts +4 -0
- package/dist/components/image-edit.d.ts +1 -0
- package/dist/components/layout/aside.d.ts +3 -0
- package/dist/components/layout/bottom-nav/element-menu-sheet.d.ts +11 -0
- package/dist/components/layout/bottom-nav/element-sheet.d.ts +11 -0
- package/dist/components/layout/bottom-nav/index.d.ts +1 -0
- package/dist/components/layout/header.d.ts +5 -0
- package/dist/components/loading.d.ts +3 -0
- package/dist/components/menus/ai.d.ts +5 -0
- package/dist/components/menus/background.d.ts +6 -0
- package/dist/components/menus/clipart.d.ts +6 -0
- package/dist/components/menus/files.d.ts +7 -0
- package/dist/components/menus/image.d.ts +8 -0
- package/dist/components/menus/index.d.ts +13 -0
- package/dist/components/menus/layer.d.ts +5 -0
- package/dist/components/menus/product.d.ts +3 -0
- package/dist/components/menus/sca.d.ts +5 -0
- package/dist/components/menus/shapes.d.ts +6 -0
- package/dist/components/menus/templates.d.ts +6 -0
- package/dist/components/menus/text-effects.d.ts +5 -0
- package/dist/components/menus/text.d.ts +6 -0
- package/dist/components/placement-tab.d.ts +7 -0
- package/dist/components/preview/3d.d.ts +7 -0
- package/dist/components/preview/graphic.d.ts +7 -0
- package/dist/components/preview/index.d.ts +18 -0
- package/dist/components/preview/open.d.ts +7 -0
- package/dist/components/preview/real-time/3d.d.ts +12 -0
- package/dist/components/preview/real-time/graphic.d.ts +18 -0
- package/dist/components/preview/real-time/index.d.ts +11 -0
- package/dist/components/scale-tools.d.ts +7 -0
- package/dist/components/semi-deisgn-config.d.ts +13 -0
- package/dist/components/semi-design-link.d.ts +9 -0
- package/dist/components/store.d.ts +1 -0
- package/dist/components/toolbar.d.ts +2 -0
- package/dist/config-D2qm60gf.js +16 -0
- package/dist/contracts/api-design.d.ts +176 -0
- package/dist/contracts/design.d.ts +86 -0
- package/dist/design-7zRpRtv9.js +20331 -0
- package/dist/engine/canvas-designer.d.ts +101 -0
- package/dist/engine/canvas-designer.js +313 -0
- package/dist/engine/constants.d.ts +27 -0
- package/dist/engine/constants.js +148 -0
- package/dist/engine/editor.d.ts +186 -0
- package/dist/engine/editor.js +734 -0
- package/dist/engine/events.d.ts +34 -0
- package/dist/engine/events.js +7 -0
- package/dist/engine/extensions/curved-text.d.ts +59 -0
- package/dist/engine/fabric.d.ts +4 -0
- package/dist/engine/fabric.js +187 -0
- package/dist/engine/history.d.ts +27 -0
- package/dist/engine/history.js +56 -0
- package/dist/engine/managers/event.d.ts +101 -0
- package/dist/engine/managers/event.js +410 -0
- package/dist/engine/managers/resize.d.ts +24 -0
- package/dist/engine/managers/resize.js +63 -0
- package/dist/engine/managers/snapline.d.ts +70 -0
- package/dist/engine/managers/snapline.js +124 -0
- package/dist/engine/managers/workspace.d.ts +26 -0
- package/dist/engine/managers/workspace.js +53 -0
- package/dist/engine/processors/image.d.ts +88 -0
- package/dist/engine/processors/image.js +473 -0
- package/dist/engine/processors/template.d.ts +45 -0
- package/dist/engine/processors/template.js +314 -0
- package/dist/engine/processors/text.d.ts +74 -0
- package/dist/engine/processors/text.js +215 -0
- package/dist/engine/semi-export-editor.d.ts +199 -0
- package/dist/engine/types.d.ts +28 -0
- package/dist/engine/utils/common.d.ts +25 -0
- package/dist/engine/utils/common.js +68 -0
- package/dist/engine/utils/dialog.d.ts +25 -0
- package/dist/engine/utils/font.d.ts +5 -0
- package/dist/engine/utils/font.js +39 -0
- package/dist/engine/utils/image.d.ts +8 -0
- package/dist/engine/utils/image.js +50 -0
- package/dist/engine/utils/loading.d.ts +17 -0
- package/dist/engine/utils/loading.js +71 -0
- package/dist/engine/utils/measure.d.ts +6 -0
- package/dist/engine/utils/measure.js +6 -0
- package/dist/engine/utils/mockup.d.ts +59 -0
- package/dist/engine/utils/setting.d.ts +4 -0
- package/dist/engine/utils/setting.js +73 -0
- package/dist/fabric-types.d.ts +59 -0
- package/dist/full-designer.js +14 -0
- package/dist/hooks/pagination.d.ts +19 -0
- package/dist/hooks/use-adobe-express.d.ts +50 -0
- package/dist/hooks/use-before-unload.d.ts +1 -0
- package/dist/hooks/use-image-drop.d.ts +18 -0
- package/dist/hooks/use-oss-upload.d.ts +34 -0
- package/dist/hooks/use-screen.d.ts +1 -0
- package/dist/i18n/index.d.ts +12 -0
- package/dist/images/design/asset_empty.png +0 -0
- package/dist/images/design/design/background.svg +3 -0
- package/dist/images/design/design/color-picker.svg +15 -0
- package/dist/images/design/design/computer.svg +1 -0
- package/dist/images/design/design/copy.svg +1 -0
- package/dist/images/design/design/image.svg +10 -0
- package/dist/images/design/design/line.svg +1 -0
- package/dist/images/design/design/text.svg +1 -0
- package/dist/images/design/design/title.svg +1 -0
- package/dist/images/design/empty.png +0 -0
- package/dist/images/design/layer_empty.png +0 -0
- package/dist/images/design/menu/ai.svg +1 -0
- package/dist/images/design/menu/back.svg +4 -0
- package/dist/images/design/menu/background.svg +6 -0
- package/dist/images/design/menu/clipart.svg +6 -0
- package/dist/images/design/menu/file.svg +4 -0
- package/dist/images/design/menu/fill.svg +1 -0
- package/dist/images/design/menu/image.svg +7 -0
- package/dist/images/design/menu/layer.svg +6 -0
- package/dist/images/design/menu/product.svg +3 -0
- package/dist/images/design/menu/sca.svg +5 -0
- package/dist/images/design/menu/shapes.svg +5 -0
- package/dist/images/design/menu/templates.svg +6 -0
- package/dist/images/design/menu/text.svg +6 -0
- package/dist/images/design/menu/uploads.svg +7 -0
- package/dist/images/design/spinner.svg +3 -0
- package/dist/images/design/spinners.svg +17 -0
- package/dist/images/design/transparent_pattern.svg +5 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +127 -0
- package/dist/lib/analytics.d.ts +17 -0
- package/dist/lib/cn.d.ts +3 -0
- package/dist/lib/common.d.ts +16 -0
- package/dist/lib/config.d.ts +14 -0
- package/dist/lib/navigation.d.ts +2 -0
- package/dist/renderer/ThreeDPreview.d.ts +14 -0
- package/dist/renderer/sticker.js +1731 -0
- package/dist/renderer/three-d-preview.js +32 -0
- package/dist/state/designer-store.d.ts +43 -0
- package/dist/state/designer-store.js +85 -0
- package/dist/style.css +1 -0
- package/dist/types.d.ts +184 -0
- package/dist/ui/accordion.d.ts +7 -0
- package/dist/ui/button-group.d.ts +11 -0
- package/dist/ui/button.d.ts +10 -0
- package/dist/ui/checkbox.d.ts +4 -0
- package/dist/ui/command.d.ts +18 -0
- package/dist/ui/confirm-dialog.d.ts +15 -0
- package/dist/ui/context-menu.d.ts +25 -0
- package/dist/ui/dialog.d.ts +15 -0
- package/dist/ui/drawer.d.ts +15 -0
- package/dist/ui/editable-combobox.d.ts +10 -0
- package/dist/ui/hint.d.ts +8 -0
- package/dist/ui/image.d.ts +24 -0
- package/dist/ui/input-group.d.ts +16 -0
- package/dist/ui/input-with-addon.d.ts +17 -0
- package/dist/ui/input.d.ts +3 -0
- package/dist/ui/label.d.ts +4 -0
- package/dist/ui/loading-button.d.ts +15 -0
- package/dist/ui/popover.d.ts +9 -0
- package/dist/ui/scroll-area.d.ts +5 -0
- package/dist/ui/select.d.ts +22 -0
- package/dist/ui/separator.d.ts +4 -0
- package/dist/ui/shared-loading-button.d.ts +20 -0
- package/dist/ui/simple-dialog.d.ts +19 -0
- package/dist/ui/simple-popover.d.ts +13 -0
- package/dist/ui/simple-select.d.ts +20 -0
- package/dist/ui/skeleton.d.ts +2 -0
- package/dist/ui/slider.d.ts +4 -0
- package/dist/ui/spinner-box.d.ts +12 -0
- package/dist/ui/spinner.d.ts +2 -0
- package/dist/ui/switch.d.ts +6 -0
- package/dist/ui/tab/index.d.ts +15 -0
- package/dist/ui/textarea.d.ts +3 -0
- package/dist/ui/tooltip.d.ts +7 -0
- package/dist/workers/image-resize.worker.d.ts +1 -0
- package/dist/workers/mockup.worker.d.ts +5 -0
- package/dist/workers/render.worker.d.ts +1 -0
- 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 {};
|