@8btc/whiteboard 0.0.17 → 0.0.19-beta.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/dist/index.js CHANGED
@@ -1,538 +1,422 @@
1
- var __defProp = Object.defineProperty;
2
- var __typeError = (msg) => {
3
- throw TypeError(msg);
1
+ var de = Object.defineProperty;
2
+ var Ht = (o) => {
3
+ throw TypeError(o);
4
4
  };
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
8
- var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
9
- var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
10
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
11
- var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
12
- var _core, _stage, _viewport, _handleWheel, _handlePointerDown, _handlePointerMove, _handlePointerUp, _handleDragStart, _handleDragMove, _handleDragEnd, _CanvasStage_instances, setupEventListeners_fn, _core2, _transformer, _handleTransformStart, _handleTransform, _handleTransformEnd, _handleDragStart2, _handleDragMove2, _handleDragEnd2, _CanvasTransformer_instances, setupEventListeners_fn2, _toolTypeChangeHandler, _RectNode_instances, setupEventHandlers_fn, _ImageNode_instances, loadImage_fn, _toolTypeChangeHandler2, setupEventHandlers_fn2, syncImageMarkers_fn, syncImageMarkersToState_fn, _rect, _markerGroup, _circle, _text, _handleViewportChange, _handleNodesSelected, _ImageMarkerNode_instances, changeVisulStyle_fn, setupEventHandlers_fn3, _canvasStage, _mainLayer, _canvasTransformer, _draftNode, _container, _handleKeyDown, _CanvasCore_instances, setupKeyboardEvents_fn;
13
- import { jsxs, jsx, Fragment } from "react/jsx-runtime";
14
- import { useState, useEffect, useRef } from "react";
15
- import Konva from "konva";
16
- import mitt from "mitt";
17
- import { v4 } from "uuid";
18
- import { Slot } from "@radix-ui/react-slot";
19
- import { cva } from "class-variance-authority";
20
- import { clsx } from "clsx";
21
- import { twMerge } from "tailwind-merge";
22
- import { Minus, Plus, Undo2, Redo2 } from "lucide-react";
23
- class CanvasStage {
24
- constructor(core, config) {
25
- __privateAdd(this, _CanvasStage_instances);
26
- __privateAdd(this, _core);
27
- __privateAdd(this, _stage);
28
- __privateAdd(this, _viewport, { x: 0, y: 0, scale: 1 });
5
+ var le = (o, s, t) => s in o ? de(o, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[s] = t;
6
+ var rt = (o, s, t) => le(o, typeof s != "symbol" ? s + "" : s, t), Dt = (o, s, t) => s.has(o) || Ht("Cannot " + t);
7
+ var e = (o, s, t) => (Dt(o, s, "read from private field"), t ? t.call(o) : s.get(o)), d = (o, s, t) => s.has(o) ? Ht("Cannot add the same private member more than once") : s instanceof WeakSet ? s.add(o) : s.set(o, t), l = (o, s, t, i) => (Dt(o, s, "write to private field"), i ? i.call(o, t) : s.set(o, t), t), C = (o, s, t) => (Dt(o, s, "access private method"), t);
8
+ import { jsxs as st, jsx as S, Fragment as ge } from "react/jsx-runtime";
9
+ import { useState as at, useEffect as Pt, useRef as me } from "react";
10
+ import D from "konva";
11
+ import ue from "mitt";
12
+ import { R as N, N as U, I as Q } from "./const-Das6lRi-.js";
13
+ import { v4 as ut } from "uuid";
14
+ import { Slot as fe } from "@radix-ui/react-slot";
15
+ import { cva as pe } from "class-variance-authority";
16
+ import { clsx as ye } from "clsx";
17
+ import { twMerge as xe } from "tailwind-merge";
18
+ import { Minus as we, Plus as ve, Undo2 as Ne, Redo2 as Se } from "lucide-react";
19
+ var y, u, W, ft, pt, yt, xt, wt, vt, Nt, St, Kt;
20
+ class _e {
21
+ constructor(s, t) {
22
+ d(this, St);
23
+ d(this, y);
24
+ d(this, u);
25
+ d(this, W, { x: 0, y: 0, scale: 1 });
29
26
  /**
30
27
  * 处理滚轮缩放和平移
31
28
  */
32
- __privateAdd(this, _handleWheel, (e) => {
33
- e.evt.preventDefault();
34
- const stage = __privateGet(this, _stage);
35
- const pointer = stage.getPointerPosition();
36
- if (!pointer) return;
37
- if (e.evt.ctrlKey) {
38
- const oldScale = __privateGet(this, _viewport).scale;
39
- const mousePointTo = {
40
- x: (pointer.x - __privateGet(this, _viewport).x) / oldScale,
41
- y: (pointer.y - __privateGet(this, _viewport).y) / oldScale
42
- };
43
- const scaleBy = 1.01;
44
- const direction = e.evt.deltaY > 0 ? -1 : 1;
45
- const steps = Math.min(Math.abs(e.evt.deltaY), 10);
46
- let newScale = oldScale;
47
- for (let i = 0; i < steps; i++) {
48
- newScale = direction > 0 ? newScale * scaleBy : newScale / scaleBy;
29
+ d(this, ft, (s) => {
30
+ s.evt.preventDefault();
31
+ const i = e(this, u).getPointerPosition();
32
+ if (i)
33
+ if (s.evt.ctrlKey) {
34
+ const n = e(this, W).scale, r = {
35
+ x: (i.x - e(this, W).x) / n,
36
+ y: (i.y - e(this, W).y) / n
37
+ }, a = 1.01, h = s.evt.deltaY > 0 ? -1 : 1, c = Math.min(Math.abs(s.evt.deltaY), 10);
38
+ let g = n;
39
+ for (let f = 0; f < c; f++)
40
+ g = h > 0 ? g * a : g / a;
41
+ const m = Math.max(0.1, Math.min(5, g)), p = {
42
+ x: i.x - r.x * m,
43
+ y: i.y - r.y * m
44
+ };
45
+ e(this, y)._updateViewport({ x: p.x, y: p.y, scale: m });
46
+ } else {
47
+ const n = s.evt.shiftKey ? s.evt.deltaY : s.evt.deltaX, r = s.evt.shiftKey ? 0 : s.evt.deltaY;
48
+ e(this, y)._updateViewport({
49
+ x: e(this, W).x - n,
50
+ y: e(this, W).y - r
51
+ });
49
52
  }
50
- const scale = Math.max(0.1, Math.min(5, newScale));
51
- const newPos = {
52
- x: pointer.x - mousePointTo.x * scale,
53
- y: pointer.y - mousePointTo.y * scale
54
- };
55
- __privateGet(this, _core).updateViewport({ x: newPos.x, y: newPos.y, scale });
56
- } else {
57
- const deltaX = e.evt.shiftKey ? e.evt.deltaY : e.evt.deltaX;
58
- const deltaY = e.evt.shiftKey ? 0 : e.evt.deltaY;
59
- __privateGet(this, _core).updateViewport({
60
- x: __privateGet(this, _viewport).x - deltaX,
61
- y: __privateGet(this, _viewport).y - deltaY
62
- });
63
- }
64
53
  });
65
- __privateAdd(this, _handlePointerDown, (event) => {
66
- const toolType = __privateGet(this, _core).getState().toolType;
67
- if (event.evt.button !== 0 || toolType === "hand") {
54
+ d(this, pt, (s) => {
55
+ const t = e(this, y).getState().toolType;
56
+ if (s.evt.button !== 0 || t === "hand")
68
57
  return;
69
- }
70
- const clickedOnEmpty = event.target === __privateGet(this, _stage);
71
- const pointerPos = __privateGet(this, _stage).getRelativePointerPosition();
72
- if (toolType === "select" && !clickedOnEmpty) {
73
- const nodeId = event.target.id();
74
- if (nodeId) {
75
- __privateGet(this, _core).selectNode(nodeId, event.evt.shiftKey);
58
+ const i = e(this, u).getRelativePointerPosition();
59
+ if (e(this, y)._setDrawingPosition(i || { x: 0, y: 0 }), t === "select")
60
+ if (s.target === e(this, u)) {
61
+ e(this, y)._selectNodes(), e(this, y)._createSelectRect();
62
+ return;
63
+ } else {
64
+ const r = s.target.id();
65
+ r && e(this, y)._selectNodes([r], s.evt.shiftKey);
66
+ return;
76
67
  }
77
- return;
78
- }
79
- if (toolType === "rectangle" && pointerPos) {
80
- __privateGet(this, _core).createDraftNode(toolType, pointerPos);
81
- }
82
- if (toolType === "image-marker" && pointerPos) {
83
- const imageShape = __privateGet(this, _core).findImageAtPosition(pointerPos);
84
- if (imageShape) {
85
- const width = imageShape.width();
86
- const height = imageShape.height();
87
- if (width && height) {
88
- const imageBounds = {
89
- x: imageShape.x(),
90
- y: imageShape.y(),
91
- width,
92
- height
68
+ if (t === "rectangle" && i && e(this, y)._createDraftNode(t), t === "image-marker" && i) {
69
+ const n = e(this, y)._findImageAtPosition(i);
70
+ if (n) {
71
+ const r = n.width(), a = n.height();
72
+ if (r && a) {
73
+ const h = {
74
+ x: n.x(),
75
+ y: n.y(),
76
+ width: r,
77
+ height: a
93
78
  };
94
- __privateGet(this, _core).createDraftNode(toolType, pointerPos, {
95
- parent: imageShape.id(),
96
- bounds: imageBounds,
97
- startPosition: pointerPos
79
+ e(this, y)._createDraftNode(t, {
80
+ $_parentId: n.id(),
81
+ $_bounds: h
98
82
  });
99
83
  }
100
84
  }
101
85
  }
102
- __privateGet(this, _core).selectNode();
86
+ e(this, y)._selectNodes();
103
87
  });
104
- __privateAdd(this, _handlePointerMove, () => {
105
- const toolType = __privateGet(this, _core).getState().toolType;
106
- if (toolType === "hand") {
88
+ d(this, yt, () => {
89
+ const s = e(this, y).getState().toolType;
90
+ if (s === "hand")
107
91
  return;
108
- }
109
- const pointerPos = __privateGet(this, _stage).getRelativePointerPosition();
110
- if ((toolType === "rectangle" || toolType === "image-marker") && pointerPos) {
111
- __privateGet(this, _core).updateDraftNode(pointerPos);
112
- }
113
- });
114
- __privateAdd(this, _handlePointerUp, () => {
115
- const toolType = __privateGet(this, _core).getState().toolType;
116
- if (toolType === "hand") {
92
+ const t = e(this, u).getRelativePointerPosition();
93
+ if (e(this, y)._updateDrawingPosition(t || { x: 0, y: 0 }), s === "select") {
94
+ e(this, y)._updateSelectRect();
117
95
  return;
118
96
  }
119
- if (toolType === "rectangle" || toolType === "image-marker") {
120
- __privateGet(this, _core).finalizeDraftNode();
121
- }
97
+ (s === "rectangle" || s === "image-marker") && e(this, y)._updateDraftNode();
122
98
  });
123
- __privateAdd(this, _handleDragStart, (event) => {
124
- if (event.target !== __privateGet(this, _stage)) {
125
- return;
126
- }
127
- const toolType = __privateGet(this, _core).getState().toolType;
128
- if (toolType === "hand") {
129
- this.setCursor("grabbing");
130
- } else if (toolType === "select") {
131
- this.setCursor("all-scroll");
99
+ d(this, xt, () => {
100
+ const s = e(this, y).getState().toolType;
101
+ if (s !== "hand") {
102
+ if (s === "select") {
103
+ e(this, y)._finalizeSelectRect();
104
+ return;
105
+ }
106
+ (s === "rectangle" || s === "image-marker") && e(this, y)._finalizeDraftNode();
132
107
  }
133
108
  });
134
- __privateAdd(this, _handleDragMove, (event) => {
135
- if (event.target !== __privateGet(this, _stage)) {
109
+ d(this, wt, (s) => {
110
+ if (s.target !== e(this, u))
136
111
  return;
137
- }
138
- __privateGet(this, _core).updateViewport({
139
- x: __privateGet(this, _stage).x(),
140
- y: __privateGet(this, _stage).y()
141
- });
112
+ const t = e(this, y).getState().toolType;
113
+ t === "hand" ? this.setCursor("grabbing") : t === "select" && this.setCursor("all-scroll");
142
114
  });
143
- __privateAdd(this, _handleDragEnd, (event) => {
144
- if (event.target !== __privateGet(this, _stage)) {
145
- return;
146
- }
147
- __privateGet(this, _core).updateViewport({
148
- x: __privateGet(this, _stage).x(),
149
- y: __privateGet(this, _stage).y()
115
+ d(this, vt, (s) => {
116
+ s.target === e(this, u) && e(this, y)._updateViewport({
117
+ x: e(this, u).x(),
118
+ y: e(this, u).y()
150
119
  });
151
- this.resetCursor();
152
120
  });
153
- __privateSet(this, _core, core);
154
- __privateSet(this, _stage, new Konva.Stage({
155
- container: config.container,
156
- width: config.width,
157
- height: config.height,
121
+ d(this, Nt, (s) => {
122
+ s.target === e(this, u) && (e(this, y)._updateViewport({
123
+ x: e(this, u).x(),
124
+ y: e(this, u).y()
125
+ }), this.resetCursor());
126
+ });
127
+ l(this, y, s), l(this, u, new D.Stage({
128
+ container: t.container,
129
+ width: t.width,
130
+ height: t.height,
158
131
  x: 0,
159
132
  y: 0,
160
133
  scaleX: 1,
161
134
  scaleY: 1,
162
- draggable: config.draggable ?? false,
163
- className: config.className
164
- }));
165
- __privateMethod(this, _CanvasStage_instances, setupEventListeners_fn).call(this);
135
+ draggable: t.draggable ?? !1,
136
+ className: t.className
137
+ })), C(this, St, Kt).call(this);
166
138
  }
167
139
  /**
168
140
  * 获取原生 Konva.Stage 实例
169
141
  */
170
142
  getStage() {
171
- return __privateGet(this, _stage);
143
+ return e(this, u);
172
144
  }
173
145
  /**
174
146
  * 获取当前视口状态
175
147
  */
176
148
  getViewport() {
177
- return { ...__privateGet(this, _viewport) };
149
+ return { ...e(this, W) };
178
150
  }
179
151
  /**
180
152
  * 设置视口(包括位置、缩放和尺寸)
181
153
  */
182
- setViewport(viewport) {
183
- const newViewport = { ...__privateGet(this, _viewport), ...viewport };
184
- __privateSet(this, _viewport, newViewport);
185
- if (viewport.x !== void 0) {
186
- __privateGet(this, _stage).x(viewport.x);
187
- }
188
- if (viewport.y !== void 0) {
189
- __privateGet(this, _stage).y(viewport.y);
190
- }
191
- if (viewport.scale !== void 0) {
192
- __privateGet(this, _stage).scaleX(viewport.scale);
193
- __privateGet(this, _stage).scaleY(viewport.scale);
194
- }
195
- if (viewport.width !== void 0) {
196
- __privateGet(this, _stage).width(viewport.width);
197
- }
198
- if (viewport.height !== void 0) {
199
- __privateGet(this, _stage).height(viewport.height);
200
- }
154
+ setViewport(s) {
155
+ const t = { ...e(this, W), ...s };
156
+ l(this, W, t), s.x !== void 0 && e(this, u).x(s.x), s.y !== void 0 && e(this, u).y(s.y), s.scale !== void 0 && (e(this, u).scaleX(s.scale), e(this, u).scaleY(s.scale)), s.width !== void 0 && e(this, u).width(s.width), s.height !== void 0 && e(this, u).height(s.height);
201
157
  }
202
158
  /**
203
159
  * 设置是否可拖拽
204
160
  */
205
- setDraggable(draggable) {
206
- __privateGet(this, _stage).draggable(draggable);
161
+ setDraggable(s) {
162
+ e(this, u).draggable(s);
207
163
  }
208
164
  /**
209
165
  * 设置光标样式
210
166
  */
211
- setCursor(cursor) {
212
- const container = __privateGet(this, _stage).container();
213
- container.style.cursor = cursor;
167
+ setCursor(s) {
168
+ const t = e(this, u).container();
169
+ t.style.cursor = s;
214
170
  }
215
171
  /**
216
172
  * 重置光标样式
217
173
  */
218
174
  resetCursor() {
219
- const container = __privateGet(this, _stage).container();
220
- const toolType = __privateGet(this, _core).getState().toolType;
221
- if (toolType === "hand") {
222
- container.style.cursor = "grab";
175
+ const s = e(this, u).container();
176
+ if (e(this, y).getState().toolType === "hand") {
177
+ s.style.cursor = "grab";
223
178
  return;
224
179
  }
225
- container.style.cursor = "default";
180
+ s.style.cursor = "default";
226
181
  }
227
182
  /**
228
183
  * 销毁 Stage
229
184
  */
230
185
  destroy() {
231
- __privateGet(this, _stage).destroy();
186
+ e(this, u).destroy();
232
187
  }
233
188
  }
234
- _core = new WeakMap();
235
- _stage = new WeakMap();
236
- _viewport = new WeakMap();
237
- _handleWheel = new WeakMap();
238
- _handlePointerDown = new WeakMap();
239
- _handlePointerMove = new WeakMap();
240
- _handlePointerUp = new WeakMap();
241
- _handleDragStart = new WeakMap();
242
- _handleDragMove = new WeakMap();
243
- _handleDragEnd = new WeakMap();
244
- _CanvasStage_instances = new WeakSet();
245
- /**
189
+ y = new WeakMap(), u = new WeakMap(), W = new WeakMap(), ft = new WeakMap(), pt = new WeakMap(), yt = new WeakMap(), xt = new WeakMap(), wt = new WeakMap(), vt = new WeakMap(), Nt = new WeakMap(), St = new WeakSet(), /**
246
190
  * 设置事件监听器
247
191
  */
248
- setupEventListeners_fn = function() {
249
- __privateGet(this, _stage).on("wheel", __privateGet(this, _handleWheel));
250
- __privateGet(this, _stage).on("pointerdown", __privateGet(this, _handlePointerDown));
251
- __privateGet(this, _stage).on("pointermove", __privateGet(this, _handlePointerMove));
252
- __privateGet(this, _stage).on("pointerup", __privateGet(this, _handlePointerUp));
253
- __privateGet(this, _stage).on("dragstart", __privateGet(this, _handleDragStart));
254
- __privateGet(this, _stage).on("dragmove", __privateGet(this, _handleDragMove));
255
- __privateGet(this, _stage).on("dragend", __privateGet(this, _handleDragEnd));
192
+ Kt = function() {
193
+ e(this, u).on("wheel", e(this, ft)), e(this, u).on("pointerdown", e(this, pt)), e(this, u).on("pointermove", e(this, yt)), e(this, u).on("pointerup", e(this, xt)), e(this, u).on("dragstart", e(this, wt)), e(this, u).on("dragmove", e(this, vt)), e(this, u).on("dragend", e(this, Nt));
256
194
  };
257
- class CanvasTransformer {
258
- constructor(core, config) {
259
- __privateAdd(this, _CanvasTransformer_instances);
260
- __privateAdd(this, _core2);
261
- __privateAdd(this, _transformer);
195
+ var ht, v, _t, bt, Mt, Ct, It, kt, Et, jt;
196
+ class be {
197
+ constructor(s, t) {
198
+ d(this, Et);
199
+ d(this, ht);
200
+ d(this, v);
262
201
  /**
263
202
  * 处理 transformstart 事件
264
203
  */
265
- __privateAdd(this, _handleTransformStart, () => {
204
+ d(this, _t, () => {
266
205
  this.emitPositionChange();
267
206
  });
268
207
  /**
269
208
  * 处理 transform 事件
270
209
  */
271
- __privateAdd(this, _handleTransform, () => {
210
+ d(this, bt, () => {
272
211
  this.emitPositionChange();
273
212
  });
274
213
  /**
275
214
  * 处理 transformend 事件
276
215
  */
277
- __privateAdd(this, _handleTransformEnd, () => {
216
+ d(this, Mt, () => {
278
217
  this.emitPositionChange();
279
218
  });
280
219
  /**
281
220
  * 处理 dragstart 事件
282
221
  */
283
- __privateAdd(this, _handleDragStart2, () => {
222
+ d(this, Ct, () => {
284
223
  this.emitPositionChange();
285
224
  });
286
225
  /**
287
226
  * 处理 dragmove 事件
288
227
  */
289
- __privateAdd(this, _handleDragMove2, () => {
228
+ d(this, It, () => {
290
229
  this.emitPositionChange();
291
230
  });
292
231
  /**
293
232
  * 处理 dragend 事件
294
233
  */
295
- __privateAdd(this, _handleDragEnd2, () => {
234
+ d(this, kt, () => {
296
235
  this.emitPositionChange();
297
236
  });
298
- __privateSet(this, _core2, core);
299
- __privateSet(this, _transformer, new Konva.Transformer({
300
- rotateEnabled: config?.rotateEnabled ?? true,
301
- ignoreStroke: config?.ignoreStroke ?? true,
302
- anchorSize: config?.anchorSize ?? 8,
303
- borderDash: config?.borderDash ?? [4, 4],
304
- anchorCornerRadius: config?.anchorCornerRadius ?? 4,
305
- padding: config?.padding ?? 6
306
- }));
307
- __privateMethod(this, _CanvasTransformer_instances, setupEventListeners_fn2).call(this);
237
+ l(this, ht, s), l(this, v, new D.Transformer({
238
+ rotateEnabled: t?.rotateEnabled ?? !0,
239
+ ignoreStroke: t?.ignoreStroke ?? !0,
240
+ anchorSize: t?.anchorSize ?? 8,
241
+ borderDash: t?.borderDash ?? [4, 4],
242
+ anchorCornerRadius: t?.anchorCornerRadius ?? 4,
243
+ padding: t?.padding ?? 6,
244
+ shouldOverdrawWholeArea: !0
245
+ })), C(this, Et, jt).call(this);
308
246
  }
309
247
  /**
310
248
  * 获取原生 Konva.Transformer 实例
311
249
  */
312
250
  getTransformer() {
313
- return __privateGet(this, _transformer);
251
+ return e(this, v);
314
252
  }
315
253
  /**
316
254
  * 获取 Transformer 的位置信息
317
255
  */
318
256
  getPosition() {
319
- const nodes = __privateGet(this, _transformer).nodes();
320
- if (nodes.length === 0) {
257
+ if (e(this, v).nodes().length === 0)
321
258
  return null;
322
- }
323
- const box = __privateGet(this, _transformer).getClientRect();
259
+ const t = e(this, v).getClientRect();
324
260
  return {
325
- x: box.x,
326
- y: box.y,
327
- width: box.width,
328
- height: box.height,
329
- rotation: __privateGet(this, _transformer).rotation()
261
+ x: t.x,
262
+ y: t.y,
263
+ width: t.width,
264
+ height: t.height,
265
+ rotation: e(this, v).rotation()
330
266
  };
331
267
  }
332
268
  /**
333
269
  * 设置要变换的节点
334
270
  */
335
- setNodes(nodes) {
336
- if (nodes.length === 0) {
271
+ setNodes(s) {
272
+ if (s.length === 0) {
337
273
  this.clearNodes();
338
274
  return;
339
275
  }
340
- __privateGet(this, _transformer).nodes(nodes);
341
- __privateGet(this, _transformer).moveToTop();
342
- this.emitPositionChange();
276
+ e(this, v).nodes(s), e(this, v).moveToTop(), this.emitPositionChange();
343
277
  }
344
278
  /**
345
279
  * 获取当前变换的节点
346
280
  */
347
281
  getNodes() {
348
- return __privateGet(this, _transformer).nodes();
282
+ return e(this, v).nodes();
349
283
  }
350
284
  /**
351
285
  * 清除所有节点
352
286
  */
353
287
  clearNodes() {
354
- __privateGet(this, _transformer).nodes([]);
355
- __privateGet(this, _transformer).moveToBottom();
356
- this.emitPositionChange();
288
+ e(this, v).nodes([]), e(this, v).moveToBottom(), this.emitPositionChange();
357
289
  }
358
290
  /**
359
291
  * emit Transformer 位置
360
292
  */
361
293
  emitPositionChange() {
362
- const position = this.getPosition();
363
- __privateGet(this, _core2).emitEvent("transformer:positionChange", position);
294
+ const s = this.getPosition();
295
+ e(this, ht)._emit("transformer:positionChange", s);
364
296
  }
365
297
  /**
366
298
  * 销毁 Transformer
367
299
  */
368
300
  destroy() {
369
- __privateGet(this, _transformer).destroy();
301
+ e(this, v).destroy();
370
302
  }
371
303
  }
372
- _core2 = new WeakMap();
373
- _transformer = new WeakMap();
374
- _handleTransformStart = new WeakMap();
375
- _handleTransform = new WeakMap();
376
- _handleTransformEnd = new WeakMap();
377
- _handleDragStart2 = new WeakMap();
378
- _handleDragMove2 = new WeakMap();
379
- _handleDragEnd2 = new WeakMap();
380
- _CanvasTransformer_instances = new WeakSet();
381
- /**
304
+ ht = new WeakMap(), v = new WeakMap(), _t = new WeakMap(), bt = new WeakMap(), Mt = new WeakMap(), Ct = new WeakMap(), It = new WeakMap(), kt = new WeakMap(), Et = new WeakSet(), /**
382
305
  * 设置事件监听器
383
306
  */
384
- setupEventListeners_fn2 = function() {
385
- __privateGet(this, _transformer).on("transformstart", __privateGet(this, _handleTransformStart));
386
- __privateGet(this, _transformer).on("transform", __privateGet(this, _handleTransform));
387
- __privateGet(this, _transformer).on("transformend", __privateGet(this, _handleTransformEnd));
388
- __privateGet(this, _transformer).on("dragstart", __privateGet(this, _handleDragStart2));
389
- __privateGet(this, _transformer).on("dragmove", __privateGet(this, _handleDragMove2));
390
- __privateGet(this, _transformer).on("dragend", __privateGet(this, _handleDragEnd2));
307
+ jt = function() {
308
+ e(this, v).on("transformstart", e(this, _t)), e(this, v).on("transform", e(this, bt)), e(this, v).on("transformend", e(this, Mt)), e(this, v).on("dragstart", e(this, Ct)), e(this, v).on("dragmove", e(this, It)), e(this, v).on("dragend", e(this, kt));
391
309
  };
392
- class CanvasState {
393
- constructor(initialState) {
394
- __publicField(this, "_past", []);
395
- __publicField(this, "_present");
396
- __publicField(this, "_future", []);
397
- __publicField(this, "_emitter");
398
- this._present = initialState;
399
- this._emitter = mitt();
310
+ var E, $, z, T;
311
+ class Me {
312
+ // todo: 优化 selectedNodeIds 的存储和查询性能
313
+ // private _selectedNodeIds: Set<string> = new Set();
314
+ constructor(s) {
315
+ d(this, E, []);
316
+ d(this, $);
317
+ d(this, z, []);
318
+ d(this, T);
319
+ l(this, $, s), l(this, T, ue());
400
320
  }
401
321
  /**
402
322
  * 获取当前状态
403
323
  */
404
324
  getState() {
405
- return { ...this._present };
325
+ return { ...e(this, $) };
406
326
  }
407
327
  /**
408
328
  * 获取完整历史状态
409
329
  */
410
330
  getHistory() {
411
331
  return {
412
- past: [...this._past],
413
- present: { ...this._present },
414
- future: [...this._future]
332
+ past: [...e(this, E)],
333
+ present: { ...e(this, $) },
334
+ future: [...e(this, z)]
415
335
  };
416
336
  }
417
337
  /**
418
338
  * 是否可以撤销
419
339
  */
420
340
  canUndo() {
421
- return this._past.length > 0;
341
+ return e(this, E).length > 0;
422
342
  }
423
343
  /**
424
344
  * 是否可以重做
425
345
  */
426
346
  canRedo() {
427
- return this._future.length > 0;
347
+ return e(this, z).length > 0;
428
348
  }
429
349
  /**
430
350
  * 订阅状态事件
431
351
  */
432
- on(event, handler) {
433
- this._emitter.on(event, handler);
352
+ on(s, t) {
353
+ e(this, T).on(s, t);
434
354
  }
435
355
  /**
436
356
  * 取消订阅状态事件
437
357
  */
438
- off(event, handler) {
439
- this._emitter.off(event, handler);
358
+ off(s, t) {
359
+ e(this, T).off(s, t);
440
360
  }
441
361
  /**
362
+ * @internal
442
363
  * 发送事件
443
364
  */
444
- emit(event, data) {
445
- this._emitter.emit(event, data);
365
+ _emit(s, t) {
366
+ e(this, T).emit(s, t);
446
367
  }
447
368
  /**
448
369
  * 撤销操作
449
370
  */
450
371
  undo() {
451
- if (this._past.length === 0) return;
452
- const previous = this._past[this._past.length - 1];
453
- const newPast = this._past.slice(0, this._past.length - 1);
454
- this._past = newPast;
455
- this._future = [this._present, ...this._future];
456
- this._present = previous;
457
- this._syncState(previous);
458
- this._emitter.emit("state:undo", previous);
459
- this._emitter.emit("state:change", previous);
372
+ if (e(this, E).length === 0) return;
373
+ const s = e(this, E)[e(this, E).length - 1], t = e(this, E).slice(0, e(this, E).length - 1);
374
+ l(this, E, t), l(this, z, [e(this, $), ...e(this, z)]), l(this, $, s), this._renderCanvas(s), e(this, T).emit("state:undo", s), e(this, T).emit("state:change", s);
460
375
  }
461
376
  /**
462
377
  * 重做操作
463
378
  */
464
379
  redo() {
465
- if (this._future.length === 0) return;
466
- const next = this._future[0];
467
- const newFuture = this._future.slice(1);
468
- this._past = [...this._past, this._present];
469
- this._future = newFuture;
470
- this._present = next;
471
- this._syncState(next);
472
- this._emitter.emit("state:redo", next);
473
- this._emitter.emit("state:change", next);
380
+ if (e(this, z).length === 0) return;
381
+ const s = e(this, z)[0], t = e(this, z).slice(1);
382
+ l(this, E, [...e(this, E), e(this, $)]), l(this, z, t), l(this, $, s), this._renderCanvas(s), e(this, T).emit("state:redo", s), e(this, T).emit("state:change", s);
474
383
  }
475
384
  /**
476
385
  * 重置历史记录
477
386
  */
478
387
  resetHistory() {
479
- this._past = [];
480
- this._future = [];
481
- this._emitter.emit("state:reset", this._present);
482
- this._emitter.emit("state:change", this._present);
388
+ l(this, E, []), l(this, z, []), e(this, T).emit("state:reset", e(this, $)), e(this, T).emit("state:change", e(this, $));
483
389
  }
484
390
  /**
485
391
  * 更新状态
486
392
  * @param partial - 部分状态更新
487
393
  * @param addToHistory - 是否添加到历史记录
488
394
  */
489
- _updateState(partial, addToHistory = true) {
490
- const newState = { ...this._present, ...partial };
491
- if (addToHistory) {
492
- this._past = [...this._past, this._present];
493
- this._future = [];
494
- }
495
- this._present = newState;
496
- this._emitter.emit("state:change", newState);
497
- }
498
- /**
499
- * 同步状态到外部系统(由子类实现)
500
- * @param _state - 要同步的状态
501
- */
502
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
503
- _syncState(_state) {
395
+ _updateState(s, t) {
396
+ const i = { ...e(this, $), ...s };
397
+ t && (l(this, E, [...e(this, E), e(this, $)]), l(this, z, [])), l(this, $, i), e(this, T).emit("state:change", i);
504
398
  }
505
399
  /**
506
400
  * 清理资源
507
401
  */
508
402
  _dispose() {
509
- this._emitter.all.clear();
403
+ e(this, T).all.clear();
510
404
  }
511
405
  }
512
- const NODE_NAMES = {
513
- nodeRoot: "nodeRoot_intrinsic",
514
- selectable: "selectable_intrinsic",
515
- rect: "rect_intrinsic",
516
- image: "image_intrinsic",
517
- imageMarker: "image_marker_intrinsic"
518
- };
519
- const RECT = {
520
- CORNER_RADIUS: 6,
521
- MIN_SIZE: 10
522
- };
523
- const IMAGE = {
524
- MIN_SIZE: 10
525
- };
526
- class BaseCanvasNode {
527
- constructor(core, node, isDraft = false) {
528
- __publicField(this, "core");
529
- __publicField(this, "node");
530
- __publicField(this, "element");
531
- __publicField(this, "isDraft");
532
- this.core = core;
533
- this.node = node;
534
- this.isDraft = isDraft;
535
- this.element = this.createElement();
406
+ E = new WeakMap(), $ = new WeakMap(), z = new WeakMap(), T = new WeakMap();
407
+ class Ut {
408
+ constructor(s, t, i = !1) {
409
+ rt(this, "core");
410
+ rt(this, "config");
411
+ rt(this, "element");
412
+ rt(this, "isDraft");
413
+ this.core = s, this.config = t, this.isDraft = i, this.element = this.createElement(), this.element.setAttrs({ $$_canvasNode: this });
414
+ }
415
+ /**
416
+ * getID 获取节点 ID
417
+ */
418
+ getID() {
419
+ return this.config.id;
536
420
  }
537
421
  /**
538
422
  * 获取 Konva 元素
@@ -543,53 +427,48 @@ class BaseCanvasNode {
543
427
  /**
544
428
  * 获取节点数据
545
429
  */
546
- getNode() {
547
- return this.node;
430
+ getConfig() {
431
+ const s = { ...this.config };
432
+ return delete s.$$_canvasNode, structuredClone(s);
433
+ }
434
+ updateConfigBasedOnElement() {
435
+ const t = { ...this.getElement().getAttrs() };
436
+ delete t.$$_canvasNode, this.config = t;
548
437
  }
549
438
  }
550
- function getRectSize(rect) {
439
+ function Ce(o) {
551
440
  return {
552
- width: Math.max(RECT.MIN_SIZE, rect.width() * rect.scaleX()),
553
- height: Math.max(RECT.MIN_SIZE, rect.height() * rect.scaleY())
441
+ width: Math.max(N.MIN_SIZE, o.width() * o.scaleX()),
442
+ height: Math.max(N.MIN_SIZE, o.height() * o.scaleY())
554
443
  };
555
444
  }
556
- class RectNode extends BaseCanvasNode {
557
- constructor(core, node, isDraft = false) {
558
- super(core, node, isDraft);
559
- __privateAdd(this, _RectNode_instances);
560
- __privateAdd(this, _toolTypeChangeHandler, (toolType) => {
561
- const isSelect = toolType === "select";
562
- this.element.listening(isSelect);
445
+ var ct, $t, Jt;
446
+ class Ie extends Ut {
447
+ constructor(t, i, n = !1) {
448
+ super(t, i, n);
449
+ d(this, $t);
450
+ d(this, ct, (t) => {
451
+ const i = t === "select";
452
+ this.element.listening(i);
563
453
  });
564
- __privateMethod(this, _RectNode_instances, setupEventHandlers_fn).call(this, this.getElement());
454
+ C(this, $t, Jt).call(this, this.getElement());
565
455
  }
566
456
  createElement() {
567
- const width = Math.max(
568
- this.node.props.width ?? RECT.MIN_SIZE,
569
- RECT.MIN_SIZE
570
- );
571
- const height = Math.max(
572
- this.node.props.height ?? RECT.MIN_SIZE,
573
- RECT.MIN_SIZE
574
- );
575
- const config = {
576
- id: this.node.id,
577
- ...this.node.props,
578
- ...this.node.style,
579
- width,
580
- height,
581
- cornerRadius: RECT.CORNER_RADIUS,
582
- name: `${NODE_NAMES.nodeRoot} ${NODE_NAMES.selectable} ${NODE_NAMES.rect}`,
583
- draggable: true,
457
+ const t = Math.max(this.config.width ?? N.MIN_SIZE, N.MIN_SIZE), i = Math.max(this.config.height ?? N.MIN_SIZE, N.MIN_SIZE), n = {
584
458
  stroke: "black",
585
- strokeWidth: 2
586
- };
587
- const rect = new Konva.Rect(config);
588
- rect.setAttrs({
589
- width,
590
- height
591
- });
592
- return rect;
459
+ strokeWidth: 2,
460
+ ...this.config,
461
+ id: this.config.id,
462
+ width: t,
463
+ height: i,
464
+ cornerRadius: N.CORNER_RADIUS,
465
+ name: `${U.nodeRoot} ${U.selectable} ${U.rect}`,
466
+ draggable: !0
467
+ }, r = new D.Rect(n);
468
+ return r.setAttrs({
469
+ width: t,
470
+ height: i
471
+ }), r;
593
472
  }
594
473
  /**
595
474
  * 获取 Konva.Rect 实例
@@ -600,114 +479,71 @@ class RectNode extends BaseCanvasNode {
600
479
  /**
601
480
  * 更新节点数据
602
481
  */
603
- updateNode(node) {
604
- this.node = {
605
- ...this.node,
606
- ...node,
607
- props: {
608
- ...this.node.props,
609
- ...node.props
610
- },
611
- style: {
612
- ...this.node.style,
613
- ...node.style
614
- }
615
- };
616
- const rect = this.getElement();
617
- rect.x(this.node.props.x);
618
- rect.y(this.node.props.y);
619
- const width = Math.max(
620
- this.node.props.width ?? RECT.MIN_SIZE,
621
- RECT.MIN_SIZE
622
- );
623
- const height = Math.max(
624
- this.node.props.height ?? RECT.MIN_SIZE,
625
- RECT.MIN_SIZE
626
- );
627
- rect.width(width);
628
- rect.height(height);
482
+ updateNode(t) {
483
+ this.config = {
484
+ ...this.config,
485
+ ...t
486
+ }, this.getElement().setAttrs(t);
629
487
  }
630
488
  /**
631
489
  * 销毁
632
490
  */
633
491
  destroy() {
634
- this.core.off("toolType:change", __privateGet(this, _toolTypeChangeHandler));
635
- this.element.destroy();
492
+ this.core.off("toolType:change", e(this, ct)), this.element.destroy();
636
493
  }
637
494
  }
638
- _toolTypeChangeHandler = new WeakMap();
639
- _RectNode_instances = new WeakSet();
640
- /**
495
+ ct = new WeakMap(), $t = new WeakSet(), /**
641
496
  * 设置事件处理器
642
497
  */
643
- setupEventHandlers_fn = function(rect) {
644
- const element = rect;
645
- this.core.on("toolType:change", __privateGet(this, _toolTypeChangeHandler));
646
- element.on("transform", (event) => {
647
- const rect2 = event.target;
648
- const { width, height } = getRectSize(rect2);
649
- rect2.scale({ x: 1, y: 1 });
650
- rect2.width(width);
651
- rect2.height(height);
652
- });
653
- element.on("transformend", (event) => {
654
- const rect2 = event.target;
655
- const { width, height } = getRectSize(rect2);
656
- const newProps = {
657
- ...this.node.props,
658
- x: rect2.x(),
659
- y: rect2.y(),
660
- width,
661
- height,
662
- rotation: rect2.rotation()
663
- };
664
- this.node.props = newProps;
665
- this.core._syncNodeFromElement(this.node.id, {
666
- props: newProps
667
- });
668
- });
669
- element.on("dragend", (event) => {
670
- const rect2 = event.target;
671
- const newProps = {
672
- ...this.node.props,
673
- x: rect2.x(),
674
- y: rect2.y()
675
- };
676
- this.node.props = newProps;
677
- this.core._syncNodeFromElement(this.node.id, {
678
- props: newProps
679
- });
498
+ Jt = function(t) {
499
+ const i = t;
500
+ this.core.on("toolType:change", e(this, ct)), i.on("transform", (n) => {
501
+ const r = n.target, { width: a, height: h } = Ce(r);
502
+ r.scale({ x: 1, y: 1 }), r.width(a), r.height(h);
503
+ }), i.on("transformend", (n) => {
504
+ this.updateConfigBasedOnElement(), this.core._rebuildStateAfterNodeChange(this, !0);
505
+ }), i.on("dragend", (n) => {
506
+ this.updateConfigBasedOnElement(), this.core._rebuildStateAfterNodeChange(this, !0);
680
507
  });
681
508
  };
682
- class ImageNode extends BaseCanvasNode {
683
- constructor(core, node, isDraft = false) {
684
- super(core, node, isDraft);
685
- __privateAdd(this, _ImageNode_instances);
686
- __privateAdd(this, _toolTypeChangeHandler2, (toolType) => {
687
- const isSelect = toolType === "select";
688
- this.element.listening(isSelect);
509
+ var H, At, dt, lt, Qt, zt;
510
+ class ke extends Ut {
511
+ constructor(t, i, n = !1) {
512
+ super(t, i, n);
513
+ d(this, H);
514
+ d(this, dt, (t) => {
515
+ const i = t === "select";
516
+ this.element.listening(i);
517
+ });
518
+ d(this, lt, () => {
519
+ const t = this.getElement().getLayer();
520
+ if (!t) return;
521
+ const i = t.find(
522
+ (n) => n.hasName(this.config.id)
523
+ );
524
+ this.core._rebuildStateAfterNodeChange(
525
+ [
526
+ this,
527
+ ...i.map(
528
+ (n) => n.getAttr("$$_canvasNode")
529
+ )
530
+ ],
531
+ !0
532
+ );
689
533
  });
690
- __privateMethod(this, _ImageNode_instances, loadImage_fn).call(this);
691
- __privateMethod(this, _ImageNode_instances, setupEventHandlers_fn2).call(this, this.getElement());
534
+ C(this, H, At).call(this), C(this, H, Qt).call(this, this.getElement());
692
535
  }
693
536
  createElement() {
694
- const width = this.node.props.width || IMAGE.MIN_SIZE;
695
- const height = this.node.props.height || IMAGE.MIN_SIZE;
696
- const placeholder = document.createElement("canvas");
697
- placeholder.width = width;
698
- placeholder.height = height;
699
- const img = new Konva.Image({
700
- id: this.node.id,
701
- x: this.node.props.x,
702
- y: this.node.props.y,
703
- width,
704
- height,
705
- rotation: this.node.props.rotation || 0,
706
- name: `${NODE_NAMES.nodeRoot} ${NODE_NAMES.selectable} ${NODE_NAMES.image}`,
707
- draggable: true,
708
- image: placeholder
537
+ const t = this.config.width || Q.MIN_SIZE, i = this.config.height || Q.MIN_SIZE, n = document.createElement("canvas");
538
+ return n.width = t, n.height = i, new D.Image({
539
+ ...this.config,
540
+ id: this.config.id,
541
+ width: t,
542
+ height: i,
543
+ name: `${U.nodeRoot} ${U.selectable} ${U.image}`,
544
+ draggable: !0,
545
+ image: n
709
546
  });
710
- return img;
711
547
  }
712
548
  /**
713
549
  * 获取 Konva.Image 实例
@@ -718,271 +554,141 @@ class ImageNode extends BaseCanvasNode {
718
554
  /**
719
555
  * 更新节点数据
720
556
  */
721
- updateNode(node) {
722
- this.node = {
723
- ...this.node,
724
- ...node,
725
- props: {
726
- ...this.node.props,
727
- ...node.props
728
- },
729
- style: {
730
- ...this.node.style,
731
- ...node.style
732
- },
733
- meta: {
734
- ...this.node.meta,
735
- ...node.meta
736
- }
737
- };
738
- const img = this.getElement();
739
- img.x(this.node.props.x);
740
- img.y(this.node.props.y);
741
- if (this.node.props.width && this.node.props.height) {
742
- const width = Math.max(this.node.props.width, IMAGE.MIN_SIZE);
743
- const height = Math.max(this.node.props.height, IMAGE.MIN_SIZE);
744
- img.width(width);
745
- img.height(height);
746
- }
747
- if (this.node.props.rotation !== void 0) {
748
- img.rotation(this.node.props.rotation);
749
- }
750
- if (node.meta?.imageUrl && node.meta.imageUrl !== this.node.meta.imageUrl) {
751
- __privateMethod(this, _ImageNode_instances, loadImage_fn).call(this);
752
- }
557
+ updateNode(t) {
558
+ const i = this.config;
559
+ this.config = {
560
+ ...this.config,
561
+ ...t,
562
+ id: this.config.id
563
+ }, this.getElement().setAttrs(t), t.$_imageUrl && t.$_imageUrl !== i.$_imageUrl && C(this, H, At).call(this);
753
564
  }
754
565
  /**
755
566
  * 销毁
756
567
  */
757
568
  destroy() {
758
- this.core.off("toolType:change", __privateGet(this, _toolTypeChangeHandler2));
759
- this.element.destroy();
569
+ this.core.off("toolType:change", e(this, dt)), this.element.destroy();
570
+ }
571
+ getConfig() {
572
+ const t = { ...this.config };
573
+ return delete t.$$_canvasNode, delete t.image, structuredClone(t);
760
574
  }
761
575
  }
762
- _ImageNode_instances = new WeakSet();
763
- /**
576
+ H = new WeakSet(), /**
764
577
  * 加载图片
765
578
  */
766
- loadImage_fn = function() {
767
- const imageUrl = this.node.meta.imageUrl;
768
- if (!imageUrl) {
579
+ At = function() {
580
+ const t = this.config.$_imageUrl;
581
+ if (!t) {
769
582
  console.warn("Image URL is missing");
770
583
  return;
771
584
  }
772
- const img = new window.Image();
773
- img.crossOrigin = "anonymous";
774
- img.src = imageUrl;
775
- img.onload = () => {
776
- this.getElement().image(img);
777
- const width = this.node.props.width ?? img.width;
778
- const height = this.node.props.height ?? img.height;
779
- this.getElement().width(Math.max(width, IMAGE.MIN_SIZE));
780
- this.getElement().height(Math.max(height, IMAGE.MIN_SIZE));
781
- };
782
- img.onerror = () => {
783
- console.error("Failed to load image:", imageUrl);
585
+ const i = new window.Image();
586
+ i.crossOrigin = "anonymous", i.src = t, i.onload = () => {
587
+ this.getElement().image(i);
588
+ const n = this.config.width ?? i.width, r = this.config.height ?? i.height;
589
+ this.getElement().width(Math.max(n, Q.MIN_SIZE)), this.getElement().height(Math.max(r, Q.MIN_SIZE));
590
+ }, i.onerror = () => {
591
+ console.error("Failed to load image:", t);
784
592
  };
785
- };
786
- _toolTypeChangeHandler2 = new WeakMap();
787
- /**
593
+ }, dt = new WeakMap(), lt = new WeakMap(), /**
788
594
  * 设置事件处理器
789
595
  */
790
- setupEventHandlers_fn2 = function(img) {
791
- this.core.on("toolType:change", __privateGet(this, _toolTypeChangeHandler2));
792
- img.on("transform", (event) => {
793
- const img2 = event.target;
794
- const width = Math.max(IMAGE.MIN_SIZE, img2.width() * img2.scaleX());
795
- const height = Math.max(IMAGE.MIN_SIZE, img2.height() * img2.scaleY());
796
- img2.scale({ x: 1, y: 1 });
797
- img2.width(width);
798
- img2.height(height);
799
- __privateMethod(this, _ImageNode_instances, syncImageMarkers_fn).call(this);
800
- });
801
- img.on("transformend", (event) => {
802
- const img2 = event.target;
803
- const newProps = {
804
- ...this.node.props,
805
- x: img2.x(),
806
- y: img2.y(),
807
- width: img2.width(),
808
- height: img2.height(),
809
- rotation: img2.rotation()
810
- };
811
- this.node.props = newProps;
812
- this.core._syncNodeFromElement(this.node.id, {
813
- props: newProps
814
- });
815
- __privateMethod(this, _ImageNode_instances, syncImageMarkersToState_fn).call(this);
816
- });
817
- img.on("dragmove", () => {
818
- __privateMethod(this, _ImageNode_instances, syncImageMarkers_fn).call(this);
819
- });
820
- img.on("dragend", (event) => {
821
- const img2 = event.target;
822
- const newProps = {
823
- ...this.node.props,
824
- x: img2.x(),
825
- y: img2.y()
826
- };
827
- this.node.props = newProps;
828
- this.core._syncNodeFromElement(this.node.id, {
829
- props: newProps
830
- });
831
- __privateMethod(this, _ImageNode_instances, syncImageMarkersToState_fn).call(this);
596
+ Qt = function(t) {
597
+ this.core.on("toolType:change", e(this, dt)), t.on("transform", (i) => {
598
+ const n = i.target, r = Math.max(Q.MIN_SIZE, n.width() * n.scaleX()), a = Math.max(Q.MIN_SIZE, n.height() * n.scaleY());
599
+ n.scale({ x: 1, y: 1 }), n.width(r), n.height(a), C(this, H, zt).call(this);
600
+ }), t.on("transformend", (i) => {
601
+ this.updateConfigBasedOnElement(), e(this, lt).call(this);
602
+ }), t.on("dragmove", () => {
603
+ C(this, H, zt).call(this);
604
+ }), t.on("dragend", (i) => {
605
+ this.updateConfigBasedOnElement(), e(this, lt).call(this);
832
606
  });
833
- };
834
- /**
607
+ }, /**
835
608
  * 同步 image-marker 节点的位置(实时更新 Konva 元素)
836
609
  */
837
- syncImageMarkers_fn = function() {
838
- const img = this.getElement();
839
- const layer = img.getLayer();
840
- if (!layer) return;
841
- const imgX = img.x();
842
- const imgY = img.y();
843
- const imgWidth = img.width();
844
- const imgHeight = img.height();
845
- const imageMarkerElements = layer.find(
846
- (node) => node.hasName(this.node.id)
847
- );
848
- const nodes = this.core.getState().nodes || [];
849
- imageMarkerElements.forEach((nodeElement) => {
850
- const nodeData = nodes.find((n) => n.id === nodeElement.id());
851
- if (nodeData?.type === "image-marker" && nodeData.meta.relativePosition) {
852
- const { start, end } = nodeData.meta.relativePosition;
853
- const startX = imgX + start.percentX / 100 * imgWidth;
854
- const startY = imgY + start.percentY / 100 * imgHeight;
855
- const endX = imgX + end.percentX / 100 * imgWidth;
856
- const endY = imgY + end.percentY / 100 * imgHeight;
857
- const newX = Math.min(startX, endX);
858
- const newY = Math.min(startY, endY);
859
- const newWidth = Math.abs(endX - startX);
860
- const newHeight = Math.abs(endY - startY);
861
- nodeElement.position({ x: newX, y: newY });
862
- nodeElement.setAttrs({ width: newWidth, height: newHeight });
863
- const children = nodeElement.getChildren();
864
- children.forEach((child) => {
865
- if (child.getClassName() === "Rect") {
866
- child.setAttrs({ width: newWidth, height: newHeight });
867
- } else if (child.getClassName() === "Group") {
868
- child.setAttrs({ x: newWidth, y: newHeight });
869
- }
870
- });
610
+ zt = function() {
611
+ const t = this.getElement(), i = t.getLayer();
612
+ if (!i) return;
613
+ const n = t.x(), r = t.y(), a = t.width(), h = t.height(), c = i.find(
614
+ (m) => m.hasName(this.config.id)
615
+ ), g = this.core.getState().nodes || [];
616
+ c.forEach((m) => {
617
+ const p = g.find((f) => f.id === m.id());
618
+ if (p?.$_type === "image-marker" && p.$_relativeBox) {
619
+ const { start: f, end: x } = p.$_relativeBox, w = n + f.ratioX * a, b = r + f.ratioY * h, _ = n + x.ratioX * a, M = r + x.ratioY * h, Tt = Math.min(w, _), q = Math.min(b, M), G = Math.abs(_ - w), nt = Math.abs(M - b);
620
+ m.setAttrs({
621
+ x: Tt,
622
+ y: q,
623
+ width: G,
624
+ height: nt
625
+ }), m.getChildren().forEach((A) => {
626
+ A.getClassName() === "Rect" ? A.setAttrs({ width: G, height: nt }) : A.getClassName() === "Group" && A.setAttrs({ x: G, y: nt });
627
+ }), m.getAttr("$$_canvasNode")?.updateConfigBasedOnElement();
871
628
  }
872
629
  });
873
630
  };
874
- /**
875
- * 同步 image-marker 节点到状态
876
- */
877
- syncImageMarkersToState_fn = function() {
878
- const img = this.getElement();
879
- const layer = img.getLayer();
880
- if (!layer) return;
881
- const imageMarkerElements = layer.find(
882
- (node) => node.hasName(this.node.id)
883
- );
884
- imageMarkerElements.forEach((nodeElement) => {
885
- this.core._syncNodeFromElement(nodeElement.id(), {
886
- props: {
887
- x: nodeElement.x(),
888
- y: nodeElement.y(),
889
- width: nodeElement.width(),
890
- height: nodeElement.height()
891
- }
892
- });
893
- });
894
- };
895
- class ImageMarkerNode extends BaseCanvasNode {
896
- constructor(core, node, isDraft = false) {
897
- super(core, node, isDraft);
898
- __privateAdd(this, _ImageMarkerNode_instances);
899
- __privateAdd(this, _rect);
900
- __privateAdd(this, _markerGroup);
901
- __privateAdd(this, _circle);
902
- __privateAdd(this, _text);
903
- __privateAdd(this, _handleViewportChange);
904
- __privateAdd(this, _handleNodesSelected);
905
- const group = this.getElement();
906
- __privateSet(this, _rect, group.findOne(".rect"));
907
- __privateSet(this, _markerGroup, group.findOne(".marker-group"));
908
- __privateSet(this, _circle, __privateGet(this, _markerGroup).findOne("Circle"));
909
- __privateSet(this, _text, __privateGet(this, _markerGroup).findOne("Text"));
910
- __privateMethod(this, _ImageMarkerNode_instances, setupEventHandlers_fn3).call(this);
911
- __privateSet(this, _handleViewportChange, () => {
912
- __privateMethod(this, _ImageMarkerNode_instances, changeVisulStyle_fn).call(this);
913
- });
914
- this.core.on("viewport:scale:change", __privateGet(this, _handleViewportChange));
915
- __privateSet(this, _handleNodesSelected, (selectedIds) => {
916
- const isSelected = selectedIds.includes(this.node.id);
917
- this.setFocusState(isSelected);
918
- });
919
- this.core.on("nodes:selected", __privateGet(this, _handleNodesSelected));
631
+ var V, R, j, L, tt, et, it, te, ee;
632
+ class Ee extends Ut {
633
+ constructor(t, i, n = !1) {
634
+ super(t, i, n);
635
+ d(this, it);
636
+ d(this, V);
637
+ d(this, R);
638
+ d(this, j);
639
+ d(this, L);
640
+ d(this, tt);
641
+ d(this, et);
642
+ const r = this.getElement();
643
+ l(this, V, r.findOne(".rect")), l(this, R, r.findOne(".marker-group")), l(this, j, e(this, R).findOne("Circle")), l(this, L, e(this, R).findOne("Text")), C(this, it, ee).call(this), l(this, tt, () => {
644
+ C(this, it, te).call(this);
645
+ }), this.core.on("viewport:scale:change", e(this, tt)), l(this, et, (a) => {
646
+ const h = a.includes(this.config.id);
647
+ this.setFocusState(h);
648
+ }), this.core.on("nodes:selected", e(this, et));
920
649
  }
921
650
  createElement() {
922
- const width = Math.max(
923
- this.node.props.width ?? RECT.MIN_SIZE,
924
- RECT.MIN_SIZE
925
- );
926
- const height = Math.max(
927
- this.node.props.height ?? RECT.MIN_SIZE,
928
- RECT.MIN_SIZE
929
- );
930
- const group = new Konva.Group({
931
- id: this.node.id,
932
- name: `${NODE_NAMES.nodeRoot} ${NODE_NAMES.imageMarker} ${this.node.meta.parent}`,
933
- x: this.node.props.x,
934
- y: this.node.props.y,
935
- width,
936
- height
937
- });
938
- const stageScale = this.core.getStageScale();
939
- const rectStrokeWidth = 2 / stageScale;
940
- const rectDash = [5 / stageScale, 5 / stageScale];
941
- const rectCornerRadius = RECT.CORNER_RADIUS / stageScale;
942
- const rect = new Konva.Rect({
651
+ const t = Math.max(this.config.width ?? N.MIN_SIZE, N.MIN_SIZE), i = Math.max(this.config.height ?? N.MIN_SIZE, N.MIN_SIZE), n = new D.Group({
652
+ id: this.config.id,
653
+ name: `${U.nodeRoot} ${U.imageMarker} ${this.config.$_parentId}`,
654
+ x: this.config.x,
655
+ y: this.config.y,
656
+ width: t,
657
+ height: i
658
+ }), r = this.core.getStageScale(), a = 2 / r, h = [5 / r, 5 / r], c = N.CORNER_RADIUS / r, g = new D.Rect({
943
659
  name: "rect",
944
660
  x: 0,
945
661
  y: 0,
946
- width,
947
- height,
948
- stroke: "#3B82F6",
949
- strokeWidth: rectStrokeWidth,
950
- dash: rectDash,
662
+ width: t,
663
+ height: i,
664
+ stroke: "#F44336",
665
+ strokeWidth: a,
666
+ dash: h,
951
667
  fill: "transparent",
952
- cornerRadius: rectCornerRadius,
953
- listening: false
954
- });
955
- const markerGroup = new Konva.Group({
668
+ cornerRadius: c,
669
+ listening: !1
670
+ }), m = new D.Group({
956
671
  name: "marker-group",
957
- x: width,
958
- y: height,
959
- visible: this.isDraft ? false : true
960
- });
961
- const radius = 14 / stageScale;
962
- const strokeWidth = 3 / stageScale;
963
- const fontSize = 16 / stageScale;
964
- const circle = new Konva.Circle({
965
- radius,
966
- fill: "#3B82F6",
672
+ x: t,
673
+ y: i,
674
+ visible: !this.isDraft
675
+ }), p = 14 / r, f = 3 / r, x = 16 / r, w = new D.Circle({
676
+ radius: p,
677
+ fill: "#F44336",
967
678
  stroke: "white",
968
- strokeWidth
969
- });
970
- const text = new Konva.Text({
971
- x: -radius,
972
- y: -radius,
973
- width: radius * 2,
974
- height: radius * 2,
975
- text: String(this.node.meta.markerNumber || ""),
679
+ strokeWidth: f
680
+ }), b = new D.Text({
681
+ x: -p,
682
+ y: -p,
683
+ width: p * 2,
684
+ height: p * 2,
685
+ text: String(this.config.$_markerNumber || ""),
976
686
  align: "center",
977
687
  verticalAlign: "middle",
978
- fontSize,
688
+ fontSize: x,
979
689
  fill: "white"
980
690
  });
981
- markerGroup.add(circle);
982
- markerGroup.add(text);
983
- group.add(rect);
984
- group.add(markerGroup);
985
- return group;
691
+ return m.add(w), m.add(b), n.add(g), n.add(m), n;
986
692
  }
987
693
  /**
988
694
  * 获取 Konva.Group 实例
@@ -993,292 +699,183 @@ class ImageMarkerNode extends BaseCanvasNode {
993
699
  /**
994
700
  * 更新节点数据
995
701
  */
996
- updateNode(node) {
997
- this.node = {
998
- ...this.node,
999
- ...node,
1000
- props: {
1001
- ...this.node.props,
1002
- ...node.props
1003
- },
1004
- style: {
1005
- ...this.node.style,
1006
- ...node.style
1007
- },
1008
- meta: {
1009
- ...this.node.meta,
1010
- ...node.meta
1011
- }
702
+ updateNode(t) {
703
+ this.config = {
704
+ ...this.config,
705
+ ...t
1012
706
  };
1013
- const group = this.getElement();
1014
- group.x(this.node.props.x);
1015
- group.y(this.node.props.y);
1016
- const width = Math.max(
1017
- this.node.props.width ?? RECT.MIN_SIZE,
1018
- RECT.MIN_SIZE
1019
- );
1020
- const height = Math.max(
1021
- this.node.props.height ?? RECT.MIN_SIZE,
1022
- RECT.MIN_SIZE
1023
- );
1024
- group.width(width);
1025
- group.height(height);
1026
- __privateGet(this, _rect).width(width);
1027
- __privateGet(this, _rect).height(height);
1028
- __privateGet(this, _markerGroup).x(width);
1029
- __privateGet(this, _markerGroup).y(height);
1030
- if (node.style?.color) {
1031
- __privateGet(this, _rect).stroke(node.style.color);
1032
- }
1033
- if (node.meta?.markerNumber !== void 0) {
1034
- __privateGet(this, _text).text(String(node.meta.markerNumber));
1035
- }
707
+ const i = this.getElement();
708
+ i.x(this.config.x), i.y(this.config.y);
709
+ const n = Math.max(this.config.width ?? N.MIN_SIZE, N.MIN_SIZE), r = Math.max(this.config.height ?? N.MIN_SIZE, N.MIN_SIZE);
710
+ i.width(n), i.height(r), e(this, V).width(n), e(this, V).height(r), e(this, R).x(n), e(this, R).y(r), t.stroke && e(this, V).stroke(t.stroke), t.$_markerNumber !== void 0 && e(this, L).text(String(t.$_markerNumber));
1036
711
  }
1037
712
  /**
1038
713
  * 销毁
1039
714
  */
1040
715
  destroy() {
1041
- this.core.off("viewport:scale:change", __privateGet(this, _handleViewportChange));
1042
- this.core.off("nodes:selected", __privateGet(this, _handleNodesSelected));
1043
- this.element.destroy();
716
+ this.core.off("viewport:scale:change", e(this, tt)), this.core.off("nodes:selected", e(this, et)), this.element.destroy();
1044
717
  }
1045
718
  /**
1046
719
  * 更新焦点状态(hover 或 selected)
1047
720
  */
1048
- setFocusState(isFocus) {
1049
- const stageScale = this.core.getStageScale();
1050
- const strokeWidth = isFocus ? 4 / stageScale : 3 / stageScale;
1051
- const scale = isFocus ? 1.2 : 1;
1052
- __privateGet(this, _rect).strokeWidth(strokeWidth);
1053
- __privateGet(this, _circle).strokeWidth(strokeWidth);
1054
- __privateGet(this, _markerGroup).scaleX(scale);
1055
- __privateGet(this, _markerGroup).scaleY(scale);
721
+ setFocusState(t) {
722
+ const i = this.core.getStageScale(), n = t ? 4 / i : 3 / i, r = t ? 1.2 : 1;
723
+ e(this, V).strokeWidth(n), e(this, j).strokeWidth(n), e(this, R).scaleX(r), e(this, R).scaleY(r);
724
+ }
725
+ updateConfigBasedOnElement() {
726
+ const t = this.getElement();
727
+ this.config = {
728
+ ...this.config,
729
+ width: t.width(),
730
+ height: t.height(),
731
+ x: t.x(),
732
+ y: t.y()
733
+ };
1056
734
  }
1057
735
  }
1058
- _rect = new WeakMap();
1059
- _markerGroup = new WeakMap();
1060
- _circle = new WeakMap();
1061
- _text = new WeakMap();
1062
- _handleViewportChange = new WeakMap();
1063
- _handleNodesSelected = new WeakMap();
1064
- _ImageMarkerNode_instances = new WeakSet();
1065
- /**
736
+ V = new WeakMap(), R = new WeakMap(), j = new WeakMap(), L = new WeakMap(), tt = new WeakMap(), et = new WeakMap(), it = new WeakSet(), /**
1066
737
  * 更新标记点的缩放以保持视觉大小不变
1067
738
  */
1068
- changeVisulStyle_fn = function() {
1069
- const stageScale = this.core.getStageScale();
1070
- const radius = 14 / stageScale;
1071
- const strokeWidth = 3 / stageScale;
1072
- const fontSize = 16 / stageScale;
1073
- const rectStrokeWidth = 3 / stageScale;
1074
- const rectDash = [5 / stageScale, 5 / stageScale];
1075
- const rectCornerRadius = RECT.CORNER_RADIUS / stageScale;
1076
- __privateGet(this, _rect).strokeWidth(rectStrokeWidth);
1077
- __privateGet(this, _rect).dash(rectDash);
1078
- __privateGet(this, _rect).cornerRadius(rectCornerRadius);
1079
- __privateGet(this, _circle).radius(radius);
1080
- __privateGet(this, _circle).strokeWidth(strokeWidth);
1081
- __privateGet(this, _text).x(-radius);
1082
- __privateGet(this, _text).y(-radius);
1083
- __privateGet(this, _text).width(radius * 2);
1084
- __privateGet(this, _text).height(radius * 2);
1085
- __privateGet(this, _text).fontSize(fontSize);
1086
- };
1087
- /**
739
+ te = function() {
740
+ const t = this.core.getStageScale(), i = 14 / t, n = 3 / t, r = 16 / t, a = 3 / t, h = [5 / t, 5 / t], c = N.CORNER_RADIUS / t;
741
+ e(this, V).strokeWidth(a), e(this, V).dash(h), e(this, V).cornerRadius(c), e(this, j).radius(i), e(this, j).strokeWidth(n), e(this, L).x(-i), e(this, L).y(-i), e(this, L).width(i * 2), e(this, L).height(i * 2), e(this, L).fontSize(r);
742
+ }, /**
1088
743
  * 设置事件处理器
1089
744
  */
1090
- setupEventHandlers_fn3 = function() {
1091
- __privateGet(this, _markerGroup).on("pointerover", () => {
1092
- this.setFocusState(true);
1093
- this.core.setCursor("pointer");
1094
- });
1095
- __privateGet(this, _markerGroup).on("pointerout", () => {
1096
- const selectedIds = this.core.getState().selectedNodeIds || [];
1097
- const isSelected = selectedIds.includes(this.node.id);
1098
- this.setFocusState(isSelected);
1099
- this.core.resetCursor();
1100
- });
1101
- __privateGet(this, _markerGroup).on("pointerdown", () => {
1102
- this.core.selectNode(this.node.id);
1103
- });
1104
- __privateGet(this, _markerGroup).on("transform", () => {
745
+ ee = function() {
746
+ e(this, R).on("pointerover", () => {
747
+ this.setFocusState(!0), this.core._setCursor("pointer");
748
+ }), e(this, R).on("pointerout", () => {
749
+ const i = (this.core.getState().selectedNodeIds || []).includes(this.config.id);
750
+ this.setFocusState(i), this.core._resetCursor();
751
+ }), e(this, R).on("pointerdown", () => {
752
+ this.core._selectNodes([this.config.id]);
753
+ }), e(this, R).on("transform", () => {
1105
754
  console.log("image marker group on transform called");
1106
755
  });
1107
756
  };
1108
- function createCanvasNodeByType(core, type, config, isDraft = false) {
1109
- switch (type) {
757
+ function Gt(o, s, t, i = !1) {
758
+ switch (s) {
1110
759
  case "rectangle":
1111
- return new RectNode(core, config, isDraft);
760
+ return new Ie(o, t, i);
1112
761
  case "image":
1113
- return new ImageNode(core, config, isDraft);
762
+ return new ke(o, t, i);
1114
763
  case "image-marker":
1115
- return new ImageMarkerNode(core, config, isDraft);
764
+ return new Ee(o, t, i);
1116
765
  default:
1117
766
  return null;
1118
767
  }
1119
768
  }
1120
- function clamp(value, range) {
1121
- return Math.min(Math.max(value, range[0]), range[1]);
769
+ function Ft(o, s) {
770
+ return Math.min(Math.max(o, s[0]), s[1]);
1122
771
  }
1123
- const createNodeByType = (type, position, style, meta) => {
1124
- const baseNode = {
1125
- type,
1126
- id: v4(),
1127
- text: null,
1128
- style: {
1129
- opacity: 1,
1130
- line: "solid",
1131
- color: "black",
1132
- size: "medium",
1133
- animated: false
1134
- },
1135
- props: {
1136
- x: position.x,
1137
- y: position.y,
1138
- rotation: 0,
1139
- visible: true
1140
- },
1141
- meta: {
1142
- ...meta,
1143
- startPoint: position
1144
- }
1145
- };
1146
- if (type === "image-marker") {
1147
- return {
1148
- ...baseNode,
1149
- style: {
1150
- ...baseNode.style,
1151
- color: "#3B82F6"
1152
- }
1153
- };
1154
- }
1155
- return baseNode;
1156
- };
1157
- function updateNodeByType(node, position) {
1158
- let finalPosition = position;
1159
- if (node.type === "image-marker" && node.meta.bounds) {
1160
- const bounds = node.meta.bounds;
1161
- finalPosition = {
1162
- x: clamp(position.x, [bounds.x, bounds.x + bounds.width]),
1163
- y: clamp(position.y, [bounds.y, bounds.y + bounds.height])
772
+ const $e = (o, s, t) => ({
773
+ ...t,
774
+ $_type: o,
775
+ id: ut(),
776
+ x: s.x,
777
+ y: s.y
778
+ });
779
+ function Te(o, s, t) {
780
+ let i = s;
781
+ if (o.$_type === "image-marker" && o.$_bounds) {
782
+ const n = o.$_bounds;
783
+ i = {
784
+ x: Ft(s.x, [n.x, n.x + n.width]),
785
+ y: Ft(s.y, [n.y, n.y + n.height])
1164
786
  };
1165
787
  }
1166
- if (node.type === "rectangle" || node.type === "image-marker") {
1167
- const startPoint = node.meta.startPoint ?? {
1168
- x: node.props.x,
1169
- y: node.props.y
1170
- };
1171
- const [p1, p2] = normalizePoints(startPoint, finalPosition);
788
+ if (o.$_type === "rectangle" || o.$_type === "image-marker") {
789
+ const [n, r] = Yt(t, i);
1172
790
  return {
1173
- ...node,
1174
- props: {
1175
- ...node.props,
1176
- x: p1.x,
1177
- y: p1.y,
1178
- width: Math.max(p2.x - p1.x, RECT.MIN_SIZE),
1179
- height: Math.max(p2.y - p1.y, RECT.MIN_SIZE)
1180
- },
1181
- meta: {
1182
- ...node.meta,
1183
- // 保存初始起点,以便后续更新使用
1184
- startPoint
1185
- }
791
+ ...o,
792
+ x: n.x,
793
+ y: n.y,
794
+ width: Math.max(r.x - n.x, N.MIN_SIZE),
795
+ height: Math.max(r.y - n.y, N.MIN_SIZE)
1186
796
  };
1187
797
  }
1188
- return node;
798
+ return o;
1189
799
  }
1190
- function normalizePoints(p1, p2) {
1191
- let p1x = p1.x, p1y = p1.y, p2x = p2.x, p2y = p2.y, d;
1192
- if (p1x > p2x) {
1193
- d = Math.abs(p1x - p2x);
1194
- p1x = p2x;
1195
- p2x = p1x + d;
1196
- }
1197
- if (p1y > p2y) {
1198
- d = Math.abs(p1y - p2y);
1199
- p1y = p2y;
1200
- p2y = p1y + d;
1201
- }
1202
- return [
1203
- { x: p1x, y: p1y },
1204
- { x: p2x, y: p2y }
800
+ function Yt(o, s) {
801
+ let t = o.x, i = o.y, n = s.x, r = s.y, a;
802
+ return t > n && (a = Math.abs(t - n), t = n, n = t + a), i > r && (a = Math.abs(i - r), i = r, r = i + a), [
803
+ { x: t, y: i },
804
+ { x: n, y: r }
1205
805
  ];
1206
806
  }
1207
- class CanvasCore extends CanvasState {
1208
- constructor(el) {
1209
- super({
807
+ const Re = (o, s) => {
808
+ if (o.length !== s.length) return !1;
809
+ const t = new Set(o);
810
+ return s.every((i) => t.has(i));
811
+ };
812
+ var I, X, P, k, J, Y, O, B, gt, Z, se, Ot, Xt, ie;
813
+ class De extends Me {
814
+ constructor(t, i) {
815
+ const n = {
816
+ toolType: "select",
817
+ nodes: [],
818
+ ...i,
1210
819
  viewport: {
1211
820
  x: 0,
1212
821
  y: 0,
1213
- width: el.clientWidth,
1214
- height: el.clientHeight,
1215
- scale: 1
1216
- },
1217
- toolType: "select",
1218
- nodes: []
1219
- });
1220
- __privateAdd(this, _CanvasCore_instances);
1221
- __privateAdd(this, _canvasStage);
1222
- __privateAdd(this, _mainLayer);
1223
- __privateAdd(this, _canvasTransformer);
1224
- __privateAdd(this, _draftNode, null);
1225
- __privateAdd(this, _container);
1226
- __privateAdd(this, _handleKeyDown, (e) => {
1227
- if (e.key === "Delete" || e.key === "Backspace") {
1228
- e.preventDefault();
1229
- this.deleteSelectedNodes();
822
+ width: t.clientWidth,
823
+ height: t.clientHeight,
824
+ scale: 1,
825
+ ...i?.viewport
1230
826
  }
827
+ };
828
+ super(n);
829
+ d(this, Z);
830
+ d(this, I);
831
+ d(this, X);
832
+ d(this, P);
833
+ d(this, k, null);
834
+ d(this, J);
835
+ d(this, Y, null);
836
+ d(this, O, null);
837
+ /** 节点映射,方便快速查找 */
838
+ d(this, B, /* @__PURE__ */ new Map());
839
+ d(this, gt, (t) => {
840
+ (t.key === "Delete" || t.key === "Backspace") && (t.preventDefault(), this.deleteSelectedNodes());
1231
841
  });
1232
- __privateSet(this, _container, el);
1233
- __privateSet(this, _canvasStage, new CanvasStage(this, {
1234
- container: el,
1235
- width: el.clientWidth,
1236
- height: el.clientHeight,
1237
- draggable: false,
842
+ l(this, J, t), l(this, I, new _e(this, {
843
+ container: t,
844
+ width: t.clientWidth,
845
+ height: t.clientHeight,
846
+ draggable: !1,
1238
847
  className: "touch-none"
1239
- }));
1240
- __privateSet(this, _mainLayer, new Konva.Layer());
1241
- __privateSet(this, _canvasTransformer, new CanvasTransformer(this));
1242
- __privateGet(this, _canvasStage).getStage().add(__privateGet(this, _mainLayer));
1243
- __privateGet(this, _mainLayer).add(__privateGet(this, _canvasTransformer).getTransformer());
1244
- this.updateViewport(this.getState().viewport, false);
1245
- __privateMethod(this, _CanvasCore_instances, setupKeyboardEvents_fn).call(this);
848
+ })), l(this, X, new D.Layer()), l(this, P, new be(this)), e(this, I).getStage().add(e(this, X)), e(this, X).add(e(this, P).getTransformer()), this._renderCanvas(n), C(this, Z, se).call(this);
1246
849
  }
1247
850
  /**
1248
851
  * 获取 CanvasStage 实例
1249
852
  */
1250
853
  getCanvasStage() {
1251
- return __privateGet(this, _canvasStage);
854
+ return e(this, I);
1252
855
  }
1253
856
  /**
1254
857
  * 获取 CanvasTransformer 实例
1255
858
  */
1256
859
  getCanvasTransformer() {
1257
- return __privateGet(this, _canvasTransformer);
1258
- }
1259
- /**
1260
- * 发射事件(供内部类使用)
1261
- */
1262
- emitEvent(event, data) {
1263
- this.emit(event, data);
860
+ return e(this, P);
1264
861
  }
1265
862
  /**
1266
863
  * 获取 Konva.Stage 实例
1267
864
  */
1268
865
  getStage() {
1269
- return __privateGet(this, _canvasStage).getStage();
866
+ return e(this, I).getStage();
1270
867
  }
1271
868
  /**
1272
869
  * 获取 Stage 容器元素
1273
870
  */
1274
871
  getContainer() {
1275
- return __privateGet(this, _canvasStage).getStage().container();
872
+ return e(this, I).getStage().container();
1276
873
  }
1277
874
  /**
1278
875
  * 获取主图层
1279
876
  */
1280
877
  getMainLayer() {
1281
- return __privateGet(this, _mainLayer);
878
+ return e(this, X);
1282
879
  }
1283
880
  /**
1284
881
  * 获取当前工具类型
@@ -1289,283 +886,246 @@ class CanvasCore extends CanvasState {
1289
886
  /**
1290
887
  * 设置当前工具类型(内部使用)
1291
888
  */
1292
- setToolType(type) {
1293
- this.selectNode();
1294
- this._updateState(
889
+ setToolType(t) {
890
+ this._selectNodes(), this._updateState(
1295
891
  {
1296
- toolType: type
892
+ toolType: t
1297
893
  },
1298
- false
1299
- );
1300
- this.emit("toolType:change", type);
1301
- if (type === "hand") {
1302
- __privateGet(this, _canvasStage).setDraggable(true);
1303
- __privateGet(this, _canvasStage).setCursor("grab");
1304
- } else {
1305
- __privateGet(this, _canvasStage).setDraggable(false);
1306
- __privateGet(this, _canvasStage).resetCursor();
1307
- }
894
+ !1
895
+ ), this._emit("toolType:change", t), t === "hand" ? (e(this, I).setDraggable(!0), e(this, I).setCursor("grab")) : (e(this, I).setDraggable(!1), e(this, I).resetCursor());
896
+ }
897
+ /**
898
+ * 根据 ID 获取 Canvas 节点实例
899
+ */
900
+ getCanvasNodeById(t) {
901
+ return e(this, B).get(t) || null;
1308
902
  }
1309
903
  /**
1310
904
  * 设置是否可拖拽(内部使用)
1311
905
  */
1312
- setDraggable(draggable) {
1313
- __privateGet(this, _canvasStage).setDraggable(draggable);
906
+ setDraggable(t) {
907
+ e(this, I).setDraggable(t);
1314
908
  }
1315
909
  /**
1316
910
  * 设置光标
1317
911
  * @internal 仅供内部使用
1318
912
  */
1319
- setCursor(cursor) {
1320
- __privateGet(this, _canvasStage).setCursor(cursor);
913
+ _setCursor(t) {
914
+ e(this, I).setCursor(t);
1321
915
  }
1322
916
  /**
1323
917
  * 重置光标
1324
918
  * @internal 仅供内部使用
1325
919
  */
1326
- resetCursor() {
1327
- __privateGet(this, _canvasStage).resetCursor();
920
+ _resetCursor() {
921
+ e(this, I).resetCursor();
1328
922
  }
1329
923
  /**
1330
924
  * 获取当前 Stage 缩放比例
1331
925
  */
1332
926
  getStageScale() {
1333
- return __privateGet(this, _canvasStage).getStage().scaleX();
927
+ return e(this, I).getStage().scaleX();
1334
928
  }
1335
929
  /**
1336
930
  * 更新视口位置
1337
931
  * @internal 仅供内部使用,外部请使用 CanvasApi
1338
932
  */
1339
- updateViewport(viewport, addToHistory = false) {
1340
- __privateGet(this, _canvasStage).setViewport(viewport);
1341
- const oldViewport = this.getState().viewport;
1342
- const newViewport = {
1343
- ...oldViewport,
1344
- ...viewport
933
+ _updateViewport(t, i = !1) {
934
+ e(this, I).setViewport(t);
935
+ const n = this.getState().viewport, r = {
936
+ ...n,
937
+ ...t
1345
938
  };
1346
939
  this._updateState(
1347
940
  {
1348
- viewport: newViewport
941
+ viewport: r
1349
942
  },
1350
- addToHistory
1351
- );
1352
- this.emit("viewport:change", newViewport);
1353
- if (oldViewport.scale !== newViewport.scale) {
1354
- this.emit("viewport:scale:change", newViewport.scale);
1355
- }
1356
- __privateGet(this, _canvasTransformer).emitPositionChange();
943
+ i
944
+ ), this._emit("viewport:change", r), n.scale !== r.scale && this._emit("viewport:scale:change", r.scale), e(this, P).emitPositionChange();
1357
945
  }
1358
- createNodes(nodes) {
1359
- const canvasNodes = nodes.map((node) => createCanvasNodeByType(this, node.type, node, false)).filter((node) => node !== null);
1360
- canvasNodes.forEach((node) => {
1361
- __privateGet(this, _mainLayer).add(node.getElement());
1362
- });
1363
- const newNodes = [...this.getState().nodes || [], ...nodes];
1364
- this._updateState(
1365
- {
1366
- nodes: newNodes
1367
- },
1368
- true
1369
- );
1370
- this.emit("nodes:created", nodes);
946
+ createNodes(t, i) {
947
+ const n = t.map((r) => Gt(this, r.$_type, r, !1)).filter((r) => r !== null);
948
+ n.forEach((r) => {
949
+ e(this, X).add(r.getElement());
950
+ }), C(this, Z, Xt).call(this, n, i), this._emit("nodes:created", t);
1371
951
  }
1372
952
  /**
1373
953
  * 创建图片标注节点(内部使用)
1374
954
  */
1375
- createImageMarkerNode(parentImageId, startPosition, endPosition, imageBounds) {
1376
- const nodes = this.getState().nodes || [];
1377
- let maxMarkerNumber = 0;
1378
- nodes.forEach((node) => {
1379
- if (node.type === "image-marker" && node.meta.parent === parentImageId && typeof node.meta.markerNumber === "number") {
1380
- maxMarkerNumber = Math.max(maxMarkerNumber, node.meta.markerNumber);
1381
- }
955
+ createImageMarkerNode(t, i, n, r) {
956
+ const a = this.getState().nodes || [];
957
+ let h = 0;
958
+ a.forEach((M) => {
959
+ M.$_type === "image-marker" && M.$_parentId === t && typeof M.$_markerNumber == "number" && (h = Math.max(h, M.$_markerNumber));
1382
960
  });
1383
- const startPercentX = (startPosition.x - imageBounds.x) / imageBounds.width * 100;
1384
- const startPercentY = (startPosition.y - imageBounds.y) / imageBounds.height * 100;
1385
- const endPercentX = (endPosition.x - imageBounds.x) / imageBounds.width * 100;
1386
- const endPercentY = (endPosition.y - imageBounds.y) / imageBounds.height * 100;
1387
- const x = Math.min(startPosition.x, endPosition.x);
1388
- const y = Math.min(startPosition.y, endPosition.y);
1389
- const width = Math.abs(endPosition.x - startPosition.x);
1390
- const height = Math.abs(endPosition.y - startPosition.y);
1391
- const markerNode = {
1392
- id: v4(),
1393
- type: "image-marker",
1394
- props: {
1395
- x,
1396
- y,
1397
- width,
1398
- height,
1399
- rotation: 0,
1400
- visible: true
1401
- },
1402
- style: {
1403
- color: "#3B82F6",
1404
- line: "dashed",
1405
- size: "medium",
1406
- opacity: 1
1407
- },
1408
- meta: {
1409
- parent: parentImageId,
1410
- markerNumber: maxMarkerNumber + 1,
1411
- relativePosition: {
1412
- start: {
1413
- percentX: Math.max(0, Math.min(100, startPercentX)),
1414
- percentY: Math.max(0, Math.min(100, startPercentY))
1415
- },
1416
- end: {
1417
- percentX: Math.max(0, Math.min(100, endPercentX)),
1418
- percentY: Math.max(0, Math.min(100, endPercentY))
1419
- }
961
+ const c = (i.x - r.x) / r.width, g = (i.y - r.y) / r.height, m = (n.x - r.x) / r.width, p = (n.y - r.y) / r.height, f = Math.min(i.x, n.x), x = Math.min(i.y, n.y), w = Math.abs(n.x - i.x), b = Math.abs(n.y - i.y), _ = {
962
+ id: ut(),
963
+ $_type: "image-marker",
964
+ x: f,
965
+ y: x,
966
+ width: w,
967
+ height: b,
968
+ visible: !0,
969
+ line: "dashed",
970
+ $_parentId: t,
971
+ $_markerNumber: h + 1,
972
+ $_relativeBox: {
973
+ start: {
974
+ ratioX: Math.max(0, Math.min(1, c)),
975
+ ratioY: Math.max(0, Math.min(1, g))
976
+ },
977
+ end: {
978
+ ratioX: Math.max(0, Math.min(1, m)),
979
+ ratioY: Math.max(0, Math.min(1, p))
1420
980
  }
1421
981
  }
1422
982
  };
1423
- this.createNodes([markerNode]);
983
+ this.createNodes([_], !0);
1424
984
  }
1425
985
  /**
1426
986
  * 在指定位置查找图片节点
1427
987
  * @internal 仅供内部使用
1428
988
  */
1429
- findImageAtPosition(position) {
1430
- const layer = __privateGet(this, _mainLayer);
1431
- const shapes = layer.getChildren();
1432
- const filteredShapes = shapes.filter(
1433
- (shape) => !shape.name().includes("imageMarker")
1434
- );
1435
- const sortedShapes = filteredShapes.slice().sort((a, b) => b.zIndex() - a.zIndex());
1436
- for (const shape of sortedShapes) {
1437
- const x = shape.x();
1438
- const y = shape.y();
1439
- const width = shape.width();
1440
- const height = shape.height();
1441
- if (position.x >= x && position.x <= x + width && position.y >= y && position.y <= y + height) {
1442
- if (shape.getClassName() === "Image") {
1443
- return shape;
1444
- }
1445
- return null;
1446
- }
989
+ _findImageAtPosition(t) {
990
+ const a = e(this, X).getChildren().filter(
991
+ (h) => !h.name().includes("imageMarker")
992
+ ).slice().sort((h, c) => c.zIndex() - h.zIndex());
993
+ for (const h of a) {
994
+ const c = h.x(), g = h.y(), m = h.width(), p = h.height();
995
+ if (t.x >= c && t.x <= c + m && t.y >= g && t.y <= g + p)
996
+ return h.getClassName() === "Image" ? h : null;
1447
997
  }
1448
998
  return null;
1449
999
  }
1450
1000
  /**
1451
1001
  * @internal 仅供内部使用
1452
1002
  */
1453
- createDraftNode(type, position, meta) {
1454
- if (__privateGet(this, _draftNode)) {
1455
- __privateGet(this, _draftNode).destroy();
1456
- }
1457
- const node = createNodeByType(type, position, void 0, meta);
1458
- __privateSet(this, _draftNode, createCanvasNodeByType(this, type, node, true));
1459
- if (!__privateGet(this, _draftNode)) return;
1460
- __privateGet(this, _mainLayer).add(__privateGet(this, _draftNode).getElement());
1003
+ _setDrawingPosition(t) {
1004
+ l(this, O, [t, t]);
1461
1005
  }
1462
1006
  /**
1463
1007
  * @internal 仅供内部使用
1464
1008
  */
1465
- updateDraftNode(position) {
1466
- if (!__privateGet(this, _draftNode)) return;
1467
- const node = __privateGet(this, _draftNode).getNode();
1468
- const updatedNode = updateNodeByType(node, position);
1469
- __privateGet(this, _draftNode).updateNode(updatedNode);
1009
+ _updateDrawingPosition(t) {
1010
+ e(this, O) && (e(this, O)[1] = t);
1470
1011
  }
1471
1012
  /**
1472
1013
  * @internal 仅供内部使用
1473
1014
  */
1474
- finalizeDraftNode() {
1475
- if (!__privateGet(this, _draftNode)) return;
1476
- const id = v4();
1477
- const draftNode = __privateGet(this, _draftNode).getNode();
1478
- if (draftNode.type === "image-marker" && draftNode.meta.parent) {
1479
- const bounds = draftNode.meta.bounds;
1480
- const startPosition = draftNode.meta.startPosition;
1481
- const endPosition = {
1482
- x: draftNode.props.x + (draftNode.props.width || 0),
1483
- y: draftNode.props.y + (draftNode.props.height || 0)
1484
- };
1485
- const nodes = this.getState().nodes || [];
1486
- let maxMarkerNumber = 0;
1487
- nodes.forEach((node3) => {
1488
- if (node3.type === "image-marker" && node3.meta.parent === draftNode.meta.parent && typeof node3.meta.markerNumber === "number") {
1489
- maxMarkerNumber = Math.max(maxMarkerNumber, node3.meta.markerNumber);
1490
- }
1015
+ _createDraftNode(t, i) {
1016
+ e(this, k) && e(this, k).destroy();
1017
+ const n = $e(t, e(this, O)[0], i);
1018
+ l(this, k, Gt(this, t, n, !0)), e(this, k) && e(this, X).add(e(this, k).getElement());
1019
+ }
1020
+ /**
1021
+ * @internal 仅供内部使用
1022
+ */
1023
+ _updateDraftNode() {
1024
+ if (!e(this, k)) return;
1025
+ const t = e(this, k).getConfig(), i = Te(
1026
+ t,
1027
+ e(this, O)[1],
1028
+ e(this, O)[0]
1029
+ );
1030
+ e(this, k).updateNode(i);
1031
+ }
1032
+ /**
1033
+ * @internal 仅供内部使用
1034
+ */
1035
+ _finalizeDraftNode() {
1036
+ if (!e(this, k)) return;
1037
+ const t = ut(), i = e(this, k).getConfig();
1038
+ if (i.$_type === "image-marker" && i.$_parentId) {
1039
+ const r = i.$_bounds, a = e(this, O)[0], h = {
1040
+ x: i.x + (i.width || 0),
1041
+ y: i.y + (i.height || 0)
1042
+ }, [c, g] = Yt(a, h), m = this.getState().nodes || [];
1043
+ let p = 0;
1044
+ m.forEach((M) => {
1045
+ M.$_type === "image-marker" && M.$_parentId === i.$_parentId && typeof M.$_markerNumber == "number" && (p = Math.max(p, M.$_markerNumber));
1491
1046
  });
1492
- const startPercentX = (startPosition.x - bounds.x) / bounds.width * 100;
1493
- const startPercentY = (startPosition.y - bounds.y) / bounds.height * 100;
1494
- const endPercentX = (endPosition.x - bounds.x) / bounds.width * 100;
1495
- const endPercentY = (endPosition.y - bounds.y) / bounds.height * 100;
1496
- const node2 = {
1497
- ...draftNode,
1498
- props: {
1499
- ...draftNode.props
1500
- },
1501
- style: {
1502
- ...draftNode.style
1503
- },
1504
- meta: {
1505
- parent: draftNode.meta.parent,
1506
- markerNumber: maxMarkerNumber + 1,
1507
- relativePosition: {
1508
- start: {
1509
- percentX: Math.max(0, Math.min(100, startPercentX)),
1510
- percentY: Math.max(0, Math.min(100, startPercentY))
1511
- },
1512
- end: {
1513
- percentX: Math.max(0, Math.min(100, endPercentX)),
1514
- percentY: Math.max(0, Math.min(100, endPercentY))
1515
- }
1047
+ const f = (c.x - r.x) / r.width, x = (c.y - r.y) / r.height, w = (g.x - r.x) / r.width, b = (g.y - r.y) / r.height, _ = {
1048
+ ...i,
1049
+ $_markerNumber: p + 1,
1050
+ $_relativeBox: {
1051
+ start: {
1052
+ ratioX: Math.max(0, Math.min(1, f)),
1053
+ ratioY: Math.max(0, Math.min(1, x))
1054
+ },
1055
+ end: {
1056
+ ratioX: Math.max(0, Math.min(1, w)),
1057
+ ratioY: Math.max(0, Math.min(1, b))
1516
1058
  }
1517
1059
  },
1518
- id,
1519
- type: "image-marker"
1060
+ $_type: "image-marker",
1061
+ id: t
1520
1062
  };
1521
- this.createNodes([node2]);
1522
- __privateGet(this, _draftNode).destroy();
1523
- __privateSet(this, _draftNode, null);
1524
- this.setToolType("select");
1063
+ this.createNodes([_], !0), e(this, k).destroy(), l(this, k, null), this.setToolType("select");
1525
1064
  return;
1526
1065
  }
1527
- const node = {
1528
- ...draftNode,
1529
- props: {
1530
- ...draftNode.props
1531
- },
1532
- style: {
1533
- ...draftNode.style
1534
- },
1535
- meta: {
1536
- ...draftNode.meta
1537
- },
1538
- id
1066
+ const n = {
1067
+ ...i,
1068
+ id: t
1539
1069
  };
1540
- this.createNodes([node]);
1541
- __privateGet(this, _draftNode).destroy();
1542
- __privateSet(this, _draftNode, null);
1543
- this.setToolType("select");
1070
+ this.createNodes([n], !0), e(this, k).destroy(), l(this, k, null), this.setToolType("select");
1071
+ }
1072
+ /**
1073
+ * @internal 仅供内部使用
1074
+ */
1075
+ _createSelectRect() {
1076
+ e(this, Y) && e(this, Y).destroy(), l(this, Y, new D.Rect({
1077
+ x: e(this, O)[0].x,
1078
+ y: e(this, O)[0].y,
1079
+ width: 0,
1080
+ height: 0,
1081
+ stroke: "rgb(33, 150, 243)",
1082
+ strokeWidth: 1,
1083
+ fill: "rgba(33, 150, 243, 0.2)"
1084
+ })), e(this, X).add(e(this, Y));
1085
+ }
1086
+ /*
1087
+ * @internal 仅供内部使用
1088
+ */
1089
+ _updateSelectRect() {
1090
+ if (!e(this, Y)) return;
1091
+ const [t, i] = Yt(...e(this, O));
1092
+ e(this, Y).setAttrs({
1093
+ x: t.x,
1094
+ y: t.y,
1095
+ width: i.x - t.x,
1096
+ height: i.y - t.y
1097
+ });
1098
+ const n = e(this, Y).getClientRect(), a = e(this, X).find(`.${U.selectable}`).filter((h) => {
1099
+ const c = h.getClientRect();
1100
+ return D.Util.haveIntersection(n, c);
1101
+ });
1102
+ this._selectNodes(
1103
+ a.length > 0 ? a.map((h) => h.id()) : void 0,
1104
+ !1
1105
+ );
1106
+ }
1107
+ /**
1108
+ * @internal 仅供内部使用
1109
+ */
1110
+ _finalizeSelectRect() {
1111
+ e(this, Y) && (e(this, Y).destroy(), l(this, Y, null));
1544
1112
  }
1545
1113
  /**
1546
1114
  * 选择节点
1547
1115
  * @internal 仅供内部使用,外部请使用 CanvasApi
1548
1116
  */
1549
- selectNode(nodeId, multiSelect = false) {
1550
- const curSelectedNodeIds = this.getState().selectedNodeIds ?? [];
1551
- let selectedNodeIds = [];
1552
- if (nodeId) {
1553
- if (multiSelect && curSelectedNodeIds.length > 0) {
1554
- selectedNodeIds = [...curSelectedNodeIds, nodeId];
1555
- } else {
1556
- selectedNodeIds = [nodeId];
1117
+ _selectNodes(t, i = !1) {
1118
+ const n = this.getState().selectedNodeIds ?? [];
1119
+ let r = [];
1120
+ if (t?.length && (i && n.length > 0 ? r = [...n, ...t] : r = [...t]), !Re(n, r)) {
1121
+ if (r.length === 0)
1122
+ e(this, P).clearNodes();
1123
+ else {
1124
+ const a = this.getStage().find(`.${U.selectable}`).filter((h) => r.includes(h.id()));
1125
+ e(this, P).setNodes(a);
1557
1126
  }
1558
- } else if (curSelectedNodeIds.length === 0) {
1559
- return;
1560
- }
1561
- if (selectedNodeIds.length === 0) {
1562
- __privateGet(this, _canvasTransformer).clearNodes();
1563
- } else {
1564
- const nodes = this.getStage().find(`.${NODE_NAMES.selectable}`).filter((node) => selectedNodeIds.includes(node.id()));
1565
- __privateGet(this, _canvasTransformer).setNodes(nodes);
1127
+ this._updateState({ selectedNodeIds: r }, !1), this._emit("nodes:selected", r);
1566
1128
  }
1567
- this._updateState({ selectedNodeIds }, false);
1568
- this.emit("nodes:selected", selectedNodeIds);
1569
1129
  }
1570
1130
  /**
1571
1131
  * 删除指定的节点(内部使用)
@@ -1574,119 +1134,99 @@ class CanvasCore extends CanvasState {
1574
1134
  * @param nodeIds - 要删除的节点 ID 数组
1575
1135
  * @returns 被删除的节点数据数组
1576
1136
  */
1577
- deleteNodes(nodeIds) {
1578
- if (nodeIds.length === 0) return [];
1579
- const nodes = this.getState().nodes || [];
1580
- const idsToDelete = new Set(nodeIds);
1581
- nodeIds.forEach((id) => {
1582
- const node = nodes.find((n) => n.id === id);
1583
- if (node?.type === "image") {
1584
- nodes.forEach((n) => {
1585
- if (n.type === "image-marker" && n.meta.parent === id) {
1586
- idsToDelete.add(n.id);
1587
- }
1588
- });
1589
- }
1590
- });
1591
- const deletedNodes = nodes.filter((n) => idsToDelete.has(n.id));
1592
- idsToDelete.forEach((id) => {
1593
- const shape = this.getStage().findOne(`#${id}`);
1594
- if (shape) {
1595
- shape.destroy();
1596
- }
1137
+ deleteNodes(t) {
1138
+ if (t.length === 0) return [];
1139
+ const i = this.getState().nodes || [], n = new Set(t);
1140
+ t.forEach((a) => {
1141
+ i.find((c) => c.id === a)?.$_type === "image" && i.forEach((c) => {
1142
+ c.$_type === "image-marker" && c.$_parentId === a && n.add(c.id);
1143
+ });
1597
1144
  });
1598
- const newNodes = nodes.filter((n) => !idsToDelete.has(n.id));
1599
- __privateGet(this, _canvasTransformer).clearNodes();
1600
- this._updateState(
1145
+ const r = i.filter((a) => n.has(a.id));
1146
+ return n.forEach((a) => {
1147
+ const h = this.getStage().findOne(`#${a}`);
1148
+ h && h.destroy();
1149
+ }), C(this, Z, ie).call(this, Array.from(n), !0), e(this, P).clearNodes(), this._updateState(
1601
1150
  {
1602
- nodes: newNodes,
1603
1151
  selectedNodeIds: []
1604
1152
  },
1605
- true
1606
- );
1607
- this.emit("nodes:deleted", deletedNodes);
1608
- return deletedNodes;
1153
+ !0
1154
+ ), this._emit("nodes:deleted", r), r;
1609
1155
  }
1610
1156
  /**
1611
1157
  * 删除选中的节点(内部使用)
1612
1158
  * @internal 仅供内部使用,外部请使用 CanvasApi
1613
1159
  */
1614
1160
  deleteSelectedNodes() {
1615
- const selectedNodeIds = this.getState().selectedNodeIds || [];
1616
- if (selectedNodeIds.length === 0) return;
1617
- this.deleteNodes(selectedNodeIds);
1161
+ const t = this.getState().selectedNodeIds || [];
1162
+ t.length !== 0 && this.deleteNodes(t);
1618
1163
  }
1619
1164
  /**
1620
1165
  * 销毁 canvas
1621
1166
  */
1622
1167
  dispose() {
1623
- __privateGet(this, _container).removeEventListener("keydown", __privateGet(this, _handleKeyDown));
1624
- this.getCanvasTransformer().destroy();
1625
- this.getMainLayer().destroy();
1626
- this.getCanvasStage().destroy();
1627
- this._dispose();
1628
- }
1629
- /**
1630
- * 从元素同步节点数据(供节点类内部使用)
1631
- */
1632
- _syncNodeFromElement(nodeId, updates) {
1633
- const nodes = this.getState().nodes || [];
1634
- const nodeIndex = nodes.findIndex((n) => n.id === nodeId);
1635
- if (nodeIndex === -1) return;
1636
- const updatedNode = {
1637
- ...nodes[nodeIndex],
1638
- ...updates,
1639
- props: {
1640
- ...nodes[nodeIndex].props,
1641
- ...updates.props
1642
- },
1643
- style: {
1644
- ...nodes[nodeIndex].style,
1645
- ...updates.style
1646
- },
1647
- meta: {
1648
- ...nodes[nodeIndex].meta,
1649
- ...updates.meta
1650
- }
1651
- };
1652
- const newNodes = [...nodes];
1653
- newNodes[nodeIndex] = updatedNode;
1654
- this._updateState(
1655
- {
1656
- nodes: newNodes
1657
- },
1658
- true
1659
- );
1168
+ e(this, J).removeEventListener("keydown", e(this, gt)), this.getCanvasTransformer().destroy(), this.getMainLayer().destroy(), this.getCanvasStage().destroy(), this._dispose();
1169
+ }
1170
+ /**
1171
+ * @internal 仅供内部使用
1172
+ * 在元素节点改变后(例如 tranfromEnd dragEnd)重建 state.nodes
1173
+ */
1174
+ _rebuildStateAfterNodeChange(t, i) {
1175
+ C(this, Z, Xt).call(this, Array.isArray(t) ? t : [t], i);
1660
1176
  }
1661
1177
  /**
1662
1178
  * 实现父类的状态同步方法
1663
1179
  * 当 undo/redo 时被调用
1664
1180
  */
1665
- _syncState(state) {
1666
- __privateGet(this, _canvasStage).setViewport({
1667
- x: state.viewport.x,
1668
- y: state.viewport.y,
1669
- scale: state.viewport.scale,
1670
- width: state.viewport.width,
1671
- height: state.viewport.height
1672
- });
1181
+ _renderCanvas(t) {
1182
+ this._updateViewport(
1183
+ {
1184
+ x: t.viewport.x,
1185
+ y: t.viewport.y,
1186
+ scale: t.viewport.scale,
1187
+ width: t.viewport.width,
1188
+ height: t.viewport.height
1189
+ },
1190
+ !1
1191
+ ), e(this, B).forEach((n, r) => {
1192
+ n.destroy();
1193
+ }), e(this, B).clear(), this.createNodes(t.nodes || [], !1);
1194
+ const i = t.selectedNodeIds || [];
1195
+ if (i.length === 0)
1196
+ e(this, P).clearNodes();
1197
+ else {
1198
+ const n = this.getStage().find(`.${U.selectable}`).filter((r) => i.includes(r.id()));
1199
+ e(this, P).setNodes(n);
1200
+ }
1673
1201
  }
1674
1202
  }
1675
- _canvasStage = new WeakMap();
1676
- _mainLayer = new WeakMap();
1677
- _canvasTransformer = new WeakMap();
1678
- _draftNode = new WeakMap();
1679
- _container = new WeakMap();
1680
- _handleKeyDown = new WeakMap();
1681
- _CanvasCore_instances = new WeakSet();
1682
- /**
1203
+ I = new WeakMap(), X = new WeakMap(), P = new WeakMap(), k = new WeakMap(), J = new WeakMap(), Y = new WeakMap(), O = new WeakMap(), B = new WeakMap(), gt = new WeakMap(), Z = new WeakSet(), /**
1683
1204
  * 设置键盘事件监听
1684
1205
  */
1685
- setupKeyboardEvents_fn = function() {
1686
- __privateGet(this, _container).tabIndex = 0;
1687
- __privateGet(this, _container).addEventListener("keydown", __privateGet(this, _handleKeyDown));
1206
+ se = function() {
1207
+ e(this, J).tabIndex = 0, e(this, J).addEventListener("keydown", e(this, gt));
1208
+ }, /**
1209
+ * 根据canvas节点映射重建 state.nodes
1210
+ */
1211
+ Ot = function(t) {
1212
+ const i = {
1213
+ nodes: Array.from(e(this, B).values()).map((n) => n.getConfig())
1214
+ };
1215
+ this._updateState(i, t);
1216
+ }, /**
1217
+ * 更新 state.nodes
1218
+ */
1219
+ Xt = function(t, i) {
1220
+ t.forEach((n) => {
1221
+ e(this, B).set(n.getID(), n);
1222
+ }), t.length !== 0 && C(this, Z, Ot).call(this, i);
1223
+ }, ie = function(t, i = !1) {
1224
+ t.forEach((n) => {
1225
+ const r = e(this, B).get(n);
1226
+ r && r.destroy(), e(this, B).delete(n);
1227
+ }), t.length !== 0 && C(this, Z, Ot).call(this, i);
1688
1228
  };
1689
- class CanvasApi extends CanvasCore {
1229
+ class Ae extends De {
1690
1230
  /**
1691
1231
  * 获取所有可用的工具类型
1692
1232
  */
@@ -1696,76 +1236,57 @@ class CanvasApi extends CanvasCore {
1696
1236
  /**
1697
1237
  * 设置当前工具类型
1698
1238
  */
1699
- setToolType(type) {
1700
- super.setToolType(type);
1239
+ setToolType(s) {
1240
+ super.setToolType(s);
1701
1241
  }
1702
1242
  /**
1703
1243
  * 手动创建多个节点
1704
1244
  * 如果你不知道自己在干什么,请使用更高层的封装方法,如 createImageNode
1705
1245
  */
1706
- createNodes(nodes) {
1707
- super.createNodes(nodes);
1246
+ createNodes(s, t) {
1247
+ super.createNodes(s, t);
1708
1248
  }
1709
1249
  /**
1710
1250
  * 根据 ID 获取节点
1711
1251
  */
1712
- getNodeById(id) {
1713
- const nodes = this.getState().nodes || [];
1714
- const node = nodes.find((n) => n.id === id);
1715
- return node || null;
1252
+ getNodeById(s) {
1253
+ return (this.getState().nodes || []).find((n) => n.id === s) || null;
1716
1254
  }
1717
1255
  /**
1718
1256
  * 更新视口位置
1719
1257
  */
1720
- updateViewport(viewport, addToHistory = false) {
1721
- super.updateViewport(viewport, addToHistory);
1258
+ updateViewport(s, t = !1) {
1259
+ super._updateViewport(s, t);
1722
1260
  }
1723
1261
  /**
1724
1262
  * 创建图片节点
1725
1263
  */
1726
- createImageNode(imageUrl, position) {
1727
- const pos = position ?? { x: 100, y: 100 };
1728
- const imageNode = {
1729
- id: v4(),
1730
- type: "image",
1731
- props: {
1732
- x: pos.x,
1733
- y: pos.y,
1734
- width: void 0,
1735
- height: void 0,
1736
- rotation: 0,
1737
- visible: true
1738
- },
1739
- style: {
1740
- color: "#000000",
1741
- line: "solid",
1742
- size: "medium",
1743
- opacity: 1
1744
- },
1745
- meta: {
1746
- imageUrl
1747
- }
1264
+ createImageNode(s, t) {
1265
+ const i = t ?? { x: 100, y: 100 }, n = {
1266
+ id: ut(),
1267
+ $_type: "image",
1268
+ x: i.x,
1269
+ y: i.y,
1270
+ $_imageUrl: s
1748
1271
  };
1749
- this.createNodes([imageNode]);
1272
+ this.createNodes([n], !0);
1750
1273
  }
1751
1274
  /**
1752
1275
  * 导出全部图形为图片
1753
1276
  * @param options - 导出配置
1754
1277
  * @returns DataURL 格式的图片数据
1755
1278
  */
1756
- exportAsImage(options) {
1757
- const stage = this.getStage();
1758
- const transformer = this.getCanvasTransformer().getTransformer();
1759
- const transformerVisible = transformer.visible();
1760
- transformer.visible(false);
1279
+ exportAsImage(s) {
1280
+ const t = this.getStage(), i = this.getCanvasTransformer().getTransformer(), n = i.visible();
1281
+ i.visible(!1);
1761
1282
  try {
1762
- return stage.toDataURL({
1763
- pixelRatio: options?.pixelRatio ?? 2,
1764
- mimeType: options?.mimeType ?? "image/png",
1765
- quality: options?.quality ?? 1
1283
+ return t.toDataURL({
1284
+ pixelRatio: s?.pixelRatio ?? 2,
1285
+ mimeType: s?.mimeType ?? "image/png",
1286
+ quality: s?.quality ?? 1
1766
1287
  });
1767
1288
  } finally {
1768
- transformer.visible(transformerVisible);
1289
+ i.visible(n);
1769
1290
  }
1770
1291
  }
1771
1292
  /**
@@ -1773,107 +1294,75 @@ class CanvasApi extends CanvasCore {
1773
1294
  * @param options - 导出配置
1774
1295
  * @returns DataURL 格式的图片数据,如果没有选区则返回 null
1775
1296
  */
1776
- exportSelectionAsImage(options) {
1777
- const selectedNodeIds = this.getState().selectedNodeIds || [];
1778
- if (selectedNodeIds.length === 0) {
1779
- console.warn("No selection to export");
1780
- return null;
1781
- }
1782
- const padding = options?.padding ?? 0;
1783
- const tempGroup = new Konva.Group();
1784
- selectedNodeIds.forEach((id) => {
1785
- const shape = this.getStage().findOne(`#${id}`);
1786
- if (shape) {
1787
- const clone = shape.clone();
1788
- tempGroup.add(clone);
1297
+ exportSelectionAsImage(s) {
1298
+ const t = this.getState().selectedNodeIds || [];
1299
+ if (t.length === 0)
1300
+ return console.warn("No selection to export"), null;
1301
+ const i = s?.padding ?? 0, n = new D.Group();
1302
+ t.forEach((h) => {
1303
+ const c = this.getStage().findOne(`#${h}`);
1304
+ if (c) {
1305
+ const g = c.clone();
1306
+ n.add(g);
1789
1307
  }
1790
1308
  });
1791
- const box = tempGroup.getClientRect();
1792
- const dataURL = tempGroup.toDataURL({
1793
- x: box.x - padding,
1794
- y: box.y - padding,
1795
- width: box.width + padding * 2,
1796
- height: box.height + padding * 2,
1797
- pixelRatio: options?.pixelRatio ?? 2,
1798
- mimeType: options?.mimeType ?? "image/png",
1799
- quality: options?.quality ?? 1
1309
+ const r = n.getClientRect(), a = n.toDataURL({
1310
+ x: r.x - i,
1311
+ y: r.y - i,
1312
+ width: r.width + i * 2,
1313
+ height: r.height + i * 2,
1314
+ pixelRatio: s?.pixelRatio ?? 2,
1315
+ mimeType: s?.mimeType ?? "image/png",
1316
+ quality: s?.quality ?? 1
1800
1317
  });
1801
- tempGroup.destroy();
1802
- return dataURL;
1318
+ return n.destroy(), a;
1803
1319
  }
1804
1320
  /**
1805
1321
  * 导出带有标注的图片节点为图片
1806
1322
  * @param id - 图片节点 ID
1807
1323
  * @returns DataURL 格式的图片数据,如果节点或者 marker 不存在则返回 null
1808
1324
  */
1809
- exportImageWithMarker(id, options) {
1810
- const imageShape = this.getStage().findOne(`#${id}`);
1811
- if (!imageShape) {
1812
- console.warn("Image shape not found on stage");
1813
- return null;
1814
- }
1815
- const nodes = this.getState().nodes || [];
1816
- const markerNodes = nodes.filter(
1817
- (n) => n.type === "image-marker" && n.meta.parent === id
1325
+ exportImageWithMarker(s, t) {
1326
+ const i = this.getStage().findOne(`#${s}`);
1327
+ if (!i)
1328
+ return console.warn("Image shape not found on stage"), null;
1329
+ const r = (this.getState().nodes || []).filter(
1330
+ (m) => m.$_type === "image-marker" && m.$_parentId === s
1818
1331
  );
1819
- if (markerNodes.length === 0) {
1820
- console.warn("No image-marker nodes found for the given image ID");
1821
- return null;
1822
- }
1823
- const tempGroup = new Konva.Group();
1824
- const imageClone = imageShape.clone();
1825
- tempGroup.add(imageClone);
1826
- markerNodes.forEach((markerNode) => {
1827
- const markerShape = this.getStage().findOne(`#${markerNode.id}`);
1828
- if (markerShape) {
1829
- const markerClone = markerShape.clone();
1830
- const rect = markerClone.findOne(".rect");
1831
- const markerGroup = markerClone.findOne(".marker-group");
1832
- if (rect) {
1833
- rect.strokeWidth(3);
1834
- rect.dash([5, 5]);
1835
- rect.cornerRadius(6);
1836
- }
1837
- if (markerGroup) {
1838
- const circle = markerGroup.findOne("Circle");
1839
- const text = markerGroup.findOne("Text");
1840
- if (circle) {
1841
- circle.radius(14);
1842
- circle.strokeWidth(3);
1843
- }
1844
- if (text) {
1845
- const radius = 14;
1846
- text.x(-radius);
1847
- text.y(-radius);
1848
- text.width(radius * 2);
1849
- text.height(radius * 2);
1850
- text.fontSize(16);
1851
- }
1332
+ if (r.length === 0)
1333
+ return console.warn("No image-marker nodes found for the given image ID"), null;
1334
+ const a = new D.Group(), h = i.clone();
1335
+ a.add(h), r.forEach((m) => {
1336
+ const p = this.getStage().findOne(`#${m.id}`);
1337
+ if (p) {
1338
+ const f = p.clone(), x = f.findOne(".rect"), w = f.findOne(".marker-group");
1339
+ if (x && (x.strokeWidth(3), x.dash([5, 5]), x.cornerRadius(6)), w) {
1340
+ const b = w.findOne("Circle"), _ = w.findOne("Text");
1341
+ b && (b.radius(14), b.strokeWidth(3)), _ && (_.x(-14), _.y(-14), _.width(28), _.height(28), _.fontSize(16));
1852
1342
  }
1853
- tempGroup.add(markerClone);
1343
+ a.add(f);
1854
1344
  }
1855
1345
  });
1856
- const box = tempGroup.getClientRect();
1857
- console.log("Exporting image with markers, bounding box:", box);
1858
- const dataURL = tempGroup.toDataURL({
1859
- x: box.x,
1860
- y: box.y,
1861
- width: box.width,
1862
- height: box.height,
1863
- pixelRatio: options?.pixelRatio ?? 2,
1864
- mimeType: options?.mimeType ?? "image/png",
1865
- quality: options?.quality ?? 1
1346
+ const c = a.getClientRect();
1347
+ console.log("Exporting image with markers, bounding box:", c);
1348
+ const g = a.toDataURL({
1349
+ x: c.x,
1350
+ y: c.y,
1351
+ width: c.width,
1352
+ height: c.height,
1353
+ pixelRatio: t?.pixelRatio ?? 2,
1354
+ mimeType: t?.mimeType ?? "image/png",
1355
+ quality: t?.quality ?? 1
1866
1356
  });
1867
- tempGroup.destroy();
1868
- return dataURL;
1357
+ return a.destroy(), g;
1869
1358
  }
1870
1359
  /**
1871
1360
  * 删除当前选中的节点
1872
1361
  * 如果删除的是 image 节点,会同步删除所有关联的 image-marker
1873
1362
  */
1874
1363
  deleteSelectedNodes() {
1875
- const selectedNodeIds = this.getState().selectedNodeIds || [];
1876
- this.deleteNodes(selectedNodeIds);
1364
+ const s = this.getState().selectedNodeIds || [];
1365
+ this.deleteNodes(s);
1877
1366
  }
1878
1367
  /**
1879
1368
  * 删除指定的节点
@@ -1881,31 +1370,25 @@ class CanvasApi extends CanvasCore {
1881
1370
  * @param nodeIds - 要删除的节点 ID 数组
1882
1371
  * @returns 被删除的节点数据数组
1883
1372
  */
1884
- deleteNodes(nodeIds) {
1885
- return super.deleteNodes(nodeIds);
1373
+ deleteNodes(s) {
1374
+ return super.deleteNodes(s);
1886
1375
  }
1887
1376
  /**
1888
1377
  * 将节点移动到最上层
1889
1378
  */
1890
- moveNodesToTop(nodeIds) {
1891
- if (nodeIds.length === 0) return;
1892
- nodeIds.forEach((id) => {
1893
- const shape = this.getStage().findOne(`#${id}`);
1894
- if (shape) {
1895
- shape.moveToTop();
1896
- }
1379
+ moveNodesToTop(s) {
1380
+ s.length !== 0 && s.forEach((t) => {
1381
+ const i = this.getStage().findOne(`#${t}`);
1382
+ i && i.moveToTop();
1897
1383
  });
1898
1384
  }
1899
1385
  /**
1900
1386
  * 将节点移动到最下层
1901
1387
  */
1902
- moveNodesToBottom(nodeIds) {
1903
- if (nodeIds.length === 0) return;
1904
- nodeIds.forEach((id) => {
1905
- const shape = this.getStage().findOne(`#${id}`);
1906
- if (shape) {
1907
- shape.moveToBottom();
1908
- }
1388
+ moveNodesToBottom(s) {
1389
+ s.length !== 0 && s.forEach((t) => {
1390
+ const i = this.getStage().findOne(`#${t}`);
1391
+ i && i.moveToBottom();
1909
1392
  });
1910
1393
  }
1911
1394
  /**
@@ -1918,79 +1401,52 @@ class CanvasApi extends CanvasCore {
1918
1401
  * @param options.scale - 是否自动调整缩放以适应内容,默认 false
1919
1402
  * @param options.nodeIds - 要滚动到的节点 ID 数组
1920
1403
  */
1921
- scrollToContent(options) {
1922
- const nodes = this.getState().nodes || [];
1923
- if (nodes.length === 0) return;
1924
- const padding = options?.padding ?? 50;
1925
- const shouldScale = options?.scale === true;
1926
- const targetNodeIds = options?.nodeIds;
1927
- let minX = Infinity;
1928
- let minY = Infinity;
1929
- let maxX = -Infinity;
1930
- let maxY = -Infinity;
1931
- const mainLayer = this.getMainLayer();
1932
- const selectedNodeIds = this.getState().selectedNodeIds || [];
1933
- const hasTargetIds = targetNodeIds && targetNodeIds.length > 0;
1934
- const hasSelection = !hasTargetIds && selectedNodeIds.length > 0;
1935
- const idsToShow = hasTargetIds ? targetNodeIds : hasSelection ? selectedNodeIds : null;
1936
- mainLayer.children.forEach((child) => {
1937
- if (child.visible() && child.getClassName() !== "Transformer" && child.hasName(NODE_NAMES.selectable)) {
1938
- if (idsToShow) {
1939
- const id = child.id();
1940
- if (!idsToShow.includes(id)) return;
1941
- }
1942
- const attrs = child.getAttrs();
1943
- const x2 = attrs.x || 0;
1944
- const y2 = attrs.y || 0;
1945
- const width = attrs.width || 0;
1946
- const height = attrs.height || 0;
1947
- const rotation = attrs.rotation || 0;
1948
- if (rotation) {
1949
- const box = child.getClientRect({ skipTransform: false });
1950
- const stage = this.getStage();
1951
- const currentScale = stage.scaleX();
1952
- const currentX = stage.x();
1953
- const currentY = stage.y();
1954
- const worldMinX = (box.x - currentX) / currentScale;
1955
- const worldMinY = (box.y - currentY) / currentScale;
1956
- const worldMaxX = (box.x + box.width - currentX) / currentScale;
1957
- const worldMaxY = (box.y + box.height - currentY) / currentScale;
1958
- minX = Math.min(minX, worldMinX);
1959
- minY = Math.min(minY, worldMinY);
1960
- maxX = Math.max(maxX, worldMaxX);
1961
- maxY = Math.max(maxY, worldMaxY);
1962
- } else {
1963
- minX = Math.min(minX, x2);
1964
- minY = Math.min(minY, y2);
1965
- maxX = Math.max(maxX, x2 + width);
1966
- maxY = Math.max(maxY, y2 + height);
1404
+ scrollToContent(s) {
1405
+ if ((this.getState().nodes || []).length === 0) return;
1406
+ const i = s?.padding ?? 50, n = s?.scale === !0, r = s?.nodeIds;
1407
+ let a = 1 / 0, h = 1 / 0, c = -1 / 0, g = -1 / 0;
1408
+ const m = this.getMainLayer(), p = this.getState().selectedNodeIds || [], f = r && r.length > 0, x = !f && p.length > 0, w = f ? r : x ? p : null;
1409
+ if (m.children.forEach((A) => {
1410
+ if (A.visible() && A.getClassName() !== "Transformer" && A.hasName(U.selectable)) {
1411
+ if (w) {
1412
+ const F = A.id();
1413
+ if (!w.includes(F)) return;
1967
1414
  }
1415
+ const K = A.getAttrs(), Wt = K.x || 0, Vt = K.y || 0, ne = K.width || 0, re = K.height || 0;
1416
+ if (K.rotation || 0) {
1417
+ const F = A.getClientRect({ skipTransform: !1 }), Rt = this.getStage(), mt = Rt.scaleX(), Lt = Rt.x(), Bt = Rt.y(), oe = (F.x - Lt) / mt, ae = (F.y - Bt) / mt, he = (F.x + F.width - Lt) / mt, ce = (F.y + F.height - Bt) / mt;
1418
+ a = Math.min(a, oe), h = Math.min(h, ae), c = Math.max(c, he), g = Math.max(g, ce);
1419
+ } else
1420
+ a = Math.min(a, Wt), h = Math.min(h, Vt), c = Math.max(c, Wt + ne), g = Math.max(g, Vt + re);
1968
1421
  }
1969
- });
1970
- if (minX === Infinity || minY === Infinity) return;
1971
- const contentWidth = maxX - minX;
1972
- const contentHeight = maxY - minY;
1973
- const contentCenterX = minX + contentWidth / 2;
1974
- const contentCenterY = minY + contentHeight / 2;
1975
- const viewport = this.getState().viewport;
1976
- let newScale = viewport.scale;
1977
- if (shouldScale) {
1978
- const scaleX = (viewport.width - padding * 2) / contentWidth;
1979
- const scaleY = (viewport.height - padding * 2) / contentHeight;
1980
- newScale = Math.min(scaleX, scaleY, 1);
1422
+ }), a === 1 / 0 || h === 1 / 0) return;
1423
+ const b = c - a, _ = g - h, M = a + b / 2, Tt = h + _ / 2, q = this.getState().viewport;
1424
+ let G = q.scale;
1425
+ if (n) {
1426
+ const A = (q.width - i * 2) / b, K = (q.height - i * 2) / _;
1427
+ G = Math.min(A, K, 1);
1981
1428
  }
1982
- const x = viewport.width / 2 - contentCenterX * newScale;
1983
- const y = viewport.height / 2 - contentCenterY * newScale;
1984
- this.updateViewport({ x, y, scale: newScale }, true);
1429
+ const nt = q.width / 2 - M * G, Zt = q.height / 2 - Tt * G;
1430
+ this.updateViewport({ x: nt, y: Zt, scale: G }, !0);
1431
+ }
1432
+ /**
1433
+ * 导出当前状态
1434
+ */
1435
+ save() {
1436
+ return this.getState();
1437
+ }
1438
+ /**
1439
+ * 从状态中恢复画布
1440
+ */
1441
+ restore(s) {
1442
+ this._renderCanvas(s);
1985
1443
  }
1986
1444
  }
1987
- function modulate(value, rangeA, rangeB, clamp2 = false) {
1988
- const [fromLow, fromHigh] = rangeA;
1989
- const [v0, v1] = rangeB;
1990
- const result = v0 + (value - fromLow) / (fromHigh - fromLow) * (v1 - v0);
1991
- return clamp2 ? v0 < v1 ? Math.max(Math.min(result, v1), v0) : Math.max(Math.min(result, v0), v1) : result;
1445
+ function ze(o, s, t, i = !1) {
1446
+ const [n, r] = s, [a, h] = t, c = a + (o - n) / (r - n) * (h - a);
1447
+ return i ? a < h ? Math.max(Math.min(c, h), a) : Math.max(Math.min(c, a), h) : c;
1992
1448
  }
1993
- const gridSteps = [
1449
+ const qt = [
1994
1450
  {
1995
1451
  min: -1,
1996
1452
  mid: 0.15,
@@ -2012,20 +1468,15 @@ const gridSteps = [
2012
1468
  step: 1
2013
1469
  }
2014
1470
  ];
2015
- function GridBackground({
2016
- viewportX,
2017
- viewportY,
2018
- scale,
2019
- size = 20,
2020
- showGrid = true
1471
+ function Ye({
1472
+ viewportX: o,
1473
+ viewportY: s,
1474
+ scale: t,
1475
+ size: i = 20,
1476
+ showGrid: n = !0
2021
1477
  }) {
2022
- const x = viewportX / scale;
2023
- const y = viewportY / scale;
2024
- const z = scale;
2025
- if (!showGrid) {
2026
- return null;
2027
- }
2028
- return /* @__PURE__ */ jsxs(
1478
+ const r = o / t, a = s / t, h = t;
1479
+ return n ? /* @__PURE__ */ st(
2029
1480
  "svg",
2030
1481
  {
2031
1482
  className: "canvas-grid w-full h-full absolute top-0 left-0",
@@ -2033,43 +1484,38 @@ function GridBackground({
2033
1484
  xmlns: "http://www.w3.org/2000/svg",
2034
1485
  "aria-hidden": "true",
2035
1486
  children: [
2036
- /* @__PURE__ */ jsx("defs", { children: gridSteps.map(({ min, mid, step }, i) => {
2037
- const s = step * size * z;
2038
- const xo = 0.5 + x * z;
2039
- const yo = 0.5 + y * z;
2040
- const gxo = xo > 0 ? xo % s : s + xo % s;
2041
- const gyo = yo > 0 ? yo % s : s + yo % s;
2042
- const opacity = z < mid ? modulate(z, [min, mid], [0, 1]) : 1;
2043
- return /* @__PURE__ */ jsx(
1487
+ /* @__PURE__ */ S("defs", { children: qt.map(({ min: c, mid: g, step: m }, p) => {
1488
+ const f = m * i * h, x = 0.5 + r * h, w = 0.5 + a * h, b = x > 0 ? x % f : f + x % f, _ = w > 0 ? w % f : f + w % f, M = h < g ? ze(h, [c, g], [0, 1]) : 1;
1489
+ return /* @__PURE__ */ S(
2044
1490
  "pattern",
2045
1491
  {
2046
- id: `grid_${step}`,
2047
- width: s,
2048
- height: s,
1492
+ id: `grid_${m}`,
1493
+ width: f,
1494
+ height: f,
2049
1495
  patternUnits: "userSpaceOnUse",
2050
- children: /* @__PURE__ */ jsx(
1496
+ children: /* @__PURE__ */ S(
2051
1497
  "circle",
2052
1498
  {
2053
- className: "tl-grid-dot",
2054
- cx: gxo,
2055
- cy: gyo,
1499
+ className: "grid-dot",
1500
+ cx: b,
1501
+ cy: _,
2056
1502
  r: 1,
2057
- opacity
1503
+ opacity: M
2058
1504
  }
2059
1505
  )
2060
1506
  },
2061
- i
1507
+ p
2062
1508
  );
2063
1509
  }) }),
2064
- gridSteps.map(({ step }, i) => /* @__PURE__ */ jsx("rect", { width: "100%", height: "100%", fill: `url(#grid_${step})` }, i))
1510
+ qt.map(({ step: c }, g) => /* @__PURE__ */ S("rect", { width: "100%", height: "100%", fill: `url(#grid_${c})` }, g))
2065
1511
  ]
2066
1512
  }
2067
- );
1513
+ ) : null;
2068
1514
  }
2069
- function cn(...inputs) {
2070
- return twMerge(clsx(inputs));
1515
+ function Oe(...o) {
1516
+ return xe(ye(o));
2071
1517
  }
2072
- const buttonVariants = cva(
1518
+ const Xe = pe(
2073
1519
  "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
2074
1520
  {
2075
1521
  variants: {
@@ -2096,162 +1542,148 @@ const buttonVariants = cva(
2096
1542
  }
2097
1543
  }
2098
1544
  );
2099
- function Button({
2100
- className,
2101
- variant = "default",
2102
- size = "default",
2103
- asChild = false,
2104
- ...props
1545
+ function ot({
1546
+ className: o,
1547
+ variant: s = "default",
1548
+ size: t = "default",
1549
+ asChild: i = !1,
1550
+ ...n
2105
1551
  }) {
2106
- const Comp = asChild ? Slot : "button";
2107
- return /* @__PURE__ */ jsx(
2108
- Comp,
1552
+ return /* @__PURE__ */ S(
1553
+ i ? fe : "button",
2109
1554
  {
2110
1555
  "data-slot": "button",
2111
- "data-variant": variant,
2112
- "data-size": size,
2113
- className: cn(buttonVariants({ variant, size, className })),
2114
- ...props
1556
+ "data-variant": s,
1557
+ "data-size": t,
1558
+ className: Oe(Xe({ variant: s, size: t, className: o })),
1559
+ ...n
2115
1560
  }
2116
1561
  );
2117
1562
  }
2118
- function ZoomPanel({ api }) {
2119
- const [viewport, setViewport] = useState(api.getState().viewport);
2120
- useEffect(() => {
2121
- api.on("viewport:change", (newViewport) => {
2122
- setViewport(newViewport);
1563
+ function Pe({ api: o }) {
1564
+ const [s, t] = at(o.getState().viewport);
1565
+ Pt(() => {
1566
+ o.on("viewport:change", (c) => {
1567
+ t(c);
2123
1568
  });
2124
- }, [setViewport, api]);
2125
- const updateScale = (scale) => {
2126
- const halfWidth = viewport.width / 2;
2127
- const halfHeight = viewport.height / 2;
2128
- const worldCenterX = (halfWidth - viewport.x) / viewport.scale;
2129
- const worldCenterY = (halfHeight - viewport.y) / viewport.scale;
2130
- const x = halfWidth - worldCenterX * scale;
2131
- const y = halfHeight - worldCenterY * scale;
2132
- api.updateViewport({ x, y, scale });
2133
- };
2134
- const handleZoomIn = () => {
2135
- const scale = Math.min(viewport.scale * 1.2, 5);
2136
- updateScale(scale);
2137
- };
2138
- const handleZoomOut = () => {
2139
- const scale = Math.max(viewport.scale / 1.2, 0.1);
2140
- updateScale(scale);
2141
- };
2142
- const handleReset = () => {
2143
- updateScale(1);
2144
- };
2145
- const percent = Math.round(viewport.scale * 100);
2146
- return /* @__PURE__ */ jsxs("div", { className: "zoom-panel flex items-center gap-2", children: [
2147
- /* @__PURE__ */ jsx(
2148
- Button,
1569
+ }, [t, o]);
1570
+ const i = (c) => {
1571
+ const g = s.width / 2, m = s.height / 2, p = (g - s.x) / s.scale, f = (m - s.y) / s.scale, x = g - p * c, w = m - f * c;
1572
+ o.updateViewport({ x, y: w, scale: c });
1573
+ }, n = () => {
1574
+ const c = Math.min(s.scale * 1.2, 5);
1575
+ i(c);
1576
+ }, r = () => {
1577
+ const c = Math.max(s.scale / 1.2, 0.1);
1578
+ i(c);
1579
+ }, a = () => {
1580
+ i(1);
1581
+ }, h = Math.round(s.scale * 100);
1582
+ return /* @__PURE__ */ st("div", { className: "zoom-panel flex items-center gap-2", children: [
1583
+ /* @__PURE__ */ S(
1584
+ ot,
2149
1585
  {
2150
1586
  size: "sm",
2151
1587
  variant: "secondary",
2152
- onClick: handleZoomOut,
1588
+ onClick: r,
2153
1589
  title: "缩小",
2154
- children: /* @__PURE__ */ jsx(Minus, {})
1590
+ children: /* @__PURE__ */ S(we, {})
2155
1591
  }
2156
1592
  ),
2157
- /* @__PURE__ */ jsxs(
2158
- Button,
1593
+ /* @__PURE__ */ st(
1594
+ ot,
2159
1595
  {
2160
1596
  size: "sm",
2161
1597
  variant: "secondary",
2162
- onClick: handleReset,
2163
- title: `${percent}%`,
1598
+ onClick: a,
1599
+ title: `${h}%`,
2164
1600
  className: "min-w-16",
2165
1601
  children: [
2166
- percent,
1602
+ h,
2167
1603
  "%"
2168
1604
  ]
2169
1605
  }
2170
1606
  ),
2171
- /* @__PURE__ */ jsx(
2172
- Button,
1607
+ /* @__PURE__ */ S(
1608
+ ot,
2173
1609
  {
2174
1610
  size: "sm",
2175
1611
  variant: "secondary",
2176
- onClick: handleZoomIn,
1612
+ onClick: n,
2177
1613
  title: "放大",
2178
- children: /* @__PURE__ */ jsx(Plus, {})
1614
+ children: /* @__PURE__ */ S(ve, {})
2179
1615
  }
2180
1616
  )
2181
1617
  ] });
2182
1618
  }
2183
- function HistoryPanel({ api }) {
2184
- const [canUndo, setCanUndo] = useState(api.canUndo());
2185
- const [canRedo, setCanRedo] = useState(api.canRedo());
2186
- useEffect(() => {
2187
- const handleStateChange = () => {
2188
- setCanUndo(api.canUndo());
2189
- setCanRedo(api.canRedo());
1619
+ function Ue({ api: o }) {
1620
+ const [s, t] = at(o.canUndo()), [i, n] = at(o.canRedo());
1621
+ return Pt(() => {
1622
+ const r = () => {
1623
+ t(o.canUndo()), n(o.canRedo());
2190
1624
  };
2191
- api.on("state:change", handleStateChange);
2192
- return () => {
2193
- api.off("state:change", handleStateChange);
1625
+ return o.on("state:change", r), () => {
1626
+ o.off("state:change", r);
2194
1627
  };
2195
- }, [api]);
2196
- return /* @__PURE__ */ jsxs("div", { className: "history-panel flex items-center gap-2", children: [
2197
- /* @__PURE__ */ jsx(
2198
- Button,
1628
+ }, [o]), /* @__PURE__ */ st("div", { className: "history-panel flex items-center gap-2", children: [
1629
+ /* @__PURE__ */ S(
1630
+ ot,
2199
1631
  {
2200
1632
  size: "sm",
2201
1633
  variant: "secondary",
2202
- disabled: !canUndo,
2203
- onClick: () => api.undo(),
1634
+ disabled: !s,
1635
+ onClick: () => o.undo(),
2204
1636
  title: "撤销",
2205
- children: /* @__PURE__ */ jsx(Undo2, {})
1637
+ children: /* @__PURE__ */ S(Ne, {})
2206
1638
  }
2207
1639
  ),
2208
- /* @__PURE__ */ jsx(
2209
- Button,
1640
+ /* @__PURE__ */ S(
1641
+ ot,
2210
1642
  {
2211
1643
  size: "sm",
2212
1644
  variant: "secondary",
2213
- disabled: !canRedo,
2214
- onClick: () => api.redo(),
1645
+ disabled: !i,
1646
+ onClick: () => o.redo(),
2215
1647
  title: "重做",
2216
- children: /* @__PURE__ */ jsx(Redo2, {})
1648
+ children: /* @__PURE__ */ S(Se, {})
2217
1649
  }
2218
1650
  )
2219
1651
  ] });
2220
1652
  }
2221
- function PureCanvas({ setApi }) {
2222
- const containerRef = useRef(null);
2223
- const [_api, _setApi] = useState(null);
2224
- const [viewport, setViewport] = useState({ x: 0, y: 0, scale: 1 });
2225
- useEffect(() => {
2226
- if (!containerRef.current) return;
2227
- const core = new CanvasApi(containerRef.current);
2228
- _setApi(core);
2229
- setApi?.(core);
2230
- core.on("viewport:change", (newViewport) => {
2231
- setViewport(newViewport);
2232
- });
2233
- return () => {
2234
- core.dispose();
1653
+ function ts({ setApi: o }) {
1654
+ const s = me(null), [t, i] = at(null), [n, r] = at({ x: 0, y: 0, scale: 1 });
1655
+ return Pt(() => {
1656
+ if (!s.current) return;
1657
+ const a = new Ae(s.current);
1658
+ return i(a), o?.(a), a.on("viewport:change", (h) => {
1659
+ r(h);
1660
+ }), () => {
1661
+ a.dispose();
2235
1662
  };
2236
- }, [setApi]);
2237
- return /* @__PURE__ */ jsxs("div", { className: "pure-canvas relative size-full", children: [
2238
- /* @__PURE__ */ jsx(
2239
- GridBackground,
1663
+ }, [o]), /* @__PURE__ */ st("div", { className: "whiteboard relative size-full", children: [
1664
+ /* @__PURE__ */ S(
1665
+ Ye,
1666
+ {
1667
+ viewportX: n.x,
1668
+ viewportY: n.y,
1669
+ scale: n.scale
1670
+ }
1671
+ ),
1672
+ /* @__PURE__ */ S(
1673
+ "div",
2240
1674
  {
2241
- viewportX: viewport.x,
2242
- viewportY: viewport.y,
2243
- scale: viewport.scale
1675
+ ref: s,
1676
+ className: "whiteboard-container size-full outline-none"
2244
1677
  }
2245
1678
  ),
2246
- /* @__PURE__ */ jsx("div", { ref: containerRef, className: "size-full" }),
2247
- _api && /* @__PURE__ */ jsxs(Fragment, { children: [
2248
- /* @__PURE__ */ jsx("div", { className: "history-panel-wrapper absolute bottom-4 left-4 z-10", children: /* @__PURE__ */ jsx(HistoryPanel, { api: _api }) }),
2249
- /* @__PURE__ */ jsx("div", { className: "zoom-panel-wrapper absolute bottom-4 right-4 z-10", children: /* @__PURE__ */ jsx(ZoomPanel, { api: _api }) })
1679
+ t && /* @__PURE__ */ st(ge, { children: [
1680
+ /* @__PURE__ */ S("div", { className: "history-panel-wrapper absolute bottom-4 left-4 z-10", children: /* @__PURE__ */ S(Ue, { api: t }) }),
1681
+ /* @__PURE__ */ S("div", { className: "zoom-panel-wrapper absolute bottom-4 right-4 z-10", children: /* @__PURE__ */ S(Pe, { api: t }) })
2250
1682
  ] })
2251
1683
  ] });
2252
1684
  }
2253
1685
  export {
2254
- CanvasApi,
2255
- NODE_NAMES,
2256
- PureCanvas
1686
+ Ae as CanvasApi,
1687
+ U as NODE_NAMES,
1688
+ ts as Whiteboard
2257
1689
  };