luo-image-annotator 0.0.4 → 0.0.7

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.
@@ -1,71 +1,72 @@
1
- var _t = Object.defineProperty;
2
- var It = (v, t, n) => t in v ? _t(v, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : v[t] = n;
3
- var C = (v, t, n) => It(v, typeof t != "symbol" ? t + "" : t, n);
4
- import { defineComponent as N, ref as S, watchEffect as St, openBlock as x, createElementBlock as b, normalizeClass as $, computed as kt, onMounted as Mt, watch as V, createElementVNode as d, createVNode as z, Fragment as T, renderList as D, createCommentVNode as L, normalizeStyle as K, toDisplayString as H, createTextVNode as O, withDirectives as q, vModelText as X, createBlock as nt, nextTick as zt } from "vue";
5
- const Y = (v, t) => Math.sqrt(Math.pow(v.x - t.x, 2) + Math.pow(v.y - t.y, 2)), Ht = (v, t) => {
6
- let n = !1;
7
- for (let e = 0, a = t.length - 1; e < t.length; a = e++) {
8
- const o = t[e].x, r = t[e].y, i = t[a].x, h = t[a].y;
9
- r > v.y != h > v.y && v.x < (i - o) * (v.y - r) / (h - r) + o && (n = !n);
1
+ var Jt = Object.defineProperty;
2
+ var jt = (m, t, i) => t in m ? Jt(m, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : m[t] = i;
3
+ var A = (m, t, i) => jt(m, typeof t != "symbol" ? t + "" : t, i);
4
+ import { defineComponent as Q, ref as k, watchEffect as Xt, openBlock as y, createElementBlock as b, normalizeClass as E, computed as U, onMounted as Yt, watch as j, createElementVNode as g, toDisplayString as $, Fragment as L, renderList as R, normalizeStyle as O, createCommentVNode as z, createVNode as P, createTextVNode as X, withDirectives as it, vModelText as ot, createBlock as vt, nextTick as qt } from "vue";
5
+ const at = (m, t) => Math.sqrt(Math.pow(m.x - t.x, 2) + Math.pow(m.y - t.y, 2)), Gt = (m, t) => {
6
+ let i = !1;
7
+ for (let n = 0, r = t.length - 1; n < t.length; r = n++) {
8
+ const o = t[n].x, c = t[n].y, a = t[r].x, d = t[r].y;
9
+ c > m.y != d > m.y && m.x < (a - o) * (m.y - c) / (d - c) + o && (i = !i);
10
10
  }
11
- return n;
12
- }, st = (v, t, n) => {
13
- const e = n * (Math.PI / 180), a = Math.cos(e), o = Math.sin(e), r = v.x - t.x, i = v.y - t.y;
11
+ return i;
12
+ }, mt = (m, t, i) => {
13
+ const n = i * (Math.PI / 180), r = Math.cos(n), o = Math.sin(n), c = m.x - t.x, a = m.y - t.y;
14
14
  return {
15
- x: t.x + (r * a - i * o),
16
- y: t.y + (r * o + i * a)
15
+ x: t.x + (c * r - a * o),
16
+ y: t.y + (c * o + a * r)
17
17
  };
18
18
  };
19
- class Pt {
19
+ class Kt {
20
20
  constructor(t) {
21
- C(this, "canvas");
22
- C(this, "ctx");
23
- C(this, "img");
24
- C(this, "annotations", []);
21
+ A(this, "canvas");
22
+ A(this, "ctx");
23
+ A(this, "img");
24
+ A(this, "annotations", []);
25
25
  // 状态
26
- C(this, "currentTool", null);
27
- C(this, "activeAnnotation", null);
28
- C(this, "hoverAnnotation", null);
29
- C(this, "isDrawing", !1);
30
- C(this, "isDragging", !1);
31
- C(this, "isPanning", !1);
26
+ A(this, "currentTool", null);
27
+ A(this, "interactionMode", "none");
28
+ A(this, "activeAnnotation", null);
29
+ A(this, "hoverAnnotation", null);
30
+ A(this, "isDrawing", !1);
31
+ A(this, "isDragging", !1);
32
+ A(this, "isPanning", !1);
32
33
  // 平移模式
33
- C(this, "panStartPoint", null);
34
+ A(this, "panStartPoint", null);
34
35
  // 平移起点
35
- C(this, "dragStartPoint", null);
36
- C(this, "dragStartAnnotation", null);
36
+ A(this, "dragStartPoint", null);
37
+ A(this, "dragStartAnnotation", null);
37
38
  // 快照用于撤销/diff
38
- C(this, "lastMouseMovePoint", null);
39
+ A(this, "lastMouseMovePoint", null);
39
40
  // 用于绘制辅助线
40
- C(this, "isHoveringStartPoint", !1);
41
+ A(this, "isHoveringStartPoint", !1);
41
42
  // 多边形闭合吸附状态
42
43
  // 设置
43
- C(this, "currentLabelColor", "#FF4081");
44
+ A(this, "currentLabelColor", "#FF4081");
44
45
  // 当前选中标签颜色
45
- C(this, "visibleLabels", /* @__PURE__ */ new Set());
46
+ A(this, "visibleLabels", /* @__PURE__ */ new Set());
46
47
  // 可见标签集合 (如果为空则全部可见,或者由外部控制渲染列表)
47
48
  // 交互
48
- C(this, "selectedHandleIndex", -1);
49
+ A(this, "selectedHandleIndex", -1);
49
50
  // -1: 主体, >=0: 顶点索引, -2: 旋转手柄
50
- C(this, "hoverHandleIndex", -1);
51
+ A(this, "hoverHandleIndex", -1);
51
52
  // 视口
52
- C(this, "scale", 1);
53
- C(this, "offset", { x: 0, y: 0 });
54
- C(this, "listeners", {});
55
- C(this, "imageUrl", "");
53
+ A(this, "scale", 1);
54
+ A(this, "offset", { x: 0, y: 0 });
55
+ A(this, "listeners", {});
56
+ A(this, "imageUrl", "");
56
57
  this.canvas = t;
57
- const n = t.getContext("2d");
58
- if (!n) throw new Error("Could not get 2d context");
59
- this.ctx = n, this.img = new Image(), this.img.crossOrigin = "Anonymous", this.img.onload = () => {
58
+ const i = t.getContext("2d");
59
+ if (!i) throw new Error("Could not get 2d context");
60
+ this.ctx = i, this.img = new Image(), this.img.crossOrigin = "Anonymous", this.img.onload = () => {
60
61
  this.fitImageToCanvas(), this.render();
61
62
  }, this.bindEvents();
62
63
  }
63
64
  // --- 公共 API ---
64
- on(t, n) {
65
- this.listeners[t] || (this.listeners[t] = []), this.listeners[t].push(n);
65
+ on(t, i) {
66
+ this.listeners[t] || (this.listeners[t] = []), this.listeners[t].push(i);
66
67
  }
67
- emit(t, n) {
68
- this.listeners[t] && this.listeners[t].forEach((e) => e(n));
68
+ emit(t, i) {
69
+ this.listeners[t] && this.listeners[t].forEach((n) => n(i));
69
70
  }
70
71
  loadImage(t) {
71
72
  this.imageUrl = t, this.img.src = t, this.activeAnnotation = null, this.isDrawing = !1;
@@ -77,7 +78,7 @@ class Pt {
77
78
  return this.annotations;
78
79
  }
79
80
  setTool(t) {
80
- t === "pan" ? (this.currentTool = null, this.isPanning = !1, this.canvas.style.cursor = "grab") : t === "select" ? (this.currentTool = null, this.canvas.style.cursor = "default") : (this.currentTool = t, this.canvas.style.cursor = "crosshair"), this.activeAnnotation = null, this.isDrawing = !1, this.render();
81
+ t === "pan" ? (this.interactionMode = "pan", this.currentTool = null, this.isPanning = !1, this.canvas.style.cursor = "grab") : t === "select" ? (this.interactionMode = "select", this.currentTool = null, this.canvas.style.cursor = "default") : t ? (this.interactionMode = "draw", this.currentTool = t, this.canvas.style.cursor = "crosshair") : (this.interactionMode = "none", this.currentTool = null, this.canvas.style.cursor = "default"), this.activeAnnotation = null, this.isDrawing = !1, this.render();
81
82
  }
82
83
  setLabelStyle(t) {
83
84
  this.currentLabelColor = t;
@@ -86,33 +87,33 @@ class Pt {
86
87
  this.visibleLabels = new Set(t), this.render();
87
88
  }
88
89
  zoom(t) {
89
- const e = t > 0 ? this.scale * 1.1 : this.scale / 1.1;
90
- if (e < 0.1 || e > 10) return;
91
- const a = this.canvas.width / 2, o = this.canvas.height / 2, r = this.toImageCoords(a, o);
92
- this.scale = e, this.offset.x = a - r.x * this.scale, this.offset.y = o - r.y * this.scale, this.render();
90
+ const n = t > 0 ? this.scale * 1.1 : this.scale / 1.1;
91
+ if (n < 0.1 || n > 10) return;
92
+ const r = this.canvas.width / 2, o = this.canvas.height / 2, c = this.toImageCoords(r, o);
93
+ this.scale = n, this.offset.x = r - c.x * this.scale, this.offset.y = o - c.y * this.scale, this.render();
93
94
  }
94
95
  resize() {
95
96
  this.fitImageToCanvas(), this.render();
96
97
  }
97
98
  // --- 坐标系统 ---
98
- toImageCoords(t, n) {
99
+ toImageCoords(t, i) {
99
100
  return {
100
101
  x: (t - this.offset.x) / this.scale,
101
- y: (n - this.offset.y) / this.scale
102
+ y: (i - this.offset.y) / this.scale
102
103
  };
103
104
  }
104
- toScreenCoords(t, n) {
105
+ toScreenCoords(t, i) {
105
106
  return {
106
107
  x: t * this.scale + this.offset.x,
107
- y: n * this.scale + this.offset.y
108
+ y: i * this.scale + this.offset.y
108
109
  };
109
110
  }
110
111
  fitImageToCanvas() {
111
112
  const t = this.canvas.parentElement;
112
113
  if (t) {
113
114
  if (this.canvas.width = t.clientWidth, this.canvas.height = t.clientHeight, this.img.width === 0) return;
114
- const n = this.canvas.width / this.img.width, e = this.canvas.height / this.img.height;
115
- this.scale = Math.min(n, e), this.offset.x = (this.canvas.width - this.img.width * this.scale) / 2, this.offset.y = (this.canvas.height - this.img.height * this.scale) / 2;
115
+ const i = this.canvas.width / this.img.width, n = this.canvas.height / this.img.height;
116
+ this.scale = Math.min(i, n), this.offset.x = (this.canvas.width - this.img.width * this.scale) / 2, this.offset.y = (this.canvas.height - this.img.height * this.scale) / 2;
116
117
  }
117
118
  }
118
119
  // --- 事件处理 ---
@@ -120,42 +121,52 @@ class Pt {
120
121
  this.canvas.addEventListener("mousedown", this.handleMouseDown.bind(this)), this.canvas.addEventListener("mousemove", this.handleMouseMove.bind(this)), this.canvas.addEventListener("mouseup", this.handleMouseUp.bind(this)), this.canvas.addEventListener("mouseleave", this.handleMouseUp.bind(this)), window.addEventListener("keydown", this.handleKeyDown.bind(this));
121
122
  }
122
123
  handleKeyDown(t) {
123
- (t.key === "Delete" || t.key === "Backspace") && this.activeAnnotation && this.deleteAnnotation(this.activeAnnotation.id);
124
+ this.interactionMode === "select" && (t.key === "Delete" || t.key === "Backspace") && this.activeAnnotation && this.deleteAnnotation(this.activeAnnotation.id);
124
125
  }
125
126
  deleteAnnotation(t) {
126
- const n = this.annotations.findIndex((e) => e.id === t);
127
- if (n > -1) {
128
- const e = this.annotations[n];
129
- this.annotations.splice(n, 1), this.activeAnnotation = null, this.emit("annotationChange", {
127
+ const i = this.annotations.findIndex((n) => n.id === t);
128
+ if (i > -1) {
129
+ const n = this.annotations[i];
130
+ this.annotations.splice(i, 1), this.activeAnnotation = null, this.emit("annotationChange", {
130
131
  action: "delete",
131
- changedItem: e,
132
+ changedItem: n,
132
133
  imageUrl: this.imageUrl
133
134
  }), this.render();
134
135
  }
135
136
  }
136
137
  handleMouseDown(t) {
137
- const n = this.canvas.getBoundingClientRect(), e = t.clientX - n.left, a = t.clientY - n.top, o = this.toImageCoords(e, a);
138
+ const i = this.canvas.getBoundingClientRect(), n = t.clientX - i.left, r = t.clientY - i.top, o = this.toImageCoords(n, r);
138
139
  if (this.canvas.style.cursor === "grab" || this.canvas.style.cursor === "grabbing") {
139
- this.isPanning = !0, this.panStartPoint = { x: e, y: a }, this.canvas.style.cursor = "grabbing";
140
+ this.isPanning = !0, this.panStartPoint = { x: n, y: r }, this.canvas.style.cursor = "grabbing";
140
141
  return;
141
142
  }
142
- if (this.activeAnnotation) {
143
- const h = this.getHitHandle(e, a, this.activeAnnotation);
144
- if (h !== -100) {
145
- this.isDragging = !0, this.dragStartPoint = o, this.selectedHandleIndex = h, this.dragStartAnnotation = JSON.parse(JSON.stringify(this.activeAnnotation));
143
+ if (this.interactionMode === "select" && this.activeAnnotation) {
144
+ const d = this.getHitHandle(n, r, this.activeAnnotation);
145
+ if (d !== -100) {
146
+ this.isDragging = !0, this.dragStartPoint = o, this.selectedHandleIndex = d, this.dragStartAnnotation = JSON.parse(JSON.stringify(this.activeAnnotation));
146
147
  return;
147
148
  }
148
149
  }
149
- const r = this.getHitCategory(e, a);
150
- if (r) {
151
- this.activeAnnotation = r, this.isDragging = !1, this.selectedHandleIndex = -1, this.emit("annotationChange", { action: "select", changedItem: r, imageUrl: this.imageUrl }), this.render();
150
+ const c = this.interactionMode === "select" ? this.getHitCategory(n, r) : null;
151
+ if (c) {
152
+ this.activeAnnotation = c, this.isDragging = !1, this.selectedHandleIndex = -1, this.emit("annotationChange", { action: "select", changedItem: c, imageUrl: this.imageUrl }), this.render();
152
153
  return;
153
154
  }
154
- const i = this.getHitAnnotation(o);
155
- if (this.currentTool) {
155
+ const a = this.getHitAnnotation(o);
156
+ if (this.interactionMode === "select") {
157
+ if (a) {
158
+ if (!(this.visibleLabels.size > 0 && !this.visibleLabels.has(a.label))) {
159
+ this.activeAnnotation = a, this.isDragging = !0, this.dragStartPoint = o, this.selectedHandleIndex = -1, this.dragStartAnnotation = JSON.parse(JSON.stringify(a)), this.emit("annotationChange", { action: "select", changedItem: a, imageUrl: this.imageUrl }), this.render();
160
+ return;
161
+ }
162
+ } else
163
+ this.activeAnnotation = null, this.emit("annotationChange", { action: "select", changedItem: void 0, imageUrl: this.imageUrl }), this.render();
164
+ return;
165
+ }
166
+ if (this.interactionMode === "draw") {
156
167
  if (this.isDrawing && this.currentTool === "polygon" && this.activeAnnotation) {
157
- const h = this.activeAnnotation.coordinates;
158
- if (h.points.length > 2 && Y(o, h.points[0]) < 20 / this.scale) {
168
+ const d = this.activeAnnotation.coordinates;
169
+ if (d.points.length > 2 && at(o, d.points[0]) < 20 / this.scale) {
159
170
  this.finishDrawing();
160
171
  return;
161
172
  }
@@ -167,38 +178,30 @@ class Pt {
167
178
  this.startDrawing(o);
168
179
  return;
169
180
  }
170
- if (i) {
171
- this.activeAnnotation = i, this.isDragging = !0, this.dragStartPoint = o, this.selectedHandleIndex = -1, this.dragStartAnnotation = JSON.parse(JSON.stringify(i)), this.emit("annotationChange", { action: "select", changedItem: i, imageUrl: this.imageUrl }), this.render();
172
- return;
173
- }
174
181
  this.startDrawing(o);
175
- } else i ? (this.activeAnnotation = i, this.isDragging = !0, this.dragStartPoint = o, this.selectedHandleIndex = -1, this.dragStartAnnotation = JSON.parse(JSON.stringify(i)), this.emit("annotationChange", { action: "select", changedItem: i, imageUrl: this.imageUrl }), this.render()) : (this.activeAnnotation = null, this.render());
176
- } else if (i) {
177
- if (!(this.visibleLabels.size > 0 && !this.visibleLabels.has(i.label))) {
178
- this.activeAnnotation = i, this.isDragging = !0, this.dragStartPoint = o, this.selectedHandleIndex = -1, this.dragStartAnnotation = JSON.parse(JSON.stringify(i)), this.emit("annotationChange", { action: "select", changedItem: i, imageUrl: this.imageUrl }), this.render();
179
- return;
180
182
  }
181
- } else
182
- this.activeAnnotation = null, this.render();
183
+ return;
184
+ }
185
+ this.activeAnnotation = null, this.render();
183
186
  }
184
187
  handleMouseMove(t) {
185
- const n = this.canvas.getBoundingClientRect(), e = t.clientX - n.left, a = t.clientY - n.top, o = this.toImageCoords(e, a);
188
+ const i = this.canvas.getBoundingClientRect(), n = t.clientX - i.left, r = t.clientY - i.top, o = this.toImageCoords(n, r);
186
189
  if (this.isPanning && this.panStartPoint) {
187
- const r = e - this.panStartPoint.x, i = a - this.panStartPoint.y;
188
- this.offset.x += r, this.offset.y += i, this.panStartPoint = { x: e, y: a }, this.render();
190
+ const c = n - this.panStartPoint.x, a = r - this.panStartPoint.y;
191
+ this.offset.x += c, this.offset.y += a, this.panStartPoint = { x: n, y: r }, this.render();
189
192
  return;
190
193
  }
191
194
  if (this.lastMouseMovePoint = o, this.isDrawing) {
192
195
  if (this.currentTool === "polygon" && this.activeAnnotation) {
193
- const r = this.activeAnnotation.coordinates;
194
- if (r.points.length > 2) {
195
- const i = r.points[0], h = Y(o, i);
196
- this.isHoveringStartPoint = h < 20 / this.scale;
196
+ const c = this.activeAnnotation.coordinates;
197
+ if (c.points.length > 2) {
198
+ const a = c.points[0], d = at(o, a);
199
+ this.isHoveringStartPoint = d < 20 / this.scale;
197
200
  } else
198
201
  this.isHoveringStartPoint = !1;
199
202
  }
200
203
  this.updateDrawing(o);
201
- } else this.isDragging && this.activeAnnotation && this.dragStartPoint ? this.updateDragging(o) : this.checkHover(e, a, o);
204
+ } else this.isDragging && this.activeAnnotation && this.dragStartPoint ? this.updateDragging(o) : this.checkHover(n, r, o);
202
205
  this.render();
203
206
  }
204
207
  handleMouseUp(t) {
@@ -221,17 +224,17 @@ class Pt {
221
224
  }
222
225
  // --- 绘制逻辑 ---
223
226
  // 辅助函数:将 hex 转换为 rgba
224
- hexToRgba(t, n) {
227
+ hexToRgba(t, i) {
225
228
  if (!t.startsWith("#")) return t;
226
- const e = parseInt(t.slice(1, 3), 16), a = parseInt(t.slice(3, 5), 16), o = parseInt(t.slice(5, 7), 16);
227
- return `rgba(${e}, ${a}, ${o}, ${n})`;
229
+ const n = parseInt(t.slice(1, 3), 16), r = parseInt(t.slice(3, 5), 16), o = parseInt(t.slice(5, 7), 16);
230
+ return `rgba(${n}, ${r}, ${o}, ${i})`;
228
231
  }
229
232
  startDrawing(t) {
230
233
  if (!this.currentTool) return;
231
- const n = Date.now().toString();
234
+ const i = Date.now().toString();
232
235
  if (this.hexToRgba(this.currentLabelColor, 0.2), this.currentLabelColor, this.currentTool === "rectangle")
233
236
  this.isDrawing = !0, this.dragStartPoint = t, this.activeAnnotation = {
234
- id: n,
237
+ id: i,
235
238
  type: "rectangle",
236
239
  label: "",
237
240
  // 组件应填充此项
@@ -239,25 +242,25 @@ class Pt {
239
242
  style: { strokeColor: this.currentLabelColor }
240
243
  };
241
244
  else if (this.currentTool === "point") {
242
- const e = {
243
- id: n,
245
+ const n = {
246
+ id: i,
244
247
  type: "point",
245
248
  label: "",
246
249
  coordinates: { points: [t] },
247
250
  style: { strokeColor: this.currentLabelColor }
248
251
  };
249
- this.annotations.push(e), this.emit("annotationChange", { action: "add", changedItem: e, imageUrl: this.imageUrl }), this.activeAnnotation = e;
252
+ this.annotations.push(n), this.emit("annotationChange", { action: "add", changedItem: n, imageUrl: this.imageUrl }), this.activeAnnotation = n;
250
253
  } else if (this.currentTool === "polygon")
251
254
  this.activeAnnotation && this.activeAnnotation.type === "polygon" && this.isDrawing ? this.activeAnnotation.coordinates.points.push(t) : (this.isDrawing = !0, this.activeAnnotation = {
252
- id: n,
255
+ id: i,
253
256
  type: "polygon",
254
257
  label: "",
255
258
  coordinates: { points: [t] },
256
259
  style: { strokeColor: this.currentLabelColor }
257
260
  });
258
261
  else if (this.currentTool === "category") {
259
- const e = {
260
- id: n,
262
+ const n = {
263
+ id: i,
261
264
  type: "category",
262
265
  label: "",
263
266
  // 将被填充
@@ -265,9 +268,9 @@ class Pt {
265
268
  // 或位置?
266
269
  style: { strokeColor: this.currentLabelColor }
267
270
  };
268
- this.annotations.push(e), this.emit("annotationChange", { action: "add", changedItem: e, imageUrl: this.imageUrl }), this.activeAnnotation = e;
271
+ this.annotations.push(n), this.emit("annotationChange", { action: "add", changedItem: n, imageUrl: this.imageUrl }), this.activeAnnotation = n;
269
272
  } else this.currentTool === "rotatedRect" && (this.isDrawing = !0, this.dragStartPoint = t, this.activeAnnotation = {
270
- id: n,
273
+ id: i,
271
274
  type: "rotatedRect",
272
275
  label: "",
273
276
  coordinates: { x: t.x, y: t.y, width: 0, height: 0, angle: 0 },
@@ -277,11 +280,11 @@ class Pt {
277
280
  updateDrawing(t) {
278
281
  if (this.activeAnnotation)
279
282
  if (this.activeAnnotation.type === "rectangle" && this.dragStartPoint) {
280
- const n = this.activeAnnotation.coordinates;
281
- n.x2 = t.x, n.y2 = t.y;
283
+ const i = this.activeAnnotation.coordinates;
284
+ i.x2 = t.x, i.y2 = t.y;
282
285
  } else if (this.activeAnnotation.type === "rotatedRect" && this.dragStartPoint) {
283
- const n = this.activeAnnotation.coordinates, e = Math.abs(t.x - this.dragStartPoint.x), a = Math.abs(t.y - this.dragStartPoint.y);
284
- n.width = e * 2, n.height = a * 2;
286
+ const i = this.activeAnnotation.coordinates, n = Math.abs(t.x - this.dragStartPoint.x), r = Math.abs(t.y - this.dragStartPoint.y);
287
+ i.width = n * 2, i.height = r * 2;
285
288
  } else this.activeAnnotation.type;
286
289
  }
287
290
  finishDrawing() {
@@ -292,8 +295,8 @@ class Pt {
292
295
  this.activeAnnotation = null, this.isDrawing = !1;
293
296
  return;
294
297
  }
295
- const n = Math.min(t.x1, t.x2), e = Math.max(t.x1, t.x2), a = Math.min(t.y1, t.y2), o = Math.max(t.y1, t.y2);
296
- t.x1 = n, t.x2 = e, t.y1 = a, t.y2 = o, this.annotations.push(this.activeAnnotation), this.emit("annotationChange", { action: "add", changedItem: this.activeAnnotation, imageUrl: this.imageUrl });
298
+ const i = Math.min(t.x1, t.x2), n = Math.max(t.x1, t.x2), r = Math.min(t.y1, t.y2), o = Math.max(t.y1, t.y2);
299
+ t.x1 = i, t.x2 = n, t.y1 = r, t.y2 = o, this.annotations.push(this.activeAnnotation), this.emit("annotationChange", { action: "add", changedItem: this.activeAnnotation, imageUrl: this.imageUrl });
297
300
  } else if (this.activeAnnotation.type === "polygon") {
298
301
  if (this.activeAnnotation.coordinates.points.length < 3) {
299
302
  this.activeAnnotation = null, this.isDrawing = !1;
@@ -314,89 +317,89 @@ class Pt {
314
317
  }
315
318
  updateDragging(t) {
316
319
  if (!this.activeAnnotation || !this.dragStartPoint || !this.dragStartAnnotation) return;
317
- const n = t.x - this.dragStartPoint.x, e = t.y - this.dragStartPoint.y;
318
- this.selectedHandleIndex === -1 ? this.moveAnnotation(this.activeAnnotation, this.dragStartAnnotation, n, e) : this.resizeAnnotation(this.activeAnnotation, this.dragStartAnnotation, this.selectedHandleIndex, t);
320
+ const i = t.x - this.dragStartPoint.x, n = t.y - this.dragStartPoint.y;
321
+ this.selectedHandleIndex === -1 ? this.moveAnnotation(this.activeAnnotation, this.dragStartAnnotation, i, n) : this.resizeAnnotation(this.activeAnnotation, this.dragStartAnnotation, this.selectedHandleIndex, t);
319
322
  }
320
- moveAnnotation(t, n, e, a) {
323
+ moveAnnotation(t, i, n, r) {
321
324
  if (t.type === "rectangle") {
322
- const o = n.coordinates, r = t.coordinates;
323
- r.x1 = o.x1 + e, r.x2 = o.x2 + e, r.y1 = o.y1 + a, r.y2 = o.y2 + a;
325
+ const o = i.coordinates, c = t.coordinates;
326
+ c.x1 = o.x1 + n, c.x2 = o.x2 + n, c.y1 = o.y1 + r, c.y2 = o.y2 + r;
324
327
  } else if (t.type === "point") {
325
- const o = n.coordinates, r = t.coordinates;
326
- r.points = o.points.map((i) => ({ x: i.x + e, y: i.y + a }));
328
+ const o = i.coordinates, c = t.coordinates;
329
+ c.points = o.points.map((a) => ({ x: a.x + n, y: a.y + r }));
327
330
  } else if (t.type === "rotatedRect") {
328
- const o = n.coordinates, r = t.coordinates;
329
- r.x = o.x + e, r.y = o.y + a;
331
+ const o = i.coordinates, c = t.coordinates;
332
+ c.x = o.x + n, c.y = o.y + r;
330
333
  } else if (t.type === "polygon") {
331
- const o = n.coordinates, r = t.coordinates;
332
- r.points = o.points.map((i) => ({ x: i.x + e, y: i.y + a }));
334
+ const o = i.coordinates, c = t.coordinates;
335
+ c.points = o.points.map((a) => ({ x: a.x + n, y: a.y + r }));
333
336
  }
334
337
  }
335
- resizeAnnotation(t, n, e, a) {
338
+ resizeAnnotation(t, i, n, r) {
336
339
  if (t.type === "rectangle") {
337
340
  const o = t.coordinates;
338
- e === 0 && (o.x1 = a.x, o.y1 = a.y), e === 1 && (o.x2 = a.x, o.y1 = a.y), e === 2 && (o.x2 = a.x, o.y2 = a.y), e === 3 && (o.x1 = a.x, o.y2 = a.y);
341
+ n === 0 && (o.x1 = r.x, o.y1 = r.y), n === 1 && (o.x2 = r.x, o.y1 = r.y), n === 2 && (o.x2 = r.x, o.y2 = r.y), n === 3 && (o.x1 = r.x, o.y2 = r.y);
339
342
  } else if (t.type === "polygon") {
340
343
  const o = t.coordinates;
341
- e >= 0 && e < o.points.length && (o.points[e] = a);
344
+ n >= 0 && n < o.points.length && (o.points[n] = r);
342
345
  } else if (t.type === "point") {
343
346
  const o = t.coordinates;
344
- e >= 0 && e < o.points.length && (o.points[e] = a);
347
+ n >= 0 && n < o.points.length && (o.points[n] = r);
345
348
  } else if (t.type === "rotatedRect") {
346
349
  const o = t.coordinates;
347
- if (e === -2) {
348
- const r = o.x, i = o.y, h = a.x - r, m = a.y - i;
349
- let g = Math.atan2(m, h) * 180 / Math.PI;
350
- g += 90, o.angle = g;
350
+ if (n === -2) {
351
+ const c = o.x, a = o.y, d = r.x - c, p = r.y - a;
352
+ let w = Math.atan2(p, d) * 180 / Math.PI;
353
+ w += 90, o.angle = w;
351
354
  } else {
352
- const r = o.angle * Math.PI / 180, i = Math.cos(-r), h = Math.sin(-r), m = a.x - o.x, g = a.y - o.y, u = m * i - g * h, f = m * h + g * i;
353
- (e === 0 || e === 3) && (o.width / 2, o.width = Math.abs(u) * 2), (e === 1 || e === 2) && (o.width = Math.abs(u) * 2), (e === 0 || e === 1) && (o.height = Math.abs(f) * 2), (e === 2 || e === 3) && (o.height = Math.abs(f) * 2);
355
+ const c = o.angle * Math.PI / 180, a = Math.cos(-c), d = Math.sin(-c), p = r.x - o.x, w = r.y - o.y, u = p * a - w * d, f = p * d + w * a;
356
+ (n === 0 || n === 3) && (o.width / 2, o.width = Math.abs(u) * 2), (n === 1 || n === 2) && (o.width = Math.abs(u) * 2), (n === 0 || n === 1) && (o.height = Math.abs(f) * 2), (n === 2 || n === 3) && (o.height = Math.abs(f) * 2);
354
357
  }
355
358
  }
356
359
  }
357
360
  // --- 命中测试和渲染辅助函数 ---
358
361
  getHitAnnotation(t) {
359
- for (let n = this.annotations.length - 1; n >= 0; n--) {
360
- const e = this.annotations[n];
361
- if (this.isPointInAnnotation(t, e))
362
- return e;
362
+ for (let i = this.annotations.length - 1; i >= 0; i--) {
363
+ const n = this.annotations[i];
364
+ if (this.isPointInAnnotation(t, n))
365
+ return n;
363
366
  }
364
367
  return null;
365
368
  }
366
- isPointInAnnotation(t, n) {
367
- if (n.type === "rectangle") {
368
- const e = n.coordinates;
369
- return t.x >= e.x1 && t.x <= e.x2 && t.y >= e.y1 && t.y <= e.y2;
370
- } else if (n.type === "polygon") {
371
- const e = n.coordinates;
372
- return Ht(t, e.points);
373
- } else if (n.type === "rotatedRect") {
374
- const e = n.coordinates, a = st(t, { x: e.x, y: e.y }, -e.angle), o = e.width / 2, r = e.height / 2;
375
- return a.x >= e.x - o && a.x <= e.x + o && a.y >= e.y - r && a.y <= e.y + r;
376
- } else if (n.type === "point")
377
- return n.coordinates.points.some((a) => Y(t, a) < 10 / this.scale);
369
+ isPointInAnnotation(t, i) {
370
+ if (i.type === "rectangle") {
371
+ const n = i.coordinates;
372
+ return t.x >= n.x1 && t.x <= n.x2 && t.y >= n.y1 && t.y <= n.y2;
373
+ } else if (i.type === "polygon") {
374
+ const n = i.coordinates;
375
+ return Gt(t, n.points);
376
+ } else if (i.type === "rotatedRect") {
377
+ const n = i.coordinates, r = mt(t, { x: n.x, y: n.y }, -n.angle), o = n.width / 2, c = n.height / 2;
378
+ return r.x >= n.x - o && r.x <= n.x + o && r.y >= n.y - c && r.y <= n.y + c;
379
+ } else if (i.type === "point")
380
+ return i.coordinates.points.some((r) => at(t, r) < 10 / this.scale);
378
381
  return !1;
379
382
  }
380
- getHitHandle(t, n, e) {
381
- const a = this.getAnnotationHandles(e), o = 6;
382
- for (let r = 0; r < a.length; r++) {
383
- const i = a[r], h = this.toScreenCoords(i.x, i.y);
384
- if (Math.abs(t - h.x) < o && Math.abs(n - h.y) < o)
385
- return e.type === "rotatedRect" && r === 4 ? -2 : r;
383
+ getHitHandle(t, i, n) {
384
+ const r = this.getAnnotationHandles(n), o = 6;
385
+ for (let c = 0; c < r.length; c++) {
386
+ const a = r[c], d = this.toScreenCoords(a.x, a.y);
387
+ if (Math.abs(t - d.x) < o && Math.abs(i - d.y) < o)
388
+ return n.type === "rotatedRect" && c === 4 ? -2 : c;
386
389
  }
387
390
  return -100;
388
391
  }
389
392
  getAnnotationHandles(t) {
390
393
  if (t.type === "rectangle") {
391
- const n = t.coordinates;
394
+ const i = t.coordinates;
392
395
  return [
393
- { x: n.x1, y: n.y1 },
396
+ { x: i.x1, y: i.y1 },
394
397
  // 左上
395
- { x: n.x2, y: n.y1 },
398
+ { x: i.x2, y: i.y1 },
396
399
  // 右上
397
- { x: n.x2, y: n.y2 },
400
+ { x: i.x2, y: i.y2 },
398
401
  // 右下
399
- { x: n.x1, y: n.y2 }
402
+ { x: i.x1, y: i.y2 }
400
403
  // 左下
401
404
  ];
402
405
  } else {
@@ -405,23 +408,23 @@ class Pt {
405
408
  if (t.type === "point")
406
409
  return t.coordinates.points;
407
410
  if (t.type === "rotatedRect") {
408
- const n = t.coordinates, e = { x: n.x, y: n.y }, a = n.width / 2, o = n.height / 2, r = { x: n.x - a, y: n.y - o }, i = { x: n.x + a, y: n.y - o }, h = { x: n.x + a, y: n.y + o }, m = { x: n.x - a, y: n.y + o }, g = { x: n.x, y: n.y - o - 20 / this.scale };
409
- return [r, i, h, m, g].map((u) => st(u, e, n.angle));
411
+ const i = t.coordinates, n = { x: i.x, y: i.y }, r = i.width / 2, o = i.height / 2, c = { x: i.x - r, y: i.y - o }, a = { x: i.x + r, y: i.y - o }, d = { x: i.x + r, y: i.y + o }, p = { x: i.x - r, y: i.y + o }, w = { x: i.x, y: i.y - o - 20 / this.scale };
412
+ return [c, a, d, p, w].map((u) => mt(u, n, i.angle));
410
413
  }
411
414
  }
412
415
  return [];
413
416
  }
414
- checkHover(t, n, e) {
415
- const a = this.getHitCategory(t, n);
416
- if (a) {
417
- this.canvas.style.cursor = "pointer", this.hoverAnnotation = a;
417
+ checkHover(t, i, n) {
418
+ const r = this.getHitCategory(t, i);
419
+ if (r) {
420
+ this.canvas.style.cursor = "pointer", this.hoverAnnotation = r;
418
421
  return;
419
422
  }
420
- if (this.activeAnnotation && this.getHitHandle(t, n, this.activeAnnotation) !== -100) {
423
+ if (this.activeAnnotation && this.getHitHandle(t, i, this.activeAnnotation) !== -100) {
421
424
  this.canvas.style.cursor = "pointer";
422
425
  return;
423
426
  }
424
- const o = this.getHitAnnotation(e);
427
+ const o = this.getHitAnnotation(n);
425
428
  o ? (this.canvas.style.cursor = "move", this.hoverAnnotation = o) : (this.canvas.style.cursor = "default", this.hoverAnnotation = null);
426
429
  }
427
430
  render() {
@@ -430,158 +433,169 @@ class Pt {
430
433
  }), this.activeAnnotation && this.drawItem(this.activeAnnotation, !0), this.renderCategories();
431
434
  }
432
435
  renderCategories() {
433
- const t = this.annotations.filter((h) => h.type === "category");
436
+ const t = this.annotations.filter((d) => d.type === "category");
434
437
  if (t.length === 0) return;
435
438
  this.ctx.save(), this.ctx.font = "14px sans-serif", this.ctx.textBaseline = "top";
436
- let n = 10;
437
- const e = 10, a = 8, o = 4, r = 24, i = 8;
438
- t.forEach((h) => {
439
- const m = h.label || "Unlabeled", g = this.ctx.measureText(m).width + a * 2, u = this.activeAnnotation === h, f = this.hoverAnnotation === h;
440
- this.ctx.fillStyle = u ? "#E3F2FD" : f ? "#F5F5F5" : "rgba(255, 255, 255, 0.9)", this.ctx.strokeStyle = u ? "#2196F3" : "#666", this.ctx.lineWidth = u ? 2 : 1, this.ctx.beginPath(), this.ctx.rect(n, e, g, r), this.ctx.fill(), this.ctx.stroke(), this.ctx.fillStyle = u ? "#1976D2" : "#333", this.ctx.fillText(m, n + a, e + o), n += g + i;
439
+ let i = 10;
440
+ const n = 10, r = 8, o = 4, c = 24, a = 8;
441
+ t.forEach((d) => {
442
+ const p = d.label || "Unlabeled", w = this.ctx.measureText(p).width + r * 2, u = this.activeAnnotation === d, f = this.hoverAnnotation === d;
443
+ this.ctx.fillStyle = u ? "#E3F2FD" : f ? "#F5F5F5" : "rgba(255, 255, 255, 0.9)", this.ctx.strokeStyle = u ? "#2196F3" : "#666", this.ctx.lineWidth = u ? 2 : 1, this.ctx.beginPath(), this.ctx.rect(i, n, w, c), this.ctx.fill(), this.ctx.stroke(), this.ctx.fillStyle = u ? "#1976D2" : "#333", this.ctx.fillText(p, i + r, n + o), i += w + a;
441
444
  }), this.ctx.restore();
442
445
  }
443
- getHitCategory(t, n) {
444
- const e = this.annotations.filter((g) => g.type === "category");
445
- if (e.length === 0) return null;
446
+ getHitCategory(t, i) {
447
+ const n = this.annotations.filter((w) => w.type === "category");
448
+ if (n.length === 0) return null;
446
449
  this.ctx.save(), this.ctx.font = "14px sans-serif";
447
- let a = 10;
448
- const o = 10, r = 8, i = 24, h = 8;
449
- let m = null;
450
- for (const g of e) {
451
- const u = g.label || "Unlabeled", f = this.ctx.measureText(u).width + r * 2;
452
- if (t >= a && t <= a + f && n >= o && n <= o + i) {
453
- m = g;
450
+ let r = 10;
451
+ const o = 10, c = 8, a = 24, d = 8;
452
+ let p = null;
453
+ for (const w of n) {
454
+ const u = w.label || "Unlabeled", f = this.ctx.measureText(u).width + c * 2;
455
+ if (t >= r && t <= r + f && i >= o && i <= o + a) {
456
+ p = w;
454
457
  break;
455
458
  }
456
- a += f + h;
459
+ r += f + d;
457
460
  }
458
- return this.ctx.restore(), m;
461
+ return this.ctx.restore(), p;
459
462
  }
460
- drawItem(t, n) {
463
+ drawItem(t, i) {
461
464
  var o;
462
- if (this.visibleLabels.size > 0 && !this.visibleLabels.has(t.label) && !n)
465
+ if (this.visibleLabels.size > 0 && !this.visibleLabels.has(t.label) && !i)
463
466
  return;
464
467
  this.ctx.save();
465
- const e = ((o = t.style) == null ? void 0 : o.strokeColor) || "#FF4081", a = n ? "#00E5FF" : e;
466
- if (this.ctx.strokeStyle = a, this.ctx.lineWidth = 2, n ? this.ctx.fillStyle = "rgba(0, 229, 255, 0.2)" : this.ctx.fillStyle = this.hexToRgba(e, 0.2), t.type === "rectangle") {
467
- const r = t.coordinates, i = this.toScreenCoords(r.x1, r.y1), h = this.toScreenCoords(r.x2, r.y2), m = Math.min(i.x, h.x), g = Math.min(i.y, h.y), u = Math.abs(i.x - h.x), f = Math.abs(i.y - h.y);
468
- this.ctx.strokeRect(m, g, u, f), this.ctx.fillStyle = n ? "rgba(0, 229, 255, 0.2)" : "rgba(255, 64, 129, 0.2)", this.ctx.fillRect(m, g, u, f), n && this.drawHandles(this.getAnnotationHandles(t));
468
+ const n = ((o = t.style) == null ? void 0 : o.strokeColor) || "#FF4081", r = i ? "#00E5FF" : n;
469
+ if (this.ctx.strokeStyle = r, this.ctx.lineWidth = 2, i ? this.ctx.fillStyle = "rgba(0, 229, 255, 0.2)" : this.ctx.fillStyle = this.hexToRgba(n, 0.2), t.type === "rectangle") {
470
+ const c = t.coordinates, a = this.toScreenCoords(c.x1, c.y1), d = this.toScreenCoords(c.x2, c.y2), p = Math.min(a.x, d.x), w = Math.min(a.y, d.y), u = Math.abs(a.x - d.x), f = Math.abs(a.y - d.y);
471
+ this.ctx.strokeRect(p, w, u, f), this.ctx.fillStyle = i ? "rgba(0, 229, 255, 0.2)" : "rgba(255, 64, 129, 0.2)", this.ctx.fillRect(p, w, u, f), i && this.drawHandles(this.getAnnotationHandles(t));
469
472
  } else if (t.type === "polygon") {
470
- const r = t.coordinates;
471
- if (r.points.length === 0) {
473
+ const c = t.coordinates;
474
+ if (c.points.length === 0) {
472
475
  this.ctx.restore();
473
476
  return;
474
477
  }
475
478
  this.ctx.beginPath();
476
- const i = this.toScreenCoords(r.points[0].x, r.points[0].y);
477
- this.ctx.moveTo(i.x, i.y);
478
- for (let h = 1; h < r.points.length; h++) {
479
- const m = this.toScreenCoords(r.points[h].x, r.points[h].y);
480
- this.ctx.lineTo(m.x, m.y);
479
+ const a = this.toScreenCoords(c.points[0].x, c.points[0].y);
480
+ this.ctx.moveTo(a.x, a.y);
481
+ for (let d = 1; d < c.points.length; d++) {
482
+ const p = this.toScreenCoords(c.points[d].x, c.points[d].y);
483
+ this.ctx.lineTo(p.x, p.y);
481
484
  }
482
485
  if (!this.isDrawing || t !== this.activeAnnotation)
483
486
  this.ctx.closePath();
484
487
  else if (this.lastMouseMovePoint) {
485
- let h = this.lastMouseMovePoint;
486
- if (this.isHoveringStartPoint && r.points.length > 0) {
487
- h = r.points[0];
488
- const g = this.toScreenCoords(r.points[0].x, r.points[0].y);
489
- this.ctx.save(), this.ctx.beginPath(), this.ctx.arc(g.x, g.y, 10, 0, Math.PI * 2), this.ctx.fillStyle = "rgba(255, 215, 0, 0.6)", this.ctx.strokeStyle = "#FFFFFF", this.ctx.lineWidth = 2, this.ctx.fill(), this.ctx.stroke(), this.ctx.restore();
488
+ let d = this.lastMouseMovePoint;
489
+ if (this.isHoveringStartPoint && c.points.length > 0) {
490
+ d = c.points[0];
491
+ const w = this.toScreenCoords(c.points[0].x, c.points[0].y);
492
+ this.ctx.save(), this.ctx.beginPath(), this.ctx.arc(w.x, w.y, 10, 0, Math.PI * 2), this.ctx.fillStyle = "rgba(255, 215, 0, 0.6)", this.ctx.strokeStyle = "#FFFFFF", this.ctx.lineWidth = 2, this.ctx.fill(), this.ctx.stroke(), this.ctx.restore();
490
493
  }
491
- const m = this.toScreenCoords(h.x, h.y);
492
- this.ctx.lineTo(m.x, m.y);
494
+ const p = this.toScreenCoords(d.x, d.y);
495
+ this.ctx.lineTo(p.x, p.y);
493
496
  }
494
- this.ctx.stroke(), this.ctx.fillStyle = n ? "rgba(0, 229, 255, 0.2)" : "rgba(255, 64, 129, 0.2)", this.ctx.fill(), n && this.drawHandles(this.getAnnotationHandles(t));
497
+ this.ctx.stroke(), this.ctx.fillStyle = i ? "rgba(0, 229, 255, 0.2)" : "rgba(255, 64, 129, 0.2)", this.ctx.fill(), i && this.drawHandles(this.getAnnotationHandles(t));
495
498
  } else if (t.type === "rotatedRect") {
496
- const r = t.coordinates;
497
- this.ctx.translate(this.toScreenCoords(r.x, r.y).x, this.toScreenCoords(r.x, r.y).y), this.ctx.rotate(r.angle * Math.PI / 180);
498
- const i = r.width * this.scale, h = r.height * this.scale;
499
- this.ctx.strokeRect(-i / 2, -h / 2, i, h), this.ctx.fillStyle = n ? "rgba(0, 229, 255, 0.2)" : "rgba(255, 64, 129, 0.2)", this.ctx.fillRect(-i / 2, -h / 2, i, h), this.ctx.rotate(-r.angle * Math.PI / 180), this.ctx.translate(-this.toScreenCoords(r.x, r.y).x, -this.toScreenCoords(r.x, r.y).y), n && this.drawHandles(this.getAnnotationHandles(t));
500
- } else t.type === "point" && t.coordinates.points.forEach((i) => {
501
- const h = this.toScreenCoords(i.x, i.y);
502
- this.ctx.beginPath(), this.ctx.arc(h.x, h.y, 5, 0, Math.PI * 2), this.ctx.fillStyle = n ? "#00E5FF" : e, this.ctx.fill(), this.ctx.stroke();
499
+ const c = t.coordinates;
500
+ this.ctx.translate(this.toScreenCoords(c.x, c.y).x, this.toScreenCoords(c.x, c.y).y), this.ctx.rotate(c.angle * Math.PI / 180);
501
+ const a = c.width * this.scale, d = c.height * this.scale;
502
+ this.ctx.strokeRect(-a / 2, -d / 2, a, d), this.ctx.fillStyle = i ? "rgba(0, 229, 255, 0.2)" : "rgba(255, 64, 129, 0.2)", this.ctx.fillRect(-a / 2, -d / 2, a, d), this.ctx.rotate(-c.angle * Math.PI / 180), this.ctx.translate(-this.toScreenCoords(c.x, c.y).x, -this.toScreenCoords(c.x, c.y).y), i && this.drawHandles(this.getAnnotationHandles(t));
503
+ } else t.type === "point" && t.coordinates.points.forEach((a) => {
504
+ const d = this.toScreenCoords(a.x, a.y);
505
+ this.ctx.beginPath(), this.ctx.arc(d.x, d.y, 5, 0, Math.PI * 2), this.ctx.fillStyle = i ? "#00E5FF" : n, this.ctx.fill(), this.ctx.stroke();
503
506
  });
504
507
  this.ctx.restore();
505
508
  }
506
509
  drawHandles(t) {
507
- this.ctx.fillStyle = "#FFFFFF", this.ctx.strokeStyle = "#000000", this.ctx.lineWidth = 1, t.forEach((n) => {
508
- const e = this.toScreenCoords(n.x, n.y);
509
- this.ctx.fillRect(e.x - 4, e.y - 4, 8, 8), this.ctx.strokeRect(e.x - 4, e.y - 4, 8, 8);
510
+ this.ctx.fillStyle = "#FFFFFF", this.ctx.strokeStyle = "#000000", this.ctx.lineWidth = 1, t.forEach((i) => {
511
+ const n = this.toScreenCoords(i.x, i.y);
512
+ this.ctx.fillRect(n.x - 4, n.y - 4, 8, 8), this.ctx.strokeRect(n.x - 4, n.y - 4, 8, 8);
510
513
  });
511
514
  }
512
515
  }
513
- const Lt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
516
+ const Zt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
514
517
  <path d="M512 896a384 384 0 1 0 0-768 384 384 0 0 0 0 768zm0 64a448 448 0 1 1 0-896 448 448 0 0 1 0 896z m0-320a64 64 0 1 0 0-128 64 64 0 0 0 0 128z m0 64a128 128 0 1 1 0-256 128 128 0 0 1 0 256z" fill="currentColor"/>\r
515
- </svg>`, Tt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
518
+ </svg>`, Qt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
516
519
  <path d="M609.408 149.376l-277.76 277.76a96 96 0 0 0 0 135.68l277.76 277.76a32 32 0 1 0 45.248-45.248L376.96 512l277.76-277.76a32 32 0 0 0-45.248-45.248z" fill="currentColor"/>\r
517
- </svg>`, $t = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
520
+ </svg>`, te = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
518
521
  <path d="M704 192h160v160h-160z m-64-64v288h288V128H640zM160 672h160v160H160z m-64-64v288h288V608H96z m256-320h320v64H352z" fill="currentColor"/>\r
519
- </svg>`, Dt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
522
+ </svg>`, ee = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
520
523
  <path d="M256 256h512v512H256z m-64-64v640h640V192H192z" fill="currentColor"/>\r
521
- </svg>`, Rt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
524
+ </svg>`, ne = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
522
525
  <path d="M160 256h704a32 32 0 1 1 0 64h-64v608a32 32 0 0 1-32 32H256a32 32 0 0 1-32-32V320h-64a32 32 0 1 1 0-64zm128 64v576h448V320H288z m128 0v512a32 32 0 1 1-64 0V320a32 32 0 1 1 64 0zm256 0v512a32 32 0 1 1-64 0V320a32 32 0 1 1 64 0zM352 128h320a32 32 0 0 1 32 32v64H320v-64a32 32 0 0 1 32-32z" fill="currentColor"/>\r
523
- </svg>`, Ut = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
526
+ </svg>`, se = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
524
527
  <path d="M512 666.56l-186.88-186.88a32 32 0 0 0-45.248 45.248l209.536 209.536a96 96 0 0 0 135.68 0l209.536-209.536a32 32 0 1 0-45.248-45.248L544 666.56V128a32 32 0 0 0-64 0v538.56zM192 832h640a32 32 0 1 1 0 64H192a32 32 0 1 1 0-64z" fill="currentColor"/>\r
525
- </svg>`, Ft = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
528
+ </svg>`, ie = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
526
529
  <path d="M832 512a32 32 0 1 1 64 0v352a32 32 0 0 1-32 32H160a32 32 0 0 1-32-32V160a32 32 0 0 1 32-32h352a32 32 0 0 1 0 64H192v640h640V512z m-144-320l-480 480v160h160l480-480-160-160z m-114.56 480H256v-117.76L653.44 236.8l117.76 117.76L573.44 672z m208-208l-117.76-117.76 66.56-66.56a32 32 0 0 1 45.248 0l72.512 72.512a32 32 0 0 1 0 45.248l-66.56 66.56z" fill="currentColor"/>\r
527
- </svg>`, Bt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
530
+ </svg>`, oe = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
528
531
  <path d="M940.48 876.16L148.16 83.84a32 32 0 1 0-45.12 45.12L236.8 262.4C163.52 337.28 107.52 429.12 82.56 528.96a32 32 0 0 0 0 20.48C144.384 727.68 314.88 840.96 512 840.96c103.04 0 199.36-30.72 283.52-83.84l99.84 99.84a32 32 0 1 0 45.12-45.12zM512 776.96c-176.64 0-333.44-98.56-402.56-248.96 25.6-56.32 63.36-107.52 110.08-151.04L364.8 522.24a128 128 0 0 0 147.2 147.2l123.52 123.52A445.44 445.44 0 0 1 512 776.96z m373.12-32.64l-64-64C857.6 627.84 879.616 572.16 879.616 512c0-176.64-156.8-328.96-367.616-328.96-58.24 0-113.6 11.52-164.48 32.64l-55.68-55.68C346.88 136.96 427.52 119.04 512 119.04c229.76 0 425.216 142.08 493.44 346.24a32 32 0 0 1 0 20.48 450.56 450.56 0 0 1-120.32 258.56z m-309.12-309.12l-128-128A128 128 0 0 1 576 435.2z" fill="currentColor"/>\r
529
- </svg>`, Ot = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
532
+ </svg>`, ae = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
530
533
  <path d="M512 64a448 448 0 1 1 0 896 448 448 0 0 1 0-896zm0 832a384 384 0 1 0 0-768 384 384 0 0 0 0 768zm-48-384H320a32 32 0 0 1 0-64h144V304a32 32 0 1 1 64 0v144h144a32 32 0 1 1 0 64H528v144a32 32 0 1 1-64 0V512z" fill="currentColor"/>\r
531
- </svg>`, Et = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
534
+ </svg>`, le = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
532
535
  <path d="M224 448a32 32 0 0 0 9.536 22.592l416 416a32 32 0 0 0 45.248 0l226.24-226.24a32 32 0 0 0 0-45.248l-416-416A32 32 0 0 0 482.432 192H256a64 64 0 0 0-64 64v192z m64-192h160l384 384-160 160-384-384V256z m64 128a64 64 0 1 0 0-128 64 64 0 0 0 0 128z" fill="currentColor"/>\r
533
- </svg>`, Vt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
536
+ </svg>`, re = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
534
537
  <path d="M160 832h704a32 32 0 1 1 0 64H160a32 32 0 1 1 0-64zm0-704h704a32 32 0 1 1 0 64H160a32 32 0 1 1 0-64zm0 352h704a32 32 0 1 1 0 64H160a32 32 0 1 1 0-64z" fill="currentColor"/>\r
535
- </svg>`, Nt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
538
+ </svg>`, ce = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
536
539
  <path d="M784.512 230.272v-50.56a32 32 0 1 1 64 0v149.056a32 32 0 0 1-32 32H667.52a32 32 0 1 1 0-64h92.992A320 320 0 1 0 524.8 833.152a320 320 0 0 0 320-320h64a384 384 0 0 1-384 384 384 384 0 0 1-384-384 384 384 0 0 1 643.712-282.88z" fill="currentColor"/>\r
537
- </svg>`, Jt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
540
+ </svg>`, he = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
538
541
  <path d="M340.864 149.376a32 32 0 0 0-45.248 45.248L573.44 512l-277.76 317.376a32 32 0 0 0 45.248 45.248l277.76-277.76a96 96 0 0 0 0-135.68L340.864 149.376z" fill="currentColor"/>\r
539
- </svg>`, jt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
542
+ </svg>`, de = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
540
543
  <path d="M512 192c229.76 0 425.216 142.08 493.44 346.24a32 32 0 0 1 0 20.48C937.216 762.88 741.76 904.96 512 904.96S86.784 762.88 18.56 558.72a32 32 0 0 1 0-20.48C86.784 334.08 282.24 192 512 192zm0 64c-197.12 0-367.616 120.32-428.16 296.32C144.384 727.68 314.88 840.96 512 840.96s367.616-113.28 428.16-288.64C879.616 376.32 709.12 256 512 256zm0 160a128 128 0 1 1 0 256 128 128 0 0 1 0-256zm0 64a64 64 0 1 0 0 128 64 64 0 0 0 0-128z" fill="currentColor"/>\r
541
- </svg>`, Wt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
544
+ </svg>`, ge = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
542
545
  <path d="M637.12 693.376l182.208 182.208a32 32 0 1 1-45.248 45.248L591.872 738.624a352 352 0 1 1 45.248-45.248z m-45.248-45.248A288 288 0 1 0 183.872 240.128a288 288 0 0 0 408 408zM416 448h96a32 32 0 0 1 0 64h-96v96a32 32 0 0 1-64 0v-96h-96a32 32 0 0 1 0-64h96v-96a32 32 0 0 1 64 0v96z" fill="currentColor"/>\r
543
- </svg>`, qt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
546
+ </svg>`, ue = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
544
547
  <path d="M637.12 693.376l182.208 182.208a32 32 0 1 1-45.248 45.248L591.872 738.624a352 352 0 1 1 45.248-45.248z m-45.248-45.248A288 288 0 1 0 183.872 240.128a288 288 0 0 0 408 408zM256 448h320a32 32 0 1 1 0 64H256a32 32 0 1 1 0-64z" fill="currentColor"/>\r
545
- </svg>`, Xt = ["innerHTML"], Yt = /* @__PURE__ */ N({
548
+ </svg>`, ve = ["innerHTML"], me = /* @__PURE__ */ Q({
546
549
  __name: "SvgIcon",
547
550
  props: {
548
551
  name: {},
549
552
  size: {}
550
553
  },
551
- setup(v) {
552
- const t = v, n = S(""), e = /* @__PURE__ */ Object.assign({ "../assets/svg/aim.svg": Lt, "../assets/svg/back.svg": Tt, "../assets/svg/connection.svg": $t, "../assets/svg/crop.svg": Dt, "../assets/svg/delete.svg": Rt, "../assets/svg/download.svg": Ut, "../assets/svg/edit.svg": Ft, "../assets/svg/hide.svg": Bt, "../assets/svg/pointer.svg": Ot, "../assets/svg/price-tag.svg": Et, "../assets/svg/rank.svg": Vt, "../assets/svg/refresh-right.svg": Nt, "../assets/svg/right.svg": Jt, "../assets/svg/view.svg": jt, "../assets/svg/zoom-in.svg": Wt, "../assets/svg/zoom-out.svg": qt });
553
- return St(() => {
554
- const a = `../assets/svg/${t.name}.svg`, o = e[a];
555
- o ? n.value = o : (console.warn(`Icon ${t.name} not found at path ${a}`), n.value = "");
556
- }), (a, o) => (x(), b("i", {
557
- class: $(["svg-icon", [v.size ? `size-${v.size}` : ""]]),
558
- innerHTML: n.value
559
- }, null, 10, Xt));
554
+ setup(m) {
555
+ const t = m, i = k(""), n = /* @__PURE__ */ Object.assign({ "../assets/svg/aim.svg": Zt, "../assets/svg/back.svg": Qt, "../assets/svg/connection.svg": te, "../assets/svg/crop.svg": ee, "../assets/svg/delete.svg": ne, "../assets/svg/download.svg": se, "../assets/svg/edit.svg": ie, "../assets/svg/hide.svg": oe, "../assets/svg/pointer.svg": ae, "../assets/svg/price-tag.svg": le, "../assets/svg/rank.svg": re, "../assets/svg/refresh-right.svg": ce, "../assets/svg/right.svg": he, "../assets/svg/view.svg": de, "../assets/svg/zoom-in.svg": ge, "../assets/svg/zoom-out.svg": ue });
556
+ return Xt(() => {
557
+ const r = `../assets/svg/${t.name}.svg`, o = n[r];
558
+ o ? i.value = o : (console.warn(`Icon ${t.name} not found at path ${r}`), i.value = "");
559
+ }), (r, o) => (y(), b("i", {
560
+ class: E(["svg-icon", [m.size ? `size-${m.size}` : ""]]),
561
+ innerHTML: i.value
562
+ }, null, 10, ve));
560
563
  }
561
- }), J = (v, t) => {
562
- const n = v.__vccOpts || v;
563
- for (const [e, a] of t)
564
- n[e] = a;
565
- return n;
566
- }, M = /* @__PURE__ */ J(Yt, [["__scopeId", "data-v-3928607b"]]), Kt = {
564
+ }), tt = (m, t) => {
565
+ const i = m.__vccOpts || m;
566
+ for (const [n, r] of t)
567
+ i[n] = r;
568
+ return i;
569
+ }, T = /* @__PURE__ */ tt(me, [["__scopeId", "data-v-3928607b"]]), fe = {
570
+ key: 0,
571
+ class: "image-list-sidebar"
572
+ }, ye = { class: "image-list-title" }, pe = { class: "image-list-scroll" }, be = ["onClick"], xe = { class: "image-list-stage" }, we = ["src", "alt"], Ce = {
567
573
  key: 0,
574
+ class: "thumb-overlay-layer"
575
+ }, _e = {
576
+ key: 1,
577
+ class: "thumb-overlay-svg",
578
+ viewBox: "0 0 100 100",
579
+ preserveAspectRatio: "none"
580
+ }, Ae = ["points"], Ie = { class: "image-list-text" }, ke = {
581
+ key: 1,
568
582
  class: "left-sidebar"
569
- }, Zt = ["onClick", "title"], Gt = { class: "center-area" }, Qt = {
583
+ }, Se = ["onClick", "title"], Me = { class: "center-area" }, ze = {
570
584
  key: 0,
571
585
  class: "top-bar"
572
- }, te = { class: "label-selector" }, ee = { class: "tags-row" }, ne = ["onClick"], se = {
586
+ }, $e = { class: "label-selector" }, Te = { class: "tags-row" }, Pe = ["onClick"], He = {
573
587
  key: 0,
574
588
  class: "no-labels"
575
- }, ie = {
589
+ }, Le = {
576
590
  key: 1,
577
591
  class: "batch-nav"
578
- }, oe = ["disabled"], ae = ["disabled"], le = {
579
- key: 1,
580
- class: "right-sidebar"
581
- }, re = { class: "label-list" }, ce = { class: "label-row" }, he = ["onUpdate:modelValue", "onChange"], de = ["title"], ge = ["onClick"], ve = { class: "action-icon more-actions" }, ue = ["onClick"], me = {
592
+ }, De = ["disabled"], Re = ["disabled"], Be = {
582
593
  key: 2,
594
+ class: "right-sidebar"
595
+ }, Ue = { class: "label-list" }, Fe = { class: "label-row" }, Ee = ["onUpdate:modelValue", "onChange"], Oe = ["title"], Ve = ["onClick"], Ne = { class: "action-icon more-actions" }, We = ["onClick"], Je = {
596
+ key: 3,
583
597
  class: "modal-overlay"
584
- }, fe = { class: "modal-content" }, ye = { class: "form-group" }, pe = { class: "form-group" }, xe = { class: "color-input-wrapper" }, be = /* @__PURE__ */ N({
598
+ }, je = { class: "modal-content" }, Xe = { class: "form-group" }, Ye = { class: "form-group" }, qe = { class: "color-input-wrapper" }, Ge = /* @__PURE__ */ Q({
585
599
  __name: "ImageAnnotator",
586
600
  props: {
587
601
  annotationTypes: { default: () => ["rectangle", "polygon", "point", "rotatedRect"] },
@@ -592,491 +606,582 @@ const Lt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" widt
592
606
  readOnly: { type: Boolean, default: !1 },
593
607
  image: {},
594
608
  predictionCandidates: {},
595
- reviewMode: {},
596
609
  session: {},
597
610
  requestId: {},
598
611
  minZoom: {},
599
612
  maxZoom: {}
600
613
  },
601
- emits: ["annotationChange", "batchChange", "labelChange", "ready", "error", "tool:change", "viewport:change", "annotation:add", "annotation:update", "annotation:delete", "annotation:select", "prediction:request", "prediction:loaded", "prediction:apply", "prediction:reject", "review:action", "qa:issue"],
602
- setup(v, { expose: t, emit: n }) {
603
- const e = v, a = n, o = S(null), r = S(null), i = S(null), h = S(null), m = S(0), g = S([]), u = S(""), f = S(!1), p = S({ name: "", color: "#FF0000" }), w = S("none"), k = S([]), I = () => {
604
- var c, y, _, A;
605
- const s = e.batchImages[m.value], l = (s == null ? void 0 : s.imageUrl) || ((c = e.image) == null ? void 0 : c.url);
614
+ emits: ["annotationChange", "batchChange", "labelChange", "ready", "error", "tool:change", "viewport:change", "annotation:add", "annotation:update", "annotation:delete", "annotation:select", "prediction:loaded", "prediction:apply", "prediction:reject"],
615
+ setup(m, { expose: t, emit: i }) {
616
+ const n = m, r = i, o = k(null), c = k(null), a = k(null), d = k(null), p = k(0), w = k(""), u = k([]), f = k(""), _ = k(!1), M = k({ name: "", color: "#FF0000" }), B = k("none"), D = k([]), F = k({}), et = U(() => d.value === "select" && !!w.value), Y = (e) => {
617
+ if (!e || F.value[e]) return;
618
+ const s = new Image();
619
+ s.onload = () => {
620
+ const l = s.naturalWidth || 1, h = s.naturalHeight || 1;
621
+ F.value = {
622
+ ...F.value,
623
+ [e]: { width: l, height: h }
624
+ };
625
+ }, s.src = e;
626
+ }, q = () => {
627
+ n.batchImages.forEach((e) => {
628
+ Y(e.imageUrl);
629
+ });
630
+ }, x = () => {
631
+ var l, h, v, C;
632
+ const e = n.batchImages[p.value], s = (e == null ? void 0 : e.imageUrl) || ((l = n.image) == null ? void 0 : l.url);
606
633
  return {
607
634
  eventId: `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`,
608
635
  timestamp: Date.now(),
609
- requestId: e.requestId,
610
- taskId: (y = e.session) == null ? void 0 : y.taskId,
611
- imageId: ((_ = e.image) == null ? void 0 : _.id) || l,
612
- operator: (A = e.session) == null ? void 0 : A.userId
636
+ requestId: n.requestId,
637
+ taskId: (h = n.session) == null ? void 0 : h.taskId,
638
+ imageId: ((v = n.image) == null ? void 0 : v.id) || s,
639
+ operator: (C = n.session) == null ? void 0 : C.userId
613
640
  };
614
- }, R = (s) => {
615
- var y;
616
- const l = s == null ? void 0 : s.action;
617
- if (!l) return;
618
- const c = {
619
- meta: I(),
620
- action: l,
621
- current: s == null ? void 0 : s.changedItem,
622
- source: (y = s == null ? void 0 : s.changedItem) != null && y.predictionId ? "prediction" : "manual"
641
+ }, I = (e) => {
642
+ var h;
643
+ const s = e == null ? void 0 : e.action;
644
+ if (!s) return;
645
+ const l = {
646
+ meta: x(),
647
+ action: s,
648
+ current: e == null ? void 0 : e.changedItem,
649
+ source: (h = e == null ? void 0 : e.changedItem) != null && h.predictionId ? "prediction" : "manual"
623
650
  };
624
- l === "add" && a("annotation:add", c), l === "update" && a("annotation:update", c), l === "delete" && a("annotation:delete", c), l === "select" && a("annotation:select", c);
625
- }, Z = kt(() => e.annotationTypes.filter((s) => s !== "category")), it = (s) => ({
651
+ s === "add" && r("annotation:add", l), s === "update" && r("annotation:update", l), s === "delete" && r("annotation:delete", l), s === "select" && r("annotation:select", l);
652
+ }, H = U(() => n.annotationTypes.filter((e) => e !== "category")), V = (e) => ({
626
653
  rectangle: "crop",
627
654
  polygon: "connection",
628
655
  point: "aim",
629
656
  rotatedRect: "refresh-right",
630
657
  category: "price-tag"
631
- })[s] || s, ot = (s) => ({
658
+ })[e] || e, lt = (e) => ({
632
659
  rectangle: "矩形框",
633
660
  polygon: "多边形",
634
661
  point: "关键点",
635
662
  rotatedRect: "旋转矩形",
636
663
  category: "分类标签"
637
- })[s] || s;
638
- Mt(() => {
639
- if (o.value) {
640
- i.value = new Pt(o.value), i.value.on("annotationChange", (l) => {
641
- if (l.action === "add" && l.changedItem) {
642
- const c = g.value.find((y) => y.id === u.value);
643
- c && (l.changedItem.label = c.name, l.changedItem.labelId = c.id);
664
+ })[e] || e;
665
+ Yt(() => {
666
+ if (q(), o.value) {
667
+ a.value = new Kt(o.value), a.value.on("annotationChange", (s) => {
668
+ var l, h;
669
+ if (s.action === "add" && s.changedItem) {
670
+ const v = u.value.find((C) => C.id === f.value);
671
+ v && (s.changedItem.label = v.name, s.changedItem.labelId = v.id);
644
672
  }
645
- a("annotationChange", l), R(l);
646
- }), U(), E();
647
- const s = new ResizeObserver(() => {
648
- var l;
649
- (l = i.value) == null || l.resize();
673
+ s.action === "select" ? w.value = ((l = s.changedItem) == null ? void 0 : l.id) || "" : s.action === "delete" && ((h = s.changedItem) == null ? void 0 : h.id) === w.value && (w.value = ""), r("annotationChange", s), I(s);
674
+ }), N(), G();
675
+ const e = new ResizeObserver(() => {
676
+ var s;
677
+ (s = a.value) == null || s.resize();
650
678
  });
651
- r.value && s.observe(r.value), e.defaultActiveType && F(e.defaultActiveType), a("ready", { meta: I() });
679
+ c.value && e.observe(c.value), n.defaultActiveType && W(n.defaultActiveType), r("ready", { meta: x() });
652
680
  }
653
681
  });
654
- const E = () => {
655
- if (!i.value) return;
656
- const s = g.value.find((c) => c.id === u.value);
657
- s && i.value.setLabelStyle(s.color);
658
- const l = g.value.filter((c) => c.visible).map((c) => c.name);
659
- i.value.setVisibleLabels(l);
660
- }, U = () => {
661
- var s;
662
- if (i.value)
663
- if (e.batchImages.length > 0) {
664
- const l = e.batchImages[m.value];
665
- i.value.loadImage(l.imageUrl), l.annotations ? i.value.setAnnotations(l.annotations) : i.value.setAnnotations([]);
666
- } else (s = e.image) != null && s.url && i.value.loadImage(e.image.url);
667
- }, F = (s) => {
668
- var l, c;
669
- if (h.value = s, s !== "pan" && s !== "select" && g.value.length === 0) {
682
+ const G = () => {
683
+ if (!a.value) return;
684
+ const e = u.value.find((l) => l.id === f.value);
685
+ e && a.value.setLabelStyle(e.color);
686
+ const s = u.value.filter((l) => l.visible).map((l) => l.name);
687
+ a.value.setVisibleLabels(s);
688
+ }, N = () => {
689
+ var e;
690
+ if (a.value)
691
+ if (w.value = "", n.batchImages.length > 0) {
692
+ const s = n.batchImages[p.value];
693
+ a.value.loadImage(s.imageUrl), s.annotations ? a.value.setAnnotations(s.annotations) : a.value.setAnnotations([]);
694
+ } else (e = n.image) != null && e.url && a.value.loadImage(n.image.url);
695
+ }, W = (e) => {
696
+ var s, l;
697
+ if (d.value = e, w.value = "", e !== "pan" && e !== "select" && u.value.length === 0) {
670
698
  alert("请先创建标签!");
671
699
  return;
672
700
  }
673
- s === "pan" || s === "select" ? (l = i.value) == null || l.setTool(s) : (c = i.value) == null || c.setTool(s), a("tool:change", { meta: I(), tool: s });
674
- }, at = () => {
675
- var s;
676
- (s = i.value) != null && s.activeAnnotation && i.value.deleteAnnotation(i.value.activeAnnotation.id);
677
- }, G = () => {
678
- i.value && a("viewport:change", {
679
- meta: I(),
680
- scale: i.value.scale,
681
- offset: { ...i.value.offset }
682
- });
683
- }, lt = () => {
684
- var s;
685
- (s = i.value) == null || s.zoom(1), G();
701
+ e === "pan" || e === "select" ? (s = a.value) == null || s.setTool(e) : (l = a.value) == null || l.setTool(e), r("tool:change", { meta: x(), tool: e });
702
+ }, ft = () => {
703
+ var e;
704
+ (e = a.value) != null && e.activeAnnotation && a.value.deleteAnnotation(a.value.activeAnnotation.id);
686
705
  }, rt = () => {
687
- var s;
688
- (s = i.value) == null || s.zoom(-1), G();
706
+ a.value && r("viewport:change", {
707
+ meta: x(),
708
+ scale: a.value.scale,
709
+ offset: { ...a.value.offset }
710
+ });
711
+ }, yt = () => {
712
+ var e;
713
+ (e = a.value) == null || e.zoom(1), rt();
714
+ }, pt = () => {
715
+ var e;
716
+ (e = a.value) == null || e.zoom(-1), rt();
717
+ }, bt = () => {
718
+ M.value = { name: "", color: "#2196F3" }, _.value = !0;
689
719
  }, ct = () => {
690
- p.value = { name: "", color: "#2196F3" }, f.value = !0;
691
- }, Q = () => {
692
- f.value = !1;
693
- }, ht = () => {
694
- if (!p.value.name.trim()) {
720
+ _.value = !1;
721
+ }, xt = () => {
722
+ if (!M.value.name.trim()) {
695
723
  alert("请输入标签名称");
696
724
  return;
697
725
  }
698
- const l = {
726
+ const s = {
699
727
  id: Date.now().toString(),
700
- name: p.value.name,
701
- color: p.value.color,
728
+ name: M.value.name,
729
+ color: M.value.color,
702
730
  visible: !0
703
731
  };
704
- g.value.push(l), a("labelChange", g.value), g.value.length === 1 && B(l), Q();
705
- }, B = (s) => {
706
- var l;
707
- u.value = s.id, (l = i.value) == null || l.setLabelStyle(s.color);
708
- }, dt = (s, l) => {
709
- if (!s.startsWith("#")) return s;
710
- let c = 0, y = 0, _ = 0;
711
- return s.length === 4 ? (c = parseInt(s[1] + s[1], 16), y = parseInt(s[2] + s[2], 16), _ = parseInt(s[3] + s[3], 16)) : s.length === 7 && (c = parseInt(s.slice(1, 3), 16), y = parseInt(s.slice(3, 5), 16), _ = parseInt(s.slice(5, 7), 16)), `rgba(${c}, ${y}, ${_}, ${l})`;
712
- }, gt = (s) => {
713
- var l;
714
- if (s.id === u.value && ((l = i.value) == null || l.setLabelStyle(s.color)), i.value) {
715
- const c = i.value.getAnnotations();
716
- let y = !1;
717
- c.forEach((_) => {
718
- _.label === s.name && (_.style || (_.style = {}), _.style.strokeColor = s.color, _.style.fillColor = dt(s.color, 0.2), y = !0);
719
- }), y && i.value.render();
732
+ u.value.push(s), r("labelChange", u.value), u.value.length === 1 && J(s), ct();
733
+ }, J = (e) => {
734
+ var s;
735
+ f.value = e.id, (s = a.value) == null || s.setLabelStyle(e.color);
736
+ }, wt = (e, s) => {
737
+ if (!e.startsWith("#")) return e;
738
+ let l = 0, h = 0, v = 0;
739
+ return e.length === 4 ? (l = parseInt(e[1] + e[1], 16), h = parseInt(e[2] + e[2], 16), v = parseInt(e[3] + e[3], 16)) : e.length === 7 && (l = parseInt(e.slice(1, 3), 16), h = parseInt(e.slice(3, 5), 16), v = parseInt(e.slice(5, 7), 16)), `rgba(${l}, ${h}, ${v}, ${s})`;
740
+ }, Ct = (e) => {
741
+ var s;
742
+ if (e.id === f.value && ((s = a.value) == null || s.setLabelStyle(e.color)), a.value) {
743
+ const l = a.value.getAnnotations();
744
+ let h = !1;
745
+ l.forEach((v) => {
746
+ v.label === e.name && (v.style || (v.style = {}), v.style.strokeColor = e.color, v.style.fillColor = wt(e.color, 0.2), h = !0);
747
+ }), h && a.value.render();
720
748
  }
721
- a("labelChange", g.value);
722
- }, vt = (s) => {
723
- s.visible = !s.visible, E();
724
- }, ut = (s) => {
725
- const l = g.value.findIndex((c) => c.id === s);
726
- l > -1 && (g.value.splice(l, 1), a("labelChange", g.value), u.value === s && (u.value = g.value.length > 0 ? g.value[0].id : "", u.value && B(g.value[0])), E());
749
+ r("labelChange", u.value);
750
+ }, _t = (e) => {
751
+ e.visible = !e.visible, G();
752
+ }, At = (e) => {
753
+ const s = u.value.findIndex((l) => l.id === e);
754
+ s > -1 && (u.value.splice(s, 1), r("labelChange", u.value), f.value === e && (f.value = u.value.length > 0 ? u.value[0].id : "", f.value && J(u.value[0])), G());
727
755
  };
728
- V(() => e.labels, (s) => {
729
- const l = JSON.parse(JSON.stringify(s || []));
730
- if (g.value = l, g.value.length > 0)
731
- if (!u.value || !g.value.find((c) => c.id === u.value))
732
- B(g.value[0]);
756
+ j(() => n.labels, (e) => {
757
+ const s = JSON.parse(JSON.stringify(e || []));
758
+ if (u.value = s, u.value.length > 0)
759
+ if (!f.value || !u.value.find((l) => l.id === f.value))
760
+ J(u.value[0]);
733
761
  else {
734
- const c = g.value.find((y) => y.id === u.value);
735
- c && B(c);
762
+ const l = u.value.find((h) => h.id === f.value);
763
+ l && J(l);
736
764
  }
737
765
  else
738
- u.value = "";
739
- E();
766
+ f.value = "";
767
+ G();
740
768
  }, { immediate: !0, deep: !0 });
741
- const mt = () => {
742
- m.value > 0 && (j(), m.value--, U(), W());
743
- }, ft = () => {
744
- m.value < e.batchImages.length - 1 && (j(), m.value++, U(), W());
745
- }, j = () => {
746
- if (i.value) {
747
- const s = i.value.getAnnotations();
748
- e.batchImages[m.value].annotations = s;
769
+ const It = () => {
770
+ p.value > 0 && (nt(), p.value--, N(), st());
771
+ }, kt = () => {
772
+ p.value < n.batchImages.length - 1 && (nt(), p.value++, N(), st());
773
+ }, nt = () => {
774
+ if (a.value) {
775
+ const e = a.value.getAnnotations();
776
+ n.batchImages[p.value].annotations = e;
749
777
  }
750
- }, W = () => {
751
- const s = e.batchImages[m.value];
752
- a("batchChange", {
753
- currentIndex: m.value,
754
- total: e.batchImages.length,
755
- currentImageUrl: s.imageUrl,
756
- currentAnnotations: s.annotations || []
778
+ }, st = () => {
779
+ const e = n.batchImages[p.value];
780
+ r("batchChange", {
781
+ currentIndex: p.value,
782
+ total: n.batchImages.length,
783
+ currentImageUrl: e.imageUrl,
784
+ currentAnnotations: e.annotations || []
757
785
  });
758
- }, tt = (s = []) => {
759
- var _;
760
- if (!i.value) return;
761
- if (k.value = JSON.parse(JSON.stringify(s)), k.value.length === 0) {
762
- w.value = "none";
786
+ }, ht = (e = []) => {
787
+ var v;
788
+ if (!a.value) return;
789
+ if (D.value = JSON.parse(JSON.stringify(e)), D.value.length === 0) {
790
+ B.value = "none";
763
791
  return;
764
792
  }
765
- w.value = "loaded";
766
- const c = (i.value.getAnnotations() || []).filter((A) => !A.predictionId), y = k.value.map((A) => {
767
- const P = JSON.parse(JSON.stringify(A.annotation));
768
- return P.id = P.id || `pred-${A.id}`, P.predictionId = A.id, P.modelRunId = A.modelRunId || P.modelRunId, P.confidence = A.confidence ?? P.confidence, P.reviewStatus = P.reviewStatus || "draft", P;
769
- });
770
- i.value.setAnnotations([...c, ...y]), a("prediction:loaded", {
771
- meta: I(),
772
- modelRunId: (_ = k.value[0]) == null ? void 0 : _.modelRunId,
773
- candidates: k.value
793
+ B.value = "loaded";
794
+ const l = (a.value.getAnnotations() || []).filter((C) => !C.predictionId), h = D.value.map((C) => {
795
+ const S = JSON.parse(JSON.stringify(C.annotation));
796
+ return S.id = S.id || `pred-${C.id}`, S.predictionId = C.id, S.modelRunId = C.modelRunId || S.modelRunId, S.confidence = C.confidence ?? S.confidence, S.reviewStatus = S.reviewStatus || "draft", S;
774
797
  });
775
- }, yt = (s) => {
776
- w.value = "loading", a("prediction:request", {
777
- meta: I(),
778
- threshold: s
798
+ a.value.setAnnotations([...l, ...h]), r("prediction:loaded", {
799
+ meta: x(),
800
+ modelRunId: (v = D.value[0]) == null ? void 0 : v.modelRunId,
801
+ candidates: D.value
779
802
  });
780
- }, pt = (s, l) => {
781
- var _;
782
- if (!i.value) return [];
783
- w.value = "applying";
784
- const y = (i.value.getAnnotations() || []).filter((A) => A.predictionId && s.includes(A.predictionId));
785
- return y.forEach((A) => {
786
- A.reviewStatus = "accepted";
787
- }), w.value = "applied", a("prediction:apply", {
788
- meta: I(),
789
- modelRunId: (_ = y[0]) == null ? void 0 : _.modelRunId,
790
- candidateIds: s,
791
- threshold: l,
792
- acceptedAnnotations: y
793
- }), i.value.render(), y;
794
- }, xt = (s, l) => {
795
- var _;
796
- if (!i.value) return;
797
- const c = i.value.getAnnotations() || [], y = c.filter((A) => !(A.predictionId && s.includes(A.predictionId)));
798
- i.value.setAnnotations(y), a("prediction:reject", {
799
- meta: I(),
800
- modelRunId: (_ = c.find((A) => A.predictionId && s.includes(A.predictionId))) == null ? void 0 : _.modelRunId,
801
- candidateIds: s,
802
- reason: l
803
+ }, St = (e, s) => {
804
+ var v;
805
+ if (!a.value) return [];
806
+ B.value = "applying";
807
+ const h = (a.value.getAnnotations() || []).filter((C) => C.predictionId && e.includes(C.predictionId));
808
+ return h.forEach((C) => {
809
+ C.reviewStatus = "accepted";
810
+ }), B.value = "applied", r("prediction:apply", {
811
+ meta: x(),
812
+ modelRunId: (v = h[0]) == null ? void 0 : v.modelRunId,
813
+ candidateIds: e,
814
+ threshold: s,
815
+ acceptedAnnotations: h
816
+ }), a.value.render(), h;
817
+ }, Mt = (e, s) => {
818
+ var v;
819
+ if (!a.value) return;
820
+ const l = a.value.getAnnotations() || [], h = l.filter((C) => !(C.predictionId && e.includes(C.predictionId)));
821
+ a.value.setAnnotations(h), r("prediction:reject", {
822
+ meta: x(),
823
+ modelRunId: (v = l.find((C) => C.predictionId && e.includes(C.predictionId))) == null ? void 0 : v.modelRunId,
824
+ candidateIds: e,
825
+ reason: s
803
826
  });
804
- }, bt = (s, l, c) => {
805
- if (!i.value) return;
806
- const y = i.value.getAnnotations() || [], _ = {
807
- pass: "accepted",
808
- reject: "rejected",
809
- revise: "needs_fix"
827
+ }, zt = (e, s = []) => {
828
+ a.value && (a.value.loadImage(e.url), a.value.setAnnotations(s));
829
+ }, $t = (e) => {
830
+ var s;
831
+ (s = a.value) == null || s.setAnnotations(e);
832
+ }, dt = () => {
833
+ var e;
834
+ return ((e = a.value) == null ? void 0 : e.getAnnotations()) || [];
835
+ }, Tt = (e = "json") => {
836
+ var l, h;
837
+ const s = dt();
838
+ return {
839
+ format: e,
840
+ image: ((l = n.batchImages[p.value]) == null ? void 0 : l.imageUrl) || ((h = n.image) == null ? void 0 : h.url) || "",
841
+ annotations: s
810
842
  };
811
- y.forEach((A) => {
812
- l.includes(A.id) && (A.reviewStatus = _[s]);
813
- }), i.value.render(), a("review:action", {
814
- meta: I(),
815
- reviewAction: s,
816
- targetAnnotationIds: l,
817
- comment: c
818
- });
819
- }, wt = (s, l, c) => {
820
- a("qa:issue", {
821
- meta: I(),
822
- issueType: s,
823
- targetAnnotationIds: l,
824
- detail: c
825
- });
826
- }, At = (s, l = []) => {
827
- i.value && (i.value.loadImage(s.url), i.value.setAnnotations(l));
828
- }, Ct = (s) => {
829
- var l;
830
- (l = i.value) == null || l.setAnnotations(s);
831
- }, et = () => {
843
+ }, gt = (e) => {
844
+ e >= 0 && e < n.batchImages.length && (nt(), p.value = e, N(), st());
845
+ }, Pt = (e) => {
832
846
  var s;
833
- return ((s = i.value) == null ? void 0 : s.getAnnotations()) || [];
847
+ return e === p.value && a.value ? a.value.getAnnotations() || [] : ((s = n.batchImages[e]) == null ? void 0 : s.annotations) || [];
848
+ }, Ht = (e) => e.type === "rectangle", Lt = (e) => e.type === "polygon", Dt = (e) => e.type === "point", Rt = (e) => e.type === "rotatedRect", K = (e) => {
849
+ var l, h;
850
+ const s = (l = u.value.find((v) => v.name === e.label)) == null ? void 0 : l.color;
851
+ return ((h = e.style) == null ? void 0 : h.strokeColor) || s || "#409eff";
852
+ }, ut = (e) => {
853
+ const s = e.coordinates;
854
+ return (s == null ? void 0 : s.points) || [];
855
+ }, Z = (e) => {
856
+ const s = n.batchImages[e];
857
+ if (s != null && s.width && (s != null && s.height))
858
+ return { width: s.width, height: s.height };
859
+ const l = s != null && s.imageUrl ? F.value[s.imageUrl] : void 0;
860
+ return l || (s != null && s.imageUrl && Y(s.imageUrl), { width: 1, height: 1 });
861
+ }, Bt = (e) => {
862
+ const s = n.batchImages[e];
863
+ return s != null && s.width && (s != null && s.height) ? !0 : s != null && s.imageUrl ? !!F.value[s.imageUrl] : !1;
864
+ }, Ut = (e, s) => {
865
+ const l = s.coordinates, h = Z(e), v = K(s), C = Math.min(l.x1, l.x2), S = Math.min(l.y1, l.y2), Nt = Math.max(l.x1, l.x2), Wt = Math.max(l.y1, l.y2);
866
+ return {
867
+ left: `${C / h.width * 100}%`,
868
+ top: `${S / h.height * 100}%`,
869
+ width: `${(Nt - C) / h.width * 100}%`,
870
+ height: `${(Wt - S) / h.height * 100}%`,
871
+ borderColor: v,
872
+ backgroundColor: `${v}22`
873
+ };
874
+ }, Ft = (e, s) => {
875
+ const l = Z(e);
876
+ return ut(s).map((h) => `${h.x / l.width * 100},${h.y / l.height * 100}`).join(" ");
877
+ }, Et = (e) => {
878
+ const s = K(e);
879
+ return {
880
+ fill: `${s}33`,
881
+ stroke: s,
882
+ strokeWidth: "1.4"
883
+ };
884
+ }, Ot = (e, s, l) => {
885
+ const h = Z(e), v = K(l);
886
+ return {
887
+ left: `${s.x / h.width * 100}%`,
888
+ top: `${s.y / h.height * 100}%`,
889
+ backgroundColor: v
890
+ };
891
+ }, Vt = (e, s) => {
892
+ const l = s.coordinates, h = Z(e), v = K(s), C = Math.abs(l.width), S = Math.abs(l.height);
893
+ return {
894
+ left: `${(l.x - C / 2) / h.width * 100}%`,
895
+ top: `${(l.y - S / 2) / h.height * 100}%`,
896
+ width: `${C / h.width * 100}%`,
897
+ height: `${S / h.height * 100}%`,
898
+ transform: `rotate(${l.angle || 0}deg)`,
899
+ borderColor: v,
900
+ backgroundColor: `${v}22`
901
+ };
834
902
  };
835
903
  return t({
836
- jumpTo: (s) => {
837
- s >= 0 && s < e.batchImages.length && (j(), m.value = s, U(), W());
838
- },
839
- setImage: At,
840
- setAnnotations: Ct,
841
- getAnnotations: et,
842
- selectTool: F,
843
- loadPredictionCandidates: tt,
844
- requestPrediction: yt,
845
- applyPredictions: pt,
846
- rejectPredictions: xt,
847
- reviewAction: bt,
848
- reportQaIssue: wt,
849
- exportAnnotations: (s = "json") => {
850
- var c, y;
851
- const l = et();
852
- return {
853
- format: s,
854
- image: ((c = e.batchImages[m.value]) == null ? void 0 : c.imageUrl) || ((y = e.image) == null ? void 0 : y.url) || "",
855
- annotations: l
856
- };
857
- },
904
+ jumpTo: gt,
905
+ setImage: zt,
906
+ setAnnotations: $t,
907
+ getAnnotations: dt,
908
+ selectTool: W,
909
+ loadPredictionCandidates: ht,
910
+ applyPredictions: St,
911
+ rejectPredictions: Mt,
912
+ exportAnnotations: Tt,
858
913
  getAllAnnotations: () => {
859
- var s, l;
860
- return e.batchImages.length > 0 ? e.batchImages : [{
861
- imageUrl: ((s = e.image) == null ? void 0 : s.url) || "",
862
- annotations: ((l = i.value) == null ? void 0 : l.getAnnotations()) || []
914
+ var e, s;
915
+ return n.batchImages.length > 0 ? n.batchImages : [{
916
+ imageUrl: ((e = n.image) == null ? void 0 : e.url) || "",
917
+ annotations: ((s = a.value) == null ? void 0 : s.getAnnotations()) || []
863
918
  }];
864
919
  },
865
920
  getCurrentAnnotation: () => {
866
- var s, l, c;
921
+ var e, s, l;
867
922
  return {
868
- imageUrl: ((s = e.batchImages[m.value]) == null ? void 0 : s.imageUrl) || ((l = e.image) == null ? void 0 : l.url) || "",
869
- annotations: ((c = i.value) == null ? void 0 : c.getAnnotations()) || []
923
+ imageUrl: ((e = n.batchImages[p.value]) == null ? void 0 : e.imageUrl) || ((s = n.image) == null ? void 0 : s.url) || "",
924
+ annotations: ((l = a.value) == null ? void 0 : l.getAnnotations()) || []
870
925
  };
871
926
  }
872
- }), V(() => {
873
- var s;
874
- return (s = e.image) == null ? void 0 : s.url;
927
+ }), j(() => {
928
+ var e;
929
+ return (e = n.image) == null ? void 0 : e.url;
875
930
  }, () => {
876
- var s;
877
- e.batchImages.length === 0 && ((s = e.image) != null && s.url) && U();
878
- }), V(() => e.predictionCandidates, (s) => {
879
- s && tt(s);
880
- }, { immediate: !0, deep: !0 }), (s, l) => (x(), b("div", {
881
- class: $(["annotation-container", v.theme])
931
+ var e;
932
+ n.batchImages.length === 0 && ((e = n.image) != null && e.url) && N();
933
+ }), j(() => n.predictionCandidates, (e) => {
934
+ e && ht(e);
935
+ }, { immediate: !0, deep: !0 }), j(
936
+ () => n.batchImages.map((e) => `${e.imageUrl}:${e.width || ""}x${e.height || ""}`),
937
+ () => {
938
+ q();
939
+ },
940
+ { immediate: !0 }
941
+ ), (e, s) => (y(), b("div", {
942
+ class: E(["annotation-container", m.theme])
882
943
  }, [
883
- v.readOnly ? L("", !0) : (x(), b("div", Kt, [
884
- d("div", {
885
- class: $(["tool-btn", { active: h.value === "pan" }]),
886
- onClick: l[0] || (l[0] = (c) => F("pan")),
944
+ m.batchImages && m.batchImages.length > 0 ? (y(), b("div", fe, [
945
+ g("div", ye, "批量图片(" + $(m.batchImages.length) + ")", 1),
946
+ g("div", pe, [
947
+ (y(!0), b(L, null, R(m.batchImages, (l, h) => (y(), b("button", {
948
+ key: `${l.imageUrl}-${h}`,
949
+ class: E(["image-list-item", { active: h === p.value }]),
950
+ onClick: (v) => gt(h)
951
+ }, [
952
+ g("div", xe, [
953
+ g("img", {
954
+ src: l.imageUrl,
955
+ alt: `第${h + 1}张`,
956
+ class: "image-list-thumb"
957
+ }, null, 8, we),
958
+ Bt(h) ? (y(), b("div", Ce, [
959
+ (y(!0), b(L, null, R(Pt(h), (v) => (y(), b(L, {
960
+ key: v.id
961
+ }, [
962
+ Ht(v) ? (y(), b("div", {
963
+ key: 0,
964
+ class: "thumb-overlay-rect",
965
+ style: O(Ut(h, v))
966
+ }, null, 4)) : Lt(v) ? (y(), b("svg", _e, [
967
+ g("polygon", {
968
+ points: Ft(h, v),
969
+ style: O(Et(v))
970
+ }, null, 12, Ae)
971
+ ])) : Dt(v) ? (y(!0), b(L, { key: 2 }, R(ut(v), (C, S) => (y(), b("div", {
972
+ key: `${v.id}-${S}`,
973
+ class: "thumb-overlay-point",
974
+ style: O(Ot(h, C, v))
975
+ }, null, 4))), 128)) : Rt(v) ? (y(), b("div", {
976
+ key: 3,
977
+ class: "thumb-overlay-rotated",
978
+ style: O(Vt(h, v))
979
+ }, null, 4)) : z("", !0)
980
+ ], 64))), 128))
981
+ ])) : z("", !0)
982
+ ]),
983
+ g("span", Ie, "第 " + $(h + 1) + " 张", 1)
984
+ ], 10, be))), 128))
985
+ ])
986
+ ])) : z("", !0),
987
+ m.readOnly ? z("", !0) : (y(), b("div", ke, [
988
+ g("div", {
989
+ class: E(["tool-btn", { active: d.value === "pan" }]),
990
+ onClick: s[0] || (s[0] = (l) => W("pan")),
887
991
  title: "拖动"
888
992
  }, [
889
- z(M, { name: "rank" })
993
+ P(T, { name: "rank" })
890
994
  ], 2),
891
- d("div", {
892
- class: $(["tool-btn", { active: h.value === "select" }]),
893
- onClick: l[1] || (l[1] = (c) => F("select")),
995
+ g("div", {
996
+ class: E(["tool-btn", { active: d.value === "select" }]),
997
+ onClick: s[1] || (s[1] = (l) => W("select")),
894
998
  title: "选择"
895
999
  }, [
896
- z(M, { name: "pointer" })
1000
+ P(T, { name: "pointer" })
897
1001
  ], 2),
898
- l[4] || (l[4] = d("div", { class: "divider" }, null, -1)),
899
- (x(!0), b(T, null, D(Z.value, (c) => (x(), b("div", {
900
- key: c,
901
- class: $(["tool-btn", { active: h.value === c }]),
902
- onClick: (y) => F(c),
903
- title: ot(c)
1002
+ s[4] || (s[4] = g("div", { class: "divider" }, null, -1)),
1003
+ (y(!0), b(L, null, R(H.value, (l) => (y(), b("div", {
1004
+ key: l,
1005
+ class: E(["tool-btn", { active: d.value === l }]),
1006
+ onClick: (h) => W(l),
1007
+ title: lt(l)
904
1008
  }, [
905
- z(M, {
906
- name: it(c)
1009
+ P(T, {
1010
+ name: V(l)
907
1011
  }, null, 8, ["name"])
908
- ], 10, Zt))), 128)),
909
- l[5] || (l[5] = d("div", { class: "divider" }, null, -1)),
910
- d("div", {
1012
+ ], 10, Se))), 128)),
1013
+ s[5] || (s[5] = g("div", { class: "divider" }, null, -1)),
1014
+ g("div", {
911
1015
  class: "tool-btn",
912
- onClick: lt,
1016
+ onClick: yt,
913
1017
  title: "放大"
914
1018
  }, [
915
- z(M, { name: "zoom-in" })
1019
+ P(T, { name: "zoom-in" })
916
1020
  ]),
917
- d("div", {
1021
+ g("div", {
918
1022
  class: "tool-btn",
919
- onClick: rt,
1023
+ onClick: pt,
920
1024
  title: "缩小"
921
1025
  }, [
922
- z(M, { name: "zoom-out" })
1026
+ P(T, { name: "zoom-out" })
923
1027
  ]),
924
- l[6] || (l[6] = d("div", { class: "divider" }, null, -1)),
925
- d("div", {
1028
+ s[6] || (s[6] = g("div", { class: "divider" }, null, -1)),
1029
+ et.value ? (y(), b("div", {
1030
+ key: 0,
926
1031
  class: "tool-btn",
927
- onClick: at,
1032
+ onClick: ft,
928
1033
  title: "删除选中"
929
1034
  }, [
930
- z(M, { name: "delete" })
931
- ])
1035
+ P(T, { name: "delete" })
1036
+ ])) : z("", !0)
932
1037
  ])),
933
- d("div", Gt, [
934
- v.readOnly ? L("", !0) : (x(), b("div", Qt, [
935
- d("div", te, [
936
- l[7] || (l[7] = d("span", { class: "label-text" }, "当前标签:", -1)),
937
- d("div", ee, [
938
- (x(!0), b(T, null, D(g.value, (c) => (x(), b("div", {
939
- key: c.id,
940
- class: $(["tag-chip", { active: u.value === c.id }]),
941
- style: K({ backgroundColor: c.color, borderColor: c.color }),
942
- onClick: (y) => B(c)
943
- }, H(c.name), 15, ne))), 128)),
944
- g.value.length === 0 ? (x(), b("div", se, "请在右侧创建标签")) : L("", !0)
1038
+ g("div", Me, [
1039
+ m.readOnly ? z("", !0) : (y(), b("div", ze, [
1040
+ g("div", $e, [
1041
+ s[7] || (s[7] = g("span", { class: "label-text" }, "当前标签:", -1)),
1042
+ g("div", Te, [
1043
+ (y(!0), b(L, null, R(u.value, (l) => (y(), b("div", {
1044
+ key: l.id,
1045
+ class: E(["tag-chip", { active: f.value === l.id }]),
1046
+ style: O({ backgroundColor: l.color, borderColor: l.color }),
1047
+ onClick: (h) => J(l)
1048
+ }, $(l.name), 15, Pe))), 128)),
1049
+ u.value.length === 0 ? (y(), b("div", He, "请在右侧创建标签")) : z("", !0)
945
1050
  ])
946
1051
  ])
947
1052
  ])),
948
- d("div", {
1053
+ g("div", {
949
1054
  class: "canvas-wrapper",
950
1055
  ref_key: "canvasWrapper",
951
- ref: r
1056
+ ref: c
952
1057
  }, [
953
- d("canvas", {
1058
+ g("canvas", {
954
1059
  ref_key: "canvasRef",
955
1060
  ref: o
956
1061
  }, null, 512)
957
1062
  ], 512),
958
- v.batchImages && v.batchImages.length > 0 ? (x(), b("div", ie, [
959
- d("button", {
960
- onClick: mt,
961
- disabled: m.value <= 0
1063
+ m.batchImages && m.batchImages.length > 0 ? (y(), b("div", Le, [
1064
+ g("button", {
1065
+ onClick: It,
1066
+ disabled: p.value <= 0
962
1067
  }, [
963
- z(M, { name: "back" }),
964
- l[8] || (l[8] = O(" 上一张 ", -1))
965
- ], 8, oe),
966
- d("span", null, H(m.value + 1) + " / " + H(v.batchImages.length), 1),
967
- d("button", {
968
- onClick: ft,
969
- disabled: m.value >= v.batchImages.length - 1
1068
+ P(T, { name: "back" }),
1069
+ s[8] || (s[8] = X(" 上一张 ", -1))
1070
+ ], 8, De),
1071
+ g("span", null, $(p.value + 1) + " / " + $(m.batchImages.length), 1),
1072
+ g("button", {
1073
+ onClick: kt,
1074
+ disabled: p.value >= m.batchImages.length - 1
970
1075
  }, [
971
- l[9] || (l[9] = O(" 下一张 ", -1)),
972
- z(M, { name: "right" })
973
- ], 8, ae)
974
- ])) : L("", !0)
1076
+ s[9] || (s[9] = X(" 下一张 ", -1)),
1077
+ P(T, { name: "right" })
1078
+ ], 8, Re)
1079
+ ])) : z("", !0)
975
1080
  ]),
976
- v.readOnly ? L("", !0) : (x(), b("div", le, [
977
- d("div", { class: "sidebar-header" }, [
978
- l[10] || (l[10] = d("h3", null, "标签管理", -1)),
979
- d("button", {
1081
+ m.readOnly ? z("", !0) : (y(), b("div", Be, [
1082
+ g("div", { class: "sidebar-header" }, [
1083
+ s[10] || (s[10] = g("h3", null, "标签管理", -1)),
1084
+ g("button", {
980
1085
  class: "add-btn",
981
- onClick: ct
1086
+ onClick: bt
982
1087
  }, "添加标签")
983
1088
  ]),
984
- d("div", re, [
985
- (x(!0), b(T, null, D(g.value, (c) => (x(), b("div", {
986
- key: c.id,
1089
+ g("div", Ue, [
1090
+ (y(!0), b(L, null, R(u.value, (l) => (y(), b("div", {
1091
+ key: l.id,
987
1092
  class: "label-item"
988
1093
  }, [
989
- d("div", ce, [
990
- d("label", {
1094
+ g("div", Fe, [
1095
+ g("label", {
991
1096
  class: "color-wrapper",
992
- style: K({ backgroundColor: c.color })
1097
+ style: O({ backgroundColor: l.color })
993
1098
  }, [
994
- q(d("input", {
1099
+ it(g("input", {
995
1100
  type: "color",
996
- "onUpdate:modelValue": (y) => c.color = y,
997
- onChange: (y) => gt(c),
1101
+ "onUpdate:modelValue": (h) => l.color = h,
1102
+ onChange: (h) => Ct(l),
998
1103
  style: { visibility: "hidden", width: "0", height: "0" }
999
- }, null, 40, he), [
1000
- [X, c.color]
1104
+ }, null, 40, Ee), [
1105
+ [ot, l.color]
1001
1106
  ])
1002
1107
  ], 4),
1003
- d("span", {
1108
+ g("span", {
1004
1109
  class: "label-name",
1005
- title: c.name
1006
- }, H(c.name), 9, de),
1007
- d("span", {
1110
+ title: l.name
1111
+ }, $(l.name), 9, Oe),
1112
+ g("span", {
1008
1113
  class: "action-icon eye",
1009
- onClick: (y) => vt(c)
1114
+ onClick: (h) => _t(l)
1010
1115
  }, [
1011
- c.visible ? (x(), nt(M, {
1116
+ l.visible ? (y(), vt(T, {
1012
1117
  key: 0,
1013
1118
  name: "view"
1014
- })) : (x(), nt(M, {
1119
+ })) : (y(), vt(T, {
1015
1120
  key: 1,
1016
1121
  name: "hide"
1017
1122
  }))
1018
- ], 8, ge),
1019
- d("div", ve, [
1020
- l[11] || (l[11] = d("span", { class: "dots" }, "•••", -1)),
1021
- d("span", {
1123
+ ], 8, Ve),
1124
+ g("div", Ne, [
1125
+ s[11] || (s[11] = g("span", { class: "dots" }, "•••", -1)),
1126
+ g("span", {
1022
1127
  class: "delete-btn",
1023
- onClick: (y) => ut(c.id),
1128
+ onClick: (h) => At(l.id),
1024
1129
  title: "删除"
1025
1130
  }, [
1026
- z(M, { name: "delete" })
1027
- ], 8, ue)
1131
+ P(T, { name: "delete" })
1132
+ ], 8, We)
1028
1133
  ])
1029
1134
  ])
1030
1135
  ]))), 128))
1031
1136
  ])
1032
1137
  ])),
1033
- f.value ? (x(), b("div", me, [
1034
- d("div", fe, [
1035
- l[14] || (l[14] = d("h3", null, "新增标签", -1)),
1036
- d("div", ye, [
1037
- l[12] || (l[12] = d("label", null, "名称", -1)),
1038
- q(d("input", {
1039
- "onUpdate:modelValue": l[2] || (l[2] = (c) => p.value.name = c),
1138
+ _.value ? (y(), b("div", Je, [
1139
+ g("div", je, [
1140
+ s[14] || (s[14] = g("h3", null, "新增标签", -1)),
1141
+ g("div", Xe, [
1142
+ s[12] || (s[12] = g("label", null, "名称", -1)),
1143
+ it(g("input", {
1144
+ "onUpdate:modelValue": s[2] || (s[2] = (l) => M.value.name = l),
1040
1145
  placeholder: "请输入标签名称",
1041
1146
  class: "modal-input"
1042
1147
  }, null, 512), [
1043
- [X, p.value.name]
1148
+ [ot, M.value.name]
1044
1149
  ])
1045
1150
  ]),
1046
- d("div", pe, [
1047
- l[13] || (l[13] = d("label", null, "颜色", -1)),
1048
- d("div", xe, [
1049
- q(d("input", {
1151
+ g("div", Ye, [
1152
+ s[13] || (s[13] = g("label", null, "颜色", -1)),
1153
+ g("div", qe, [
1154
+ it(g("input", {
1050
1155
  type: "color",
1051
- "onUpdate:modelValue": l[3] || (l[3] = (c) => p.value.color = c),
1156
+ "onUpdate:modelValue": s[3] || (s[3] = (l) => M.value.color = l),
1052
1157
  class: "modal-color-picker"
1053
1158
  }, null, 512), [
1054
- [X, p.value.color]
1159
+ [ot, M.value.color]
1055
1160
  ]),
1056
- d("span", null, H(p.value.color), 1)
1161
+ g("span", null, $(M.value.color), 1)
1057
1162
  ])
1058
1163
  ]),
1059
- d("div", { class: "modal-actions" }, [
1060
- d("button", {
1061
- onClick: Q,
1164
+ g("div", { class: "modal-actions" }, [
1165
+ g("button", {
1166
+ onClick: ct,
1062
1167
  class: "cancel-btn"
1063
1168
  }, "取消"),
1064
- d("button", {
1065
- onClick: ht,
1169
+ g("button", {
1170
+ onClick: xt,
1066
1171
  class: "confirm-btn"
1067
1172
  }, "确认")
1068
1173
  ])
1069
1174
  ])
1070
- ])) : L("", !0)
1175
+ ])) : z("", !0)
1071
1176
  ], 2));
1072
1177
  }
1073
- }), we = /* @__PURE__ */ J(be, [["__scopeId", "data-v-7b013204"]]), Ae = {
1178
+ }), Ke = /* @__PURE__ */ tt(Ge, [["__scopeId", "data-v-22c2957b"]]), Ze = {
1074
1179
  class: "thumbnail-wrapper",
1075
1180
  ref: "wrapper"
1076
- }, Ce = ["src", "alt"], _e = ["viewBox"], Ie = ["x", "y", "width", "height", "stroke"], Se = ["points", "stroke"], ke = ["x", "y", "fill"], Me = {
1181
+ }, Qe = ["src", "alt"], tn = ["viewBox"], en = ["x", "y", "width", "height", "stroke"], nn = ["points", "stroke"], sn = ["x", "y", "fill"], on = {
1077
1182
  key: 1,
1078
1183
  class: "loading-placeholder"
1079
- }, ze = /* @__PURE__ */ N({
1184
+ }, an = /* @__PURE__ */ Q({
1080
1185
  __name: "AnnotationThumbnail",
1081
1186
  props: {
1082
1187
  src: {},
@@ -1084,23 +1189,23 @@ const Lt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" widt
1084
1189
  alt: {},
1085
1190
  labels: {}
1086
1191
  },
1087
- setup(v) {
1088
- const t = v, n = S(null), e = S(!1), a = S(0), o = S(0), r = () => {
1089
- n.value && (a.value = n.value.naturalWidth, o.value = n.value.naturalHeight, e.value = !0);
1090
- }, i = (u) => {
1192
+ setup(m) {
1193
+ const t = m, i = k(null), n = k(!1), r = k(0), o = k(0), c = () => {
1194
+ i.value && (r.value = i.value.naturalWidth, o.value = i.value.naturalHeight, n.value = !0);
1195
+ }, a = (u) => {
1091
1196
  var f;
1092
1197
  if ((f = u.style) != null && f.strokeColor) return u.style.strokeColor;
1093
1198
  if (t.labels) {
1094
- const p = t.labels.find((w) => w.name === u.label);
1095
- if (p) return p.color;
1199
+ const _ = t.labels.find((M) => M.name === u.label);
1200
+ if (_) return _.color;
1096
1201
  }
1097
1202
  return "#FF0000";
1098
- }, h = (u) => {
1099
- const f = u.coordinates, p = Math.min(f.x1, f.x2), w = Math.min(f.y1, f.y2), k = Math.abs(f.x1 - f.x2), I = Math.abs(f.y1 - f.y2);
1100
- return { x: p, y: w, width: k, height: I };
1101
- }, m = (u) => u.coordinates.points.map((p) => `${p.x},${p.y}`).join(" "), g = (u) => {
1203
+ }, d = (u) => {
1204
+ const f = u.coordinates, _ = Math.min(f.x1, f.x2), M = Math.min(f.y1, f.y2), B = Math.abs(f.x1 - f.x2), D = Math.abs(f.y1 - f.y2);
1205
+ return { x: _, y: M, width: B, height: D };
1206
+ }, p = (u) => u.coordinates.points.map((_) => `${_.x},${_.y}`).join(" "), w = (u) => {
1102
1207
  if (u.type === "rectangle") {
1103
- const f = h(u);
1208
+ const f = d(u);
1104
1209
  return { x: f.x, y: f.y - 5 };
1105
1210
  } else if (u.type === "polygon") {
1106
1211
  const f = u.coordinates.points;
@@ -1108,171 +1213,196 @@ const Lt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" widt
1108
1213
  }
1109
1214
  return { x: 0, y: 0 };
1110
1215
  };
1111
- return (u, f) => (x(), b("div", Ae, [
1112
- d("img", {
1216
+ return (u, f) => (y(), b("div", Ze, [
1217
+ g("img", {
1113
1218
  ref_key: "img",
1114
- ref: n,
1115
- src: v.src,
1219
+ ref: i,
1220
+ src: m.src,
1116
1221
  class: "thumbnail-image",
1117
- onLoad: r,
1118
- alt: v.alt
1119
- }, null, 40, Ce),
1120
- e.value ? (x(), b("svg", {
1222
+ onLoad: c,
1223
+ alt: m.alt
1224
+ }, null, 40, Qe),
1225
+ n.value ? (y(), b("svg", {
1121
1226
  key: 0,
1122
1227
  class: "annotation-overlay",
1123
- viewBox: `0 0 ${a.value} ${o.value}`,
1228
+ viewBox: `0 0 ${r.value} ${o.value}`,
1124
1229
  preserveAspectRatio: "none"
1125
1230
  }, [
1126
- (x(!0), b(T, null, D(v.annotations, (p) => (x(), b(T, {
1127
- key: p.id
1231
+ (y(!0), b(L, null, R(m.annotations, (_) => (y(), b(L, {
1232
+ key: _.id
1128
1233
  }, [
1129
- p.type === "rectangle" ? (x(), b("rect", {
1234
+ _.type === "rectangle" ? (y(), b("rect", {
1130
1235
  key: 0,
1131
- x: h(p).x,
1132
- y: h(p).y,
1133
- width: h(p).width,
1134
- height: h(p).height,
1135
- stroke: i(p),
1236
+ x: d(_).x,
1237
+ y: d(_).y,
1238
+ width: d(_).width,
1239
+ height: d(_).height,
1240
+ stroke: a(_),
1136
1241
  "stroke-width": "2",
1137
1242
  fill: "transparent"
1138
- }, null, 8, Ie)) : L("", !0),
1139
- p.type === "polygon" ? (x(), b("polygon", {
1243
+ }, null, 8, en)) : z("", !0),
1244
+ _.type === "polygon" ? (y(), b("polygon", {
1140
1245
  key: 1,
1141
- points: m(p),
1142
- stroke: i(p),
1246
+ points: p(_),
1247
+ stroke: a(_),
1143
1248
  "stroke-width": "2",
1144
1249
  fill: "transparent"
1145
- }, null, 8, Se)) : L("", !0),
1146
- p.label ? (x(), b("text", {
1250
+ }, null, 8, nn)) : z("", !0),
1251
+ _.label ? (y(), b("text", {
1147
1252
  key: 2,
1148
- x: g(p).x,
1149
- y: g(p).y,
1150
- fill: i(p),
1253
+ x: w(_).x,
1254
+ y: w(_).y,
1255
+ fill: a(_),
1151
1256
  "font-size": "14",
1152
1257
  "font-weight": "bold",
1153
1258
  class: "anno-label"
1154
- }, H(p.label), 9, ke)) : L("", !0)
1259
+ }, $(_.label), 9, sn)) : z("", !0)
1155
1260
  ], 64))), 128))
1156
- ], 8, _e)) : (x(), b("div", Me, "Loading..."))
1261
+ ], 8, tn)) : (y(), b("div", on, "Loading..."))
1157
1262
  ], 512));
1158
1263
  }
1159
- }), He = /* @__PURE__ */ J(ze, [["__scopeId", "data-v-78bcbe0c"]]), Pe = { class: "batch-annotator" }, Le = {
1264
+ }), ln = /* @__PURE__ */ tt(an, [["__scopeId", "data-v-78bcbe0c"]]), rn = { class: "batch-annotator" }, cn = {
1160
1265
  key: 0,
1161
1266
  class: "gallery-view"
1162
- }, Te = { class: "gallery-header" }, $e = { class: "label-summary" }, De = { class: "gallery-grid" }, Re = ["onClick"], Ue = { class: "thumbnail-wrapper" }, Fe = { class: "img-meta" }, Be = { class: "img-index" }, Oe = { class: "anno-count" }, Ee = { class: "bottom-bar" }, Ve = {
1267
+ }, hn = { class: "gallery-header" }, dn = { class: "label-summary" }, gn = { class: "gallery-grid" }, un = ["onClick"], vn = { class: "thumbnail-wrapper" }, mn = { class: "img-meta" }, fn = { class: "img-index" }, yn = { class: "anno-count" }, pn = {
1268
+ key: 0,
1269
+ class: "bottom-bar"
1270
+ }, bn = {
1163
1271
  key: 1,
1164
1272
  class: "editor-view"
1165
- }, Ne = { class: "editor-header" }, Je = { class: "header-left" }, je = { class: "editor-title" }, We = { class: "editor-content" }, qe = /* @__PURE__ */ N({
1273
+ }, xn = { class: "editor-header" }, wn = { class: "header-left" }, Cn = { class: "editor-title" }, _n = { class: "editor-content" }, An = /* @__PURE__ */ Q({
1166
1274
  __name: "BatchAnnotator",
1167
1275
  props: {
1168
1276
  images: {},
1169
- labels: {}
1277
+ labels: {},
1278
+ actionBar: {},
1279
+ clickToEnterEditor: { type: Boolean }
1170
1280
  },
1171
- emits: ["export", "update:images"],
1172
- setup(v, { emit: t }) {
1173
- const n = v, e = t, a = S("gallery"), o = S([]), r = S(0), i = S(null);
1174
- V(() => n.images, (w) => {
1175
- o.value = JSON.parse(JSON.stringify(w));
1281
+ emits: ["export", "update:images", "imageClick"],
1282
+ setup(m, { emit: t }) {
1283
+ const i = m, n = t, r = k("gallery"), o = k([]), c = k(0), a = k(null), d = U(() => {
1284
+ var x, I;
1285
+ return ((I = (x = i.actionBar) == null ? void 0 : x.annotateButton) == null ? void 0 : I.show) === !0;
1286
+ }), p = U(() => {
1287
+ var x, I;
1288
+ return ((I = (x = i.actionBar) == null ? void 0 : x.exportButton) == null ? void 0 : I.show) === !0;
1289
+ }), w = U(() => d.value || p.value), u = U(() => {
1290
+ var x, I;
1291
+ return ((I = (x = i.actionBar) == null ? void 0 : x.annotateButton) == null ? void 0 : I.text) || "手动标注";
1292
+ }), f = U(() => {
1293
+ var x, I;
1294
+ return ((I = (x = i.actionBar) == null ? void 0 : x.exportButton) == null ? void 0 : I.text) || "导出";
1295
+ }), _ = U(() => i.clickToEnterEditor !== !1);
1296
+ j(() => i.images, (x) => {
1297
+ o.value = JSON.parse(JSON.stringify(x));
1176
1298
  }, { immediate: !0, deep: !0 });
1177
- const h = (w) => {
1178
- r.value = w, a.value = "editor", zt(() => {
1179
- i.value && i.value.jumpTo && i.value.jumpTo(w);
1299
+ const M = (x) => {
1300
+ c.value = x, r.value = "editor", qt(() => {
1301
+ a.value && a.value.jumpTo && a.value.jumpTo(x);
1180
1302
  });
1181
- }, m = () => {
1182
- if (i.value && i.value.getCurrentAnnotation) {
1183
- const w = i.value.getCurrentAnnotation();
1184
- o.value[r.value] && (o.value[r.value].annotations = w.annotations);
1303
+ }, B = (x, I) => {
1304
+ if (_.value) {
1305
+ M(x);
1306
+ return;
1185
1307
  }
1186
- a.value = "gallery";
1187
- }, g = () => {
1188
- e("export", o.value);
1189
- }, u = (w) => {
1190
- r.value = w.currentIndex, o.value[w.currentIndex] && (o.value[w.currentIndex].annotations = w.currentAnnotations);
1191
- }, f = (w) => {
1192
- if (i.value && i.value.getCurrentAnnotation) {
1193
- const k = i.value.getCurrentAnnotation();
1194
- o.value[r.value] && (o.value[r.value].annotations = k.annotations, e("update:images", o.value));
1308
+ n("imageClick", { index: x, image: I });
1309
+ }, D = () => {
1310
+ if (a.value && a.value.getCurrentAnnotation) {
1311
+ const x = a.value.getCurrentAnnotation();
1312
+ o.value[c.value] && (o.value[c.value].annotations = x.annotations);
1195
1313
  }
1196
- }, p = (w) => {
1314
+ r.value = "gallery";
1315
+ }, F = () => {
1316
+ n("export", o.value);
1317
+ }, et = (x) => {
1318
+ c.value = x.currentIndex, o.value[x.currentIndex] && (o.value[x.currentIndex].annotations = x.currentAnnotations);
1319
+ }, Y = (x) => {
1320
+ if (a.value && a.value.getCurrentAnnotation) {
1321
+ const I = a.value.getCurrentAnnotation();
1322
+ o.value[c.value] && (o.value[c.value].annotations = I.annotations, n("update:images", o.value));
1323
+ }
1324
+ }, q = (x) => {
1197
1325
  };
1198
- return (w, k) => (x(), b("div", Pe, [
1199
- a.value === "gallery" ? (x(), b("div", Le, [
1200
- d("div", Te, [
1201
- d("h3", null, "批量查看与标注 (" + H(o.value.length) + " 张)", 1),
1202
- d("div", $e, [
1203
- (x(!0), b(T, null, D(v.labels, (I) => (x(), b("span", {
1204
- key: I.id,
1326
+ return (x, I) => (y(), b("div", rn, [
1327
+ r.value === "gallery" ? (y(), b("div", cn, [
1328
+ g("div", hn, [
1329
+ g("h3", null, "批量查看与标注 (" + $(o.value.length) + " 张)", 1),
1330
+ g("div", dn, [
1331
+ (y(!0), b(L, null, R(m.labels, (H) => (y(), b("span", {
1332
+ key: H.id,
1205
1333
  class: "label-badge",
1206
- style: K({ backgroundColor: I.color })
1207
- }, H(I.name), 5))), 128))
1334
+ style: O({ backgroundColor: H.color })
1335
+ }, $(H.name), 5))), 128))
1208
1336
  ])
1209
1337
  ]),
1210
- d("div", De, [
1211
- (x(!0), b(T, null, D(o.value, (I, R) => (x(), b("div", {
1212
- key: R,
1338
+ g("div", gn, [
1339
+ (y(!0), b(L, null, R(o.value, (H, V) => (y(), b("div", {
1340
+ key: V,
1213
1341
  class: "gallery-item",
1214
- onClick: (Z) => h(R)
1342
+ onClick: (lt) => B(V, H)
1215
1343
  }, [
1216
- d("div", Ue, [
1217
- z(He, {
1218
- src: I.imageUrl,
1219
- annotations: I.annotations || [],
1220
- labels: v.labels
1344
+ g("div", vn, [
1345
+ P(ln, {
1346
+ src: H.imageUrl,
1347
+ annotations: H.annotations || [],
1348
+ labels: m.labels
1221
1349
  }, null, 8, ["src", "annotations", "labels"])
1222
1350
  ]),
1223
- d("div", Fe, [
1224
- d("span", Be, "#" + H(R + 1), 1),
1225
- d("span", Oe, H((I.annotations || []).length) + " 标注", 1)
1351
+ g("div", mn, [
1352
+ g("span", fn, "#" + $(V + 1), 1),
1353
+ g("span", yn, $((H.annotations || []).length) + " 标注", 1)
1226
1354
  ])
1227
- ], 8, Re))), 128))
1355
+ ], 8, un))), 128))
1228
1356
  ]),
1229
- d("div", Ee, [
1230
- d("button", {
1357
+ w.value ? (y(), b("div", pn, [
1358
+ d.value ? (y(), b("button", {
1359
+ key: 0,
1231
1360
  class: "action-btn primary",
1232
- onClick: k[0] || (k[0] = (I) => h(0))
1361
+ onClick: I[0] || (I[0] = (H) => M(0))
1233
1362
  }, [
1234
- z(M, { name: "edit" }),
1235
- k[1] || (k[1] = O(" 手动标注 ", -1))
1236
- ]),
1237
- d("button", {
1363
+ P(T, { name: "edit" }),
1364
+ X(" " + $(u.value), 1)
1365
+ ])) : z("", !0),
1366
+ p.value ? (y(), b("button", {
1367
+ key: 1,
1238
1368
  class: "action-btn success",
1239
- onClick: g
1369
+ onClick: F
1240
1370
  }, [
1241
- z(M, { name: "download" }),
1242
- k[2] || (k[2] = O(" 导出 ", -1))
1243
- ])
1244
- ])
1245
- ])) : (x(), b("div", Ve, [
1246
- d("div", Ne, [
1247
- d("div", Je, [
1248
- d("button", {
1371
+ P(T, { name: "download" }),
1372
+ X(" " + $(f.value), 1)
1373
+ ])) : z("", !0)
1374
+ ])) : z("", !0)
1375
+ ])) : (y(), b("div", bn, [
1376
+ g("div", xn, [
1377
+ g("div", wn, [
1378
+ g("button", {
1249
1379
  class: "back-btn",
1250
- onClick: m
1380
+ onClick: D
1251
1381
  }, [
1252
- z(M, { name: "back" }),
1253
- k[3] || (k[3] = O(" 返回列表 ", -1))
1382
+ P(T, { name: "back" }),
1383
+ I[1] || (I[1] = X(" 返回列表 ", -1))
1254
1384
  ]),
1255
- d("span", je, "正在标注: " + H(r.value + 1) + " / " + H(o.value.length), 1)
1385
+ g("span", Cn, "正在标注: " + $(c.value + 1) + " / " + $(o.value.length), 1)
1256
1386
  ])
1257
1387
  ]),
1258
- d("div", We, [
1259
- z(we, {
1388
+ g("div", _n, [
1389
+ P(Ke, {
1260
1390
  ref_key: "annotatorRef",
1261
- ref: i,
1391
+ ref: a,
1262
1392
  batchImages: o.value,
1263
- labels: v.labels,
1393
+ labels: m.labels,
1264
1394
  annotationTypes: ["rectangle", "polygon", "point", "rotatedRect"],
1265
- onBatchChange: u,
1266
- onAnnotationChange: f,
1267
- onLabelChange: p
1395
+ onBatchChange: et,
1396
+ onAnnotationChange: Y,
1397
+ onLabelChange: q
1268
1398
  }, null, 8, ["batchImages", "labels"])
1269
1399
  ])
1270
1400
  ]))
1271
1401
  ]));
1272
1402
  }
1273
- }), Ge = /* @__PURE__ */ J(qe, [["__scopeId", "data-v-87f3e002"]]);
1403
+ }), Sn = /* @__PURE__ */ tt(An, [["__scopeId", "data-v-bbb647e1"]]);
1274
1404
  export {
1275
- Ge as BatchAnnotator,
1276
- we as ImageAnnotator,
1277
- Ge as default
1405
+ Sn as BatchAnnotator,
1406
+ Ke as ImageAnnotator,
1407
+ Sn as default
1278
1408
  };