luo-image-annotator 0.0.17 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/luo-image-annotator.css +1 -1
- package/dist/luo-image-annotator.es.js +513 -470
- package/dist/luo-image-annotator.umd.js +1 -1
- package/package.json +1 -1
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
var ae = Object.defineProperty;
|
|
2
|
-
var le = (
|
|
3
|
-
var T = (
|
|
4
|
-
import { defineComponent as ct, ref as M, watchEffect as ce, openBlock as v, createElementBlock as m, normalizeClass as
|
|
5
|
-
const pt = (
|
|
2
|
+
var le = (y, t, n) => t in y ? ae(y, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : y[t] = n;
|
|
3
|
+
var T = (y, t, n) => le(y, typeof t != "symbol" ? t + "" : t, n);
|
|
4
|
+
import { defineComponent as ct, ref as M, watchEffect as ce, openBlock as v, createElementBlock as m, normalizeClass as q, computed as O, onMounted as yt, nextTick as at, watch as K, createElementVNode as h, toDisplayString as L, Fragment as W, renderList as J, normalizeStyle as U, createCommentVNode as R, createVNode as B, withModifiers as It, createBlock as vt, withDirectives as ft, vModelText as mt, createTextVNode as lt } from "vue";
|
|
5
|
+
const pt = (y, t) => Math.sqrt(Math.pow(y.x - t.x, 2) + Math.pow(y.y - t.y, 2)), re = (y, t) => {
|
|
6
6
|
let n = !1;
|
|
7
|
-
for (let e = 0,
|
|
8
|
-
const o = t[e].x,
|
|
9
|
-
|
|
7
|
+
for (let e = 0, l = t.length - 1; e < t.length; l = e++) {
|
|
8
|
+
const o = t[e].x, a = t[e].y, g = t[l].x, u = t[l].y;
|
|
9
|
+
a > y.y != u > y.y && y.x < (g - o) * (y.y - a) / (u - a) + o && (n = !n);
|
|
10
10
|
}
|
|
11
11
|
return n;
|
|
12
|
-
}, At = (
|
|
13
|
-
const e = n * (Math.PI / 180),
|
|
12
|
+
}, At = (y, t, n) => {
|
|
13
|
+
const e = n * (Math.PI / 180), l = Math.cos(e), o = Math.sin(e), a = y.x - t.x, g = y.y - t.y;
|
|
14
14
|
return {
|
|
15
|
-
x: t.x + (
|
|
16
|
-
y: t.y + (
|
|
15
|
+
x: t.x + (a * l - g * o),
|
|
16
|
+
y: t.y + (a * o + g * l)
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
19
|
class he {
|
|
@@ -52,6 +52,8 @@ class he {
|
|
|
52
52
|
// 视口
|
|
53
53
|
T(this, "scale", 1);
|
|
54
54
|
T(this, "offset", { x: 0, y: 0 });
|
|
55
|
+
T(this, "showLabels", !1);
|
|
56
|
+
// 是否在画布上显示标注的标签
|
|
55
57
|
T(this, "listeners", {});
|
|
56
58
|
T(this, "imageUrl", "");
|
|
57
59
|
this.canvas = t;
|
|
@@ -86,11 +88,14 @@ class he {
|
|
|
86
88
|
setVisibleLabels(t) {
|
|
87
89
|
this.visibleLabels = new Set(t), this.render();
|
|
88
90
|
}
|
|
91
|
+
setShowLabels(t) {
|
|
92
|
+
this.showLabels = t, this.render();
|
|
93
|
+
}
|
|
89
94
|
zoom(t) {
|
|
90
95
|
const e = t > 0 ? this.scale * 1.1 : this.scale / 1.1;
|
|
91
96
|
if (e < 0.1 || e > 10) return;
|
|
92
|
-
const
|
|
93
|
-
this.scale = e, this.offset.x =
|
|
97
|
+
const l = this.canvas.width / 2, o = this.canvas.height / 2, a = this.toImageCoords(l, o);
|
|
98
|
+
this.scale = e, this.offset.x = l - a.x * this.scale, this.offset.y = o - a.y * this.scale, this.clampViewportOffset(), this.render();
|
|
94
99
|
}
|
|
95
100
|
resize() {
|
|
96
101
|
this.fitImageToCanvas(), this.render();
|
|
@@ -120,18 +125,18 @@ class he {
|
|
|
120
125
|
if (this.img.width === 0 || this.img.height === 0) return;
|
|
121
126
|
const t = this.img.width * this.scale, n = this.img.height * this.scale, e = 100;
|
|
122
127
|
if (t <= this.canvas.width) {
|
|
123
|
-
const
|
|
124
|
-
this.offset.x = Math.min(o, Math.max(
|
|
128
|
+
const l = -t + e, o = this.canvas.width - e;
|
|
129
|
+
this.offset.x = Math.min(o, Math.max(l, this.offset.x));
|
|
125
130
|
} else {
|
|
126
|
-
const
|
|
127
|
-
this.offset.x = Math.min(o, Math.max(
|
|
131
|
+
const l = this.canvas.width - t - e, o = e;
|
|
132
|
+
this.offset.x = Math.min(o, Math.max(l, this.offset.x));
|
|
128
133
|
}
|
|
129
134
|
if (n <= this.canvas.height) {
|
|
130
|
-
const
|
|
131
|
-
this.offset.y = Math.min(o, Math.max(
|
|
135
|
+
const l = -n + e, o = this.canvas.height - e;
|
|
136
|
+
this.offset.y = Math.min(o, Math.max(l, this.offset.y));
|
|
132
137
|
} else {
|
|
133
|
-
const
|
|
134
|
-
this.offset.y = Math.min(o, Math.max(
|
|
138
|
+
const l = this.canvas.height - n - e, o = e;
|
|
139
|
+
this.offset.y = Math.min(o, Math.max(l, this.offset.y));
|
|
135
140
|
}
|
|
136
141
|
}
|
|
137
142
|
// --- 事件处理 ---
|
|
@@ -153,21 +158,21 @@ class he {
|
|
|
153
158
|
}
|
|
154
159
|
}
|
|
155
160
|
handleMouseDown(t) {
|
|
156
|
-
const n = this.canvas.getBoundingClientRect(), e = t.clientX - n.left,
|
|
161
|
+
const n = this.canvas.getBoundingClientRect(), e = t.clientX - n.left, l = t.clientY - n.top, o = this.toImageCoords(e, l);
|
|
157
162
|
if (this.interactionMode === "pan") {
|
|
158
|
-
this.isPanning = !0, this.panStartPoint = { x: e, y:
|
|
163
|
+
this.isPanning = !0, this.panStartPoint = { x: e, y: l }, this.canvas.style.cursor = "grabbing";
|
|
159
164
|
return;
|
|
160
165
|
}
|
|
161
166
|
if (this.interactionMode === "select" && this.activeAnnotation) {
|
|
162
|
-
const u = this.getHitHandle(e,
|
|
167
|
+
const u = this.getHitHandle(e, l, this.activeAnnotation);
|
|
163
168
|
if (u !== -100) {
|
|
164
169
|
this.isDragging = !0, this.dragStartPoint = o, this.selectedHandleIndex = u, this.dragStartAnnotation = JSON.parse(JSON.stringify(this.activeAnnotation));
|
|
165
170
|
return;
|
|
166
171
|
}
|
|
167
172
|
}
|
|
168
|
-
const
|
|
169
|
-
if (
|
|
170
|
-
this.activeAnnotation =
|
|
173
|
+
const a = this.interactionMode === "select" ? this.getHitCategory(e, l) : null;
|
|
174
|
+
if (a) {
|
|
175
|
+
this.activeAnnotation = a, this.isDragging = !1, this.selectedHandleIndex = -1, this.emit("annotationChange", { action: "select", changedItem: a, imageUrl: this.imageUrl }), this.render();
|
|
171
176
|
return;
|
|
172
177
|
}
|
|
173
178
|
const g = this.getHitAnnotation(o);
|
|
@@ -203,23 +208,23 @@ class he {
|
|
|
203
208
|
this.activeAnnotation = null, this.render();
|
|
204
209
|
}
|
|
205
210
|
handleMouseMove(t) {
|
|
206
|
-
const n = this.canvas.getBoundingClientRect(), e = t.clientX - n.left,
|
|
211
|
+
const n = this.canvas.getBoundingClientRect(), e = t.clientX - n.left, l = t.clientY - n.top, o = this.toImageCoords(e, l);
|
|
207
212
|
if (this.isPanning && this.panStartPoint) {
|
|
208
|
-
const
|
|
209
|
-
this.offset.x +=
|
|
213
|
+
const a = e - this.panStartPoint.x, g = l - this.panStartPoint.y;
|
|
214
|
+
this.offset.x += a, this.offset.y += g, this.clampViewportOffset(), this.panStartPoint = { x: e, y: l }, this.render();
|
|
210
215
|
return;
|
|
211
216
|
}
|
|
212
217
|
if (this.lastMouseMovePoint = o, this.isDrawing) {
|
|
213
218
|
if (this.currentTool === "polygon" && this.activeAnnotation) {
|
|
214
|
-
const
|
|
215
|
-
if (
|
|
216
|
-
const g =
|
|
219
|
+
const a = this.activeAnnotation.coordinates;
|
|
220
|
+
if (a.points.length > 2) {
|
|
221
|
+
const g = a.points[0], u = pt(o, g);
|
|
217
222
|
this.isHoveringStartPoint = u < 20 / this.scale;
|
|
218
223
|
} else
|
|
219
224
|
this.isHoveringStartPoint = !1;
|
|
220
225
|
}
|
|
221
226
|
this.updateDrawing(o);
|
|
222
|
-
} else this.isDragging && this.activeAnnotation && this.dragStartPoint ? this.updateDragging(o) : this.checkHover(e,
|
|
227
|
+
} else this.isDragging && this.activeAnnotation && this.dragStartPoint ? this.updateDragging(o) : this.checkHover(e, l, o);
|
|
223
228
|
this.render();
|
|
224
229
|
}
|
|
225
230
|
handleMouseUp(t) {
|
|
@@ -244,8 +249,8 @@ class he {
|
|
|
244
249
|
// 辅助函数:将 hex 转换为 rgba
|
|
245
250
|
hexToRgba(t, n) {
|
|
246
251
|
if (!t.startsWith("#")) return t;
|
|
247
|
-
const e = parseInt(t.slice(1, 3), 16),
|
|
248
|
-
return `rgba(${e}, ${
|
|
252
|
+
const e = parseInt(t.slice(1, 3), 16), l = parseInt(t.slice(3, 5), 16), o = parseInt(t.slice(5, 7), 16);
|
|
253
|
+
return `rgba(${e}, ${l}, ${o}, ${n})`;
|
|
249
254
|
}
|
|
250
255
|
startDrawing(t) {
|
|
251
256
|
if (!this.currentTool) return;
|
|
@@ -300,8 +305,8 @@ class he {
|
|
|
300
305
|
const n = this.activeAnnotation.coordinates;
|
|
301
306
|
n.x2 = t.x, n.y2 = t.y;
|
|
302
307
|
} else if (this.activeAnnotation.type === "rotatedRect" && this.dragStartPoint) {
|
|
303
|
-
const n = this.activeAnnotation.coordinates, e = Math.abs(t.x - this.dragStartPoint.x),
|
|
304
|
-
n.width = e * 2, n.height =
|
|
308
|
+
const n = this.activeAnnotation.coordinates, e = Math.abs(t.x - this.dragStartPoint.x), l = Math.abs(t.y - this.dragStartPoint.y);
|
|
309
|
+
n.width = e * 2, n.height = l * 2;
|
|
305
310
|
} else this.activeAnnotation.type;
|
|
306
311
|
}
|
|
307
312
|
finishDrawing() {
|
|
@@ -312,8 +317,8 @@ class he {
|
|
|
312
317
|
this.activeAnnotation = null, this.isDrawing = !1;
|
|
313
318
|
return;
|
|
314
319
|
}
|
|
315
|
-
const n = Math.min(t.x1, t.x2), e = Math.max(t.x1, t.x2),
|
|
316
|
-
t.x1 = n, t.x2 = e, t.y1 =
|
|
320
|
+
const n = Math.min(t.x1, t.x2), e = Math.max(t.x1, t.x2), l = Math.min(t.y1, t.y2), o = Math.max(t.y1, t.y2);
|
|
321
|
+
t.x1 = n, t.x2 = e, t.y1 = l, t.y2 = o, this.annotations.push(this.activeAnnotation), this.emit("annotationChange", { action: "add", changedItem: this.activeAnnotation, imageUrl: this.imageUrl });
|
|
317
322
|
} else if (this.activeAnnotation.type === "polygon") {
|
|
318
323
|
if (this.activeAnnotation.coordinates.points.length < 3) {
|
|
319
324
|
this.activeAnnotation = null, this.isDrawing = !1;
|
|
@@ -337,42 +342,42 @@ class he {
|
|
|
337
342
|
const n = t.x - this.dragStartPoint.x, e = t.y - this.dragStartPoint.y;
|
|
338
343
|
this.selectedHandleIndex === -1 ? this.moveAnnotation(this.activeAnnotation, this.dragStartAnnotation, n, e) : this.resizeAnnotation(this.activeAnnotation, this.dragStartAnnotation, this.selectedHandleIndex, t);
|
|
339
344
|
}
|
|
340
|
-
moveAnnotation(t, n, e,
|
|
345
|
+
moveAnnotation(t, n, e, l) {
|
|
341
346
|
if (t.type === "rectangle") {
|
|
342
|
-
const o = n.coordinates,
|
|
343
|
-
|
|
347
|
+
const o = n.coordinates, a = t.coordinates;
|
|
348
|
+
a.x1 = o.x1 + e, a.x2 = o.x2 + e, a.y1 = o.y1 + l, a.y2 = o.y2 + l;
|
|
344
349
|
} else if (t.type === "point") {
|
|
345
|
-
const o = n.coordinates,
|
|
346
|
-
|
|
350
|
+
const o = n.coordinates, a = t.coordinates;
|
|
351
|
+
a.points = o.points.map((g) => ({ x: g.x + e, y: g.y + l }));
|
|
347
352
|
} else if (t.type === "rotatedRect") {
|
|
348
|
-
const o = n.coordinates,
|
|
349
|
-
|
|
353
|
+
const o = n.coordinates, a = t.coordinates;
|
|
354
|
+
a.x = o.x + e, a.y = o.y + l;
|
|
350
355
|
} else if (t.type === "polygon") {
|
|
351
|
-
const o = n.coordinates,
|
|
352
|
-
|
|
356
|
+
const o = n.coordinates, a = t.coordinates;
|
|
357
|
+
a.points = o.points.map((g) => ({ x: g.x + e, y: g.y + l }));
|
|
353
358
|
} else if (t.type === "category") {
|
|
354
|
-
const o = n.coordinates,
|
|
355
|
-
o &&
|
|
359
|
+
const o = n.coordinates, a = t.coordinates;
|
|
360
|
+
o && a && (a.x = o.x + e, a.y = o.y + l);
|
|
356
361
|
}
|
|
357
362
|
}
|
|
358
|
-
resizeAnnotation(t, n, e,
|
|
363
|
+
resizeAnnotation(t, n, e, l) {
|
|
359
364
|
if (t.type === "rectangle") {
|
|
360
365
|
const o = t.coordinates;
|
|
361
|
-
e === 0 && (o.x1 =
|
|
366
|
+
e === 0 && (o.x1 = l.x, o.y1 = l.y), e === 1 && (o.x2 = l.x, o.y1 = l.y), e === 2 && (o.x2 = l.x, o.y2 = l.y), e === 3 && (o.x1 = l.x, o.y2 = l.y);
|
|
362
367
|
} else if (t.type === "polygon") {
|
|
363
368
|
const o = t.coordinates;
|
|
364
|
-
e >= 0 && e < o.points.length && (o.points[e] =
|
|
369
|
+
e >= 0 && e < o.points.length && (o.points[e] = l);
|
|
365
370
|
} else if (t.type === "point") {
|
|
366
371
|
const o = t.coordinates;
|
|
367
|
-
e >= 0 && e < o.points.length && (o.points[e] =
|
|
372
|
+
e >= 0 && e < o.points.length && (o.points[e] = l);
|
|
368
373
|
} else if (t.type === "rotatedRect") {
|
|
369
374
|
const o = t.coordinates;
|
|
370
375
|
if (e === -2) {
|
|
371
|
-
const
|
|
372
|
-
let
|
|
373
|
-
|
|
376
|
+
const a = o.x, g = o.y, u = l.x - a, r = l.y - g;
|
|
377
|
+
let A = Math.atan2(r, u) * 180 / Math.PI;
|
|
378
|
+
A += 90, o.angle = A;
|
|
374
379
|
} else {
|
|
375
|
-
const
|
|
380
|
+
const a = o.angle * Math.PI / 180, g = Math.cos(-a), u = Math.sin(-a), r = l.x - o.x, A = l.y - o.y, w = r * g - A * u, D = r * u + A * g;
|
|
376
381
|
(e === 0 || e === 3) && (o.width / 2, o.width = Math.abs(w) * 2), (e === 1 || e === 2) && (o.width = Math.abs(w) * 2), (e === 0 || e === 1) && (o.height = Math.abs(D) * 2), (e === 2 || e === 3) && (o.height = Math.abs(D) * 2);
|
|
377
382
|
}
|
|
378
383
|
}
|
|
@@ -394,18 +399,18 @@ class he {
|
|
|
394
399
|
const e = n.coordinates;
|
|
395
400
|
return re(t, e.points);
|
|
396
401
|
} else if (n.type === "rotatedRect") {
|
|
397
|
-
const e = n.coordinates,
|
|
398
|
-
return
|
|
402
|
+
const e = n.coordinates, l = At(t, { x: e.x, y: e.y }, -e.angle), o = e.width / 2, a = e.height / 2;
|
|
403
|
+
return l.x >= e.x - o && l.x <= e.x + o && l.y >= e.y - a && l.y <= e.y + a;
|
|
399
404
|
} else if (n.type === "point")
|
|
400
|
-
return n.coordinates.points.some((
|
|
405
|
+
return n.coordinates.points.some((l) => pt(t, l) < 10 / this.scale);
|
|
401
406
|
return !1;
|
|
402
407
|
}
|
|
403
408
|
getHitHandle(t, n, e) {
|
|
404
|
-
const
|
|
405
|
-
for (let
|
|
406
|
-
const g = a
|
|
409
|
+
const l = this.getAnnotationHandles(e), o = 6;
|
|
410
|
+
for (let a = 0; a < l.length; a++) {
|
|
411
|
+
const g = l[a], u = this.toScreenCoords(g.x, g.y);
|
|
407
412
|
if (Math.abs(t - u.x) < o && Math.abs(n - u.y) < o)
|
|
408
|
-
return e.type === "rotatedRect" &&
|
|
413
|
+
return e.type === "rotatedRect" && a === 4 ? -2 : a;
|
|
409
414
|
}
|
|
410
415
|
return -100;
|
|
411
416
|
}
|
|
@@ -428,16 +433,16 @@ class he {
|
|
|
428
433
|
if (t.type === "point")
|
|
429
434
|
return t.coordinates.points;
|
|
430
435
|
if (t.type === "rotatedRect") {
|
|
431
|
-
const n = t.coordinates, e = { x: n.x, y: n.y },
|
|
432
|
-
return [
|
|
436
|
+
const n = t.coordinates, e = { x: n.x, y: n.y }, l = n.width / 2, o = n.height / 2, a = { x: n.x - l, y: n.y - o }, g = { x: n.x + l, y: n.y - o }, u = { x: n.x + l, y: n.y + o }, r = { x: n.x - l, y: n.y + o }, A = { x: n.x, y: n.y - o - 20 / this.scale };
|
|
437
|
+
return [a, g, u, r, A].map((w) => At(w, e, n.angle));
|
|
433
438
|
}
|
|
434
439
|
}
|
|
435
440
|
return [];
|
|
436
441
|
}
|
|
437
442
|
checkHover(t, n, e) {
|
|
438
|
-
const
|
|
439
|
-
if (
|
|
440
|
-
this.canvas.style.cursor = "pointer", this.hoverAnnotation =
|
|
443
|
+
const l = this.getHitCategory(t, n);
|
|
444
|
+
if (l) {
|
|
445
|
+
this.canvas.style.cursor = "pointer", this.hoverAnnotation = l;
|
|
441
446
|
return;
|
|
442
447
|
}
|
|
443
448
|
if (this.activeAnnotation && this.getHitHandle(t, n, this.activeAnnotation) !== -100) {
|
|
@@ -463,76 +468,103 @@ class he {
|
|
|
463
468
|
const n = 12;
|
|
464
469
|
t.forEach((e) => {
|
|
465
470
|
var _;
|
|
466
|
-
const
|
|
471
|
+
const l = e.label || "未命名分类", o = this.ctx.measureText(l).width + n * 2, a = 28, g = this.activeAnnotation === e, u = this.hoverAnnotation === e;
|
|
467
472
|
let r = { x: 20, y: 20 };
|
|
468
473
|
e.coordinates && typeof e.coordinates.x == "number" && typeof e.coordinates.y == "number" && (r = this.toScreenCoords(e.coordinates.x, e.coordinates.y));
|
|
469
|
-
const
|
|
470
|
-
this.ctx.fillStyle = g ? D : this.hexToRgba(D, 0.85), u && !g && (this.ctx.fillStyle = D), g ? (this.ctx.strokeStyle = "#ffffff", this.ctx.lineWidth = 2) : (this.ctx.strokeStyle = "transparent", this.ctx.lineWidth = 0), this.ctx.beginPath(), this.ctx.roundRect(
|
|
474
|
+
const A = r.x - o / 2, w = r.y - a / 2, D = ((_ = e.style) == null ? void 0 : _.strokeColor) || "#2196F3";
|
|
475
|
+
this.ctx.fillStyle = g ? D : this.hexToRgba(D, 0.85), u && !g && (this.ctx.fillStyle = D), g ? (this.ctx.strokeStyle = "#ffffff", this.ctx.lineWidth = 2) : (this.ctx.strokeStyle = "transparent", this.ctx.lineWidth = 0), this.ctx.beginPath(), this.ctx.roundRect(A, w, o, a, 6), this.ctx.fill(), g && (this.ctx.stroke(), this.ctx.save(), this.ctx.strokeStyle = D, this.ctx.lineWidth = 2, this.ctx.strokeRect(A - 3, w - 3, o + 6, a + 6), this.ctx.restore()), this.ctx.fillStyle = "#ffffff", this.ctx.fillText(l, r.x, r.y);
|
|
471
476
|
}), this.ctx.restore();
|
|
472
477
|
}
|
|
473
478
|
getHitCategory(t, n) {
|
|
474
479
|
const e = this.annotations.filter((g) => g.type === "category");
|
|
475
480
|
if (e.length === 0) return null;
|
|
476
481
|
this.ctx.save(), this.ctx.font = "14px sans-serif";
|
|
477
|
-
const
|
|
478
|
-
let
|
|
482
|
+
const l = 12, o = 28;
|
|
483
|
+
let a = null;
|
|
479
484
|
for (let g = e.length - 1; g >= 0; g--) {
|
|
480
|
-
const u = e[g], r = u.label || "未命名分类",
|
|
485
|
+
const u = e[g], r = u.label || "未命名分类", A = this.ctx.measureText(r).width + l * 2;
|
|
481
486
|
let w = { x: 20, y: 20 };
|
|
482
487
|
u.coordinates && typeof u.coordinates.x == "number" && typeof u.coordinates.y == "number" && (w = this.toScreenCoords(u.coordinates.x, u.coordinates.y));
|
|
483
|
-
const D = w.x -
|
|
484
|
-
if (t >= D && t <= D +
|
|
485
|
-
|
|
488
|
+
const D = w.x - A / 2, _ = w.y - o / 2;
|
|
489
|
+
if (t >= D && t <= D + A && n >= _ && n <= _ + o) {
|
|
490
|
+
a = u;
|
|
486
491
|
break;
|
|
487
492
|
}
|
|
488
493
|
}
|
|
489
|
-
return this.ctx.restore(),
|
|
494
|
+
return this.ctx.restore(), a;
|
|
490
495
|
}
|
|
491
496
|
drawItem(t, n) {
|
|
492
497
|
var o;
|
|
493
498
|
if (this.visibleLabels.size > 0 && !this.visibleLabels.has(t.label) && !n)
|
|
494
499
|
return;
|
|
495
500
|
this.ctx.save();
|
|
496
|
-
const e = ((o = t.style) == null ? void 0 : o.strokeColor) || "#FF4081",
|
|
497
|
-
if (this.ctx.strokeStyle =
|
|
498
|
-
const
|
|
499
|
-
this.ctx.strokeRect(r,
|
|
501
|
+
const e = ((o = t.style) == null ? void 0 : o.strokeColor) || "#FF4081", l = n ? "#00E5FF" : e;
|
|
502
|
+
if (this.ctx.strokeStyle = l, this.ctx.lineWidth = 2, t.type === "rectangle") {
|
|
503
|
+
const a = t.coordinates, g = this.toScreenCoords(a.x1, a.y1), u = this.toScreenCoords(a.x2, a.y2), r = Math.min(g.x, u.x), A = Math.min(g.y, u.y), w = Math.abs(g.x - u.x), D = Math.abs(g.y - u.y);
|
|
504
|
+
this.ctx.strokeRect(r, A, w, D), n && this.drawHandles(this.getAnnotationHandles(t));
|
|
500
505
|
} else if (t.type === "polygon") {
|
|
501
|
-
const
|
|
502
|
-
if (
|
|
506
|
+
const a = t.coordinates;
|
|
507
|
+
if (a.points.length === 0) {
|
|
503
508
|
this.ctx.restore();
|
|
504
509
|
return;
|
|
505
510
|
}
|
|
506
511
|
this.ctx.beginPath();
|
|
507
|
-
const g = this.toScreenCoords(
|
|
512
|
+
const g = this.toScreenCoords(a.points[0].x, a.points[0].y);
|
|
508
513
|
this.ctx.moveTo(g.x, g.y);
|
|
509
|
-
for (let u = 1; u <
|
|
510
|
-
const r = this.toScreenCoords(
|
|
514
|
+
for (let u = 1; u < a.points.length; u++) {
|
|
515
|
+
const r = this.toScreenCoords(a.points[u].x, a.points[u].y);
|
|
511
516
|
this.ctx.lineTo(r.x, r.y);
|
|
512
517
|
}
|
|
513
518
|
if (!this.isDrawing || t !== this.activeAnnotation)
|
|
514
519
|
this.ctx.closePath();
|
|
515
520
|
else if (this.lastMouseMovePoint) {
|
|
516
521
|
let u = this.lastMouseMovePoint;
|
|
517
|
-
if (this.isHoveringStartPoint &&
|
|
518
|
-
u =
|
|
519
|
-
const
|
|
520
|
-
this.ctx.save(), this.ctx.beginPath(), this.ctx.arc(
|
|
522
|
+
if (this.isHoveringStartPoint && a.points.length > 0) {
|
|
523
|
+
u = a.points[0];
|
|
524
|
+
const A = this.toScreenCoords(a.points[0].x, a.points[0].y);
|
|
525
|
+
this.ctx.save(), this.ctx.beginPath(), this.ctx.arc(A.x, A.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();
|
|
521
526
|
}
|
|
522
527
|
const r = this.toScreenCoords(u.x, u.y);
|
|
523
528
|
this.ctx.lineTo(r.x, r.y);
|
|
524
529
|
}
|
|
525
530
|
this.ctx.stroke(), n && this.drawHandles(this.getAnnotationHandles(t));
|
|
526
531
|
} else if (t.type === "rotatedRect") {
|
|
527
|
-
const
|
|
528
|
-
this.ctx.translate(this.toScreenCoords(
|
|
529
|
-
const g =
|
|
530
|
-
this.ctx.strokeRect(-g / 2, -u / 2, g, u), this.ctx.rotate(-
|
|
532
|
+
const a = t.coordinates;
|
|
533
|
+
this.ctx.translate(this.toScreenCoords(a.x, a.y).x, this.toScreenCoords(a.x, a.y).y), this.ctx.rotate(a.angle * Math.PI / 180);
|
|
534
|
+
const g = a.width * this.scale, u = a.height * this.scale;
|
|
535
|
+
this.ctx.strokeRect(-g / 2, -u / 2, g, u), this.ctx.rotate(-a.angle * Math.PI / 180), this.ctx.translate(-this.toScreenCoords(a.x, a.y).x, -this.toScreenCoords(a.x, a.y).y), n && this.drawHandles(this.getAnnotationHandles(t));
|
|
531
536
|
} else t.type === "point" && t.coordinates.points.forEach((g) => {
|
|
532
537
|
const u = this.toScreenCoords(g.x, g.y);
|
|
533
538
|
this.ctx.beginPath(), this.ctx.arc(u.x, u.y, 5, 0, Math.PI * 2), this.ctx.fillStyle = n ? "#00E5FF" : e, this.ctx.fill(), this.ctx.stroke();
|
|
534
539
|
});
|
|
535
|
-
this.ctx.restore();
|
|
540
|
+
this.showLabels && t.label && t.type !== "category" && this.drawAnnotationLabel(t, e), this.ctx.restore();
|
|
541
|
+
}
|
|
542
|
+
drawAnnotationLabel(t, n) {
|
|
543
|
+
let e = 0, l = 0;
|
|
544
|
+
if (t.type === "rectangle") {
|
|
545
|
+
const o = t.coordinates, a = this.toScreenCoords(Math.min(o.x1, o.x2), Math.min(o.y1, o.y2));
|
|
546
|
+
e = a.x, l = a.y - 8;
|
|
547
|
+
} else if (t.type === "polygon") {
|
|
548
|
+
const o = t.coordinates;
|
|
549
|
+
if (o.points.length > 0) {
|
|
550
|
+
const a = this.toScreenCoords(o.points[0].x, o.points[0].y);
|
|
551
|
+
e = a.x, l = a.y - 8;
|
|
552
|
+
}
|
|
553
|
+
} else if (t.type === "rotatedRect") {
|
|
554
|
+
const o = t.coordinates, a = this.toScreenCoords(o.x, o.y - o.height / 2);
|
|
555
|
+
e = a.x, l = a.y - 8;
|
|
556
|
+
} else if (t.type === "point") {
|
|
557
|
+
const o = t.coordinates;
|
|
558
|
+
if (o.points.length > 0) {
|
|
559
|
+
const a = this.toScreenCoords(o.points[0].x, o.points[0].y);
|
|
560
|
+
e = a.x, l = a.y - 8;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
if (e !== 0 || l !== 0) {
|
|
564
|
+
this.ctx.save(), this.ctx.font = "12px sans-serif", this.ctx.textBaseline = "bottom";
|
|
565
|
+
const o = t.label, a = this.ctx.measureText(o).width, g = 8, u = 4;
|
|
566
|
+
this.ctx.fillStyle = this.hexToRgba(n, 0.8), this.ctx.beginPath(), this.ctx.roundRect(e, l - 14 - u, a + g * 2, 14 + u * 2, 4), this.ctx.fill(), this.ctx.fillStyle = "#FFFFFF", this.ctx.fillText(o, e + g, l), this.ctx.restore();
|
|
567
|
+
}
|
|
536
568
|
}
|
|
537
569
|
drawHandles(t) {
|
|
538
570
|
this.ctx.fillStyle = "#FFFFFF", this.ctx.strokeStyle = "#000000", this.ctx.lineWidth = 1, t.forEach((n) => {
|
|
@@ -547,25 +579,25 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
547
579
|
name: {},
|
|
548
580
|
size: {}
|
|
549
581
|
},
|
|
550
|
-
setup(
|
|
551
|
-
const t =
|
|
582
|
+
setup(y) {
|
|
583
|
+
const t = y, n = M(""), e = /* @__PURE__ */ Object.assign({ "../assets/svg/aim.svg": de, "../assets/svg/back.svg": ge, "../assets/svg/connection.svg": ue, "../assets/svg/crop.svg": ve, "../assets/svg/delete.svg": fe, "../assets/svg/download.svg": me, "../assets/svg/edit.svg": pe, "../assets/svg/first.svg": ye, "../assets/svg/hide.svg": xe, "../assets/svg/last.svg": we, "../assets/svg/pointer.svg": be, "../assets/svg/price-tag.svg": Ce, "../assets/svg/rank.svg": _e, "../assets/svg/refresh-right.svg": ke, "../assets/svg/right.svg": Ie, "../assets/svg/view.svg": Ae, "../assets/svg/zoom-in.svg": Se, "../assets/svg/zoom-out.svg": Me });
|
|
552
584
|
return ce(() => {
|
|
553
|
-
const
|
|
554
|
-
o ? n.value = o : (console.warn(`Icon ${t.name} not found at path ${
|
|
555
|
-
}), (
|
|
556
|
-
class:
|
|
585
|
+
const l = `../assets/svg/${t.name}.svg`, o = e[l];
|
|
586
|
+
o ? n.value = o : (console.warn(`Icon ${t.name} not found at path ${l}`), n.value = "");
|
|
587
|
+
}), (l, o) => (v(), m("i", {
|
|
588
|
+
class: q(["svg-icon", [y.size ? `size-${y.size}` : ""]]),
|
|
557
589
|
innerHTML: n.value
|
|
558
590
|
}, null, 10, Te));
|
|
559
591
|
}
|
|
560
|
-
}), rt = (
|
|
561
|
-
const n =
|
|
562
|
-
for (const [e,
|
|
563
|
-
n[e] =
|
|
592
|
+
}), rt = (y, t) => {
|
|
593
|
+
const n = y.__vccOpts || y;
|
|
594
|
+
for (const [e, l] of t)
|
|
595
|
+
n[e] = l;
|
|
564
596
|
return n;
|
|
565
|
-
},
|
|
597
|
+
}, $ = /* @__PURE__ */ rt(De, [["__scopeId", "data-v-3928607b"]]), Pe = {
|
|
566
598
|
key: 0,
|
|
567
599
|
class: "image-list-sidebar"
|
|
568
|
-
},
|
|
600
|
+
}, Le = { class: "image-list-header" }, ze = ["onClick"], $e = { class: "image-list-stage" }, Re = ["src", "alt"], Be = {
|
|
569
601
|
key: 0,
|
|
570
602
|
class: "thumb-overlay-layer"
|
|
571
603
|
}, He = {
|
|
@@ -573,13 +605,13 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
573
605
|
class: "thumb-overlay-svg",
|
|
574
606
|
viewBox: "0 0 100 100",
|
|
575
607
|
preserveAspectRatio: "none"
|
|
576
|
-
}, Ee = ["points"], Ue = { class: "image-list-text" },
|
|
608
|
+
}, Ee = ["points"], Ue = { class: "image-list-text" }, Oe = { class: "center-sidebar" }, Ve = {
|
|
577
609
|
key: 0,
|
|
578
610
|
class: "left-sidebar"
|
|
579
|
-
}, Fe = ["onClick", "title"],
|
|
611
|
+
}, Fe = ["onClick", "title"], We = {
|
|
580
612
|
key: 0,
|
|
581
613
|
class: "divider"
|
|
582
|
-
},
|
|
614
|
+
}, Ne = { class: "center-area" }, Ge = {
|
|
583
615
|
key: 0,
|
|
584
616
|
class: "floating-label-selector"
|
|
585
617
|
}, Ye = {
|
|
@@ -617,8 +649,8 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
617
649
|
maxZoom: {}
|
|
618
650
|
},
|
|
619
651
|
emits: ["annotationChange", "batchChange", "labelChange", "ready", "error", "tool:change", "viewport:change", "annotation:add", "annotation:update", "annotation:delete", "annotation:select", "prediction:loaded", "prediction:apply", "prediction:reject"],
|
|
620
|
-
setup(
|
|
621
|
-
const e =
|
|
652
|
+
setup(y, { expose: t, emit: n }) {
|
|
653
|
+
const e = y, l = n, o = M(null), a = M(null), g = M(null), u = M([]), r = M(null), A = M(null), w = M(0), D = M(""), _ = M([]), z = M(""), X = M(!1), C = M({ name: "", color: "#FF0000" }), S = M("none"), x = M([]), H = M({}), V = O(() => A.value === "select" && !!D.value), G = M(!1), Z = O(() => _.value.find((s) => s.id === z.value)), xt = (s) => {
|
|
622
654
|
s.stopPropagation(), G.value = !G.value;
|
|
623
655
|
}, wt = (s) => {
|
|
624
656
|
tt(s), G.value = !1;
|
|
@@ -632,10 +664,10 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
632
664
|
if (!s || H.value[s]) return;
|
|
633
665
|
const i = new Image();
|
|
634
666
|
i.onload = () => {
|
|
635
|
-
const
|
|
667
|
+
const c = i.naturalWidth || 1, d = i.naturalHeight || 1;
|
|
636
668
|
H.value = {
|
|
637
669
|
...H.value,
|
|
638
|
-
[s]: { width:
|
|
670
|
+
[s]: { width: c, height: d }
|
|
639
671
|
};
|
|
640
672
|
}, i.src = s;
|
|
641
673
|
}, nt = () => {
|
|
@@ -645,12 +677,12 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
645
677
|
}, ht = (s, i) => {
|
|
646
678
|
u.value[i] = s;
|
|
647
679
|
}, Q = (s = w.value) => {
|
|
648
|
-
const i = g.value,
|
|
649
|
-
if (!i || !
|
|
650
|
-
const d = i.scrollTop, f = d + i.clientHeight,
|
|
651
|
-
if (
|
|
680
|
+
const i = g.value, c = u.value[s];
|
|
681
|
+
if (!i || !c) return;
|
|
682
|
+
const d = i.scrollTop, f = d + i.clientHeight, I = c.offsetTop, P = I + c.offsetHeight;
|
|
683
|
+
if (I < d) {
|
|
652
684
|
i.scrollTo({
|
|
653
|
-
top: Math.max(
|
|
685
|
+
top: Math.max(I - 8, 0),
|
|
654
686
|
behavior: "smooth"
|
|
655
687
|
});
|
|
656
688
|
return;
|
|
@@ -660,28 +692,28 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
660
692
|
behavior: "smooth"
|
|
661
693
|
});
|
|
662
694
|
}, j = () => {
|
|
663
|
-
var
|
|
664
|
-
const s = e.batchImages[w.value], i = (s == null ? void 0 : s.imageUrl) || ((
|
|
695
|
+
var c, d, f, I;
|
|
696
|
+
const s = e.batchImages[w.value], i = (s == null ? void 0 : s.imageUrl) || ((c = e.image) == null ? void 0 : c.url);
|
|
665
697
|
return {
|
|
666
698
|
eventId: `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`,
|
|
667
699
|
timestamp: Date.now(),
|
|
668
700
|
requestId: e.requestId,
|
|
669
701
|
taskId: (d = e.session) == null ? void 0 : d.taskId,
|
|
670
702
|
imageId: ((f = e.image) == null ? void 0 : f.id) || i,
|
|
671
|
-
operator: (
|
|
703
|
+
operator: (I = e.session) == null ? void 0 : I.userId
|
|
672
704
|
};
|
|
673
|
-
},
|
|
705
|
+
}, p = (s) => {
|
|
674
706
|
var d;
|
|
675
707
|
const i = s == null ? void 0 : s.action;
|
|
676
708
|
if (!i) return;
|
|
677
|
-
const
|
|
709
|
+
const c = {
|
|
678
710
|
meta: j(),
|
|
679
711
|
action: i,
|
|
680
712
|
current: s == null ? void 0 : s.changedItem,
|
|
681
713
|
source: (d = s == null ? void 0 : s.changedItem) != null && d.predictionId ? "prediction" : "manual"
|
|
682
714
|
};
|
|
683
|
-
i === "add" &&
|
|
684
|
-
}, b =
|
|
715
|
+
i === "add" && l("annotation:add", c), i === "update" && l("annotation:update", c), i === "delete" && l("annotation:delete", c), i === "select" && l("annotation:select", c);
|
|
716
|
+
}, b = O(() => e.annotationTypes), k = (s) => ({
|
|
685
717
|
rectangle: "crop",
|
|
686
718
|
polygon: "connection",
|
|
687
719
|
point: "aim",
|
|
@@ -696,28 +728,28 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
696
728
|
})[s] || s;
|
|
697
729
|
yt(() => {
|
|
698
730
|
if (nt(), o.value) {
|
|
699
|
-
r.value = new he(o.value), r.value.on("annotationChange", (i) => {
|
|
700
|
-
var
|
|
731
|
+
r.value = new he(o.value), r.value.setShowLabels(e.readOnly), r.value.on("annotationChange", (i) => {
|
|
732
|
+
var c, d;
|
|
701
733
|
if (i.action === "add" && i.changedItem) {
|
|
702
|
-
const f = _.value.find((
|
|
734
|
+
const f = _.value.find((I) => I.id === z.value);
|
|
703
735
|
f && (i.changedItem.label = f.name, i.changedItem.labelId = f.id);
|
|
704
736
|
}
|
|
705
|
-
i.action === "select" ? D.value = ((
|
|
706
|
-
}),
|
|
737
|
+
i.action === "select" ? D.value = ((c = i.changedItem) == null ? void 0 : c.id) || "" : i.action === "delete" && ((d = i.changedItem) == null ? void 0 : d.id) === D.value && (D.value = ""), l("annotationChange", i), p(i);
|
|
738
|
+
}), N(), E();
|
|
707
739
|
const s = new ResizeObserver(() => {
|
|
708
740
|
var i;
|
|
709
741
|
(i = r.value) == null || i.resize();
|
|
710
742
|
});
|
|
711
|
-
|
|
743
|
+
a.value && s.observe(a.value), e.defaultActiveType && Y(e.defaultActiveType), at(() => Q()), l("ready", { meta: j() });
|
|
712
744
|
}
|
|
713
745
|
});
|
|
714
746
|
const E = () => {
|
|
715
747
|
if (!r.value) return;
|
|
716
|
-
const s = _.value.find((
|
|
748
|
+
const s = _.value.find((c) => c.id === z.value);
|
|
717
749
|
s && r.value.setLabelStyle(s.color);
|
|
718
|
-
const i = _.value.filter((
|
|
750
|
+
const i = _.value.filter((c) => c.visible).map((c) => c.name);
|
|
719
751
|
r.value.setVisibleLabels(i);
|
|
720
|
-
},
|
|
752
|
+
}, N = () => {
|
|
721
753
|
var s;
|
|
722
754
|
if (r.value)
|
|
723
755
|
if (D.value = "", requestAnimationFrame(() => {
|
|
@@ -728,17 +760,17 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
728
760
|
r.value.loadImage(i.imageUrl), i.annotations ? r.value.setAnnotations(i.annotations) : r.value.setAnnotations([]);
|
|
729
761
|
} else (s = e.image) != null && s.url && r.value.loadImage(e.image.url);
|
|
730
762
|
}, Y = (s) => {
|
|
731
|
-
var i,
|
|
732
|
-
if (
|
|
763
|
+
var i, c;
|
|
764
|
+
if (A.value = s, D.value = "", s !== "pan" && s !== "select" && _.value.length === 0) {
|
|
733
765
|
alert("请先创建标签!");
|
|
734
766
|
return;
|
|
735
767
|
}
|
|
736
|
-
s === "pan" || s === "select" ? (i = r.value) == null || i.setTool(s) : (
|
|
768
|
+
s === "pan" || s === "select" ? (i = r.value) == null || i.setTool(s) : (c = r.value) == null || c.setTool(s), l("tool:change", { meta: j(), tool: s });
|
|
737
769
|
}, St = () => {
|
|
738
770
|
var s;
|
|
739
771
|
(s = r.value) != null && s.activeAnnotation && r.value.deleteAnnotation(r.value.activeAnnotation.id);
|
|
740
772
|
}, bt = () => {
|
|
741
|
-
r.value &&
|
|
773
|
+
r.value && l("viewport:change", {
|
|
742
774
|
meta: j(),
|
|
743
775
|
scale: r.value.scale,
|
|
744
776
|
offset: { ...r.value.offset }
|
|
@@ -750,9 +782,9 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
750
782
|
var s;
|
|
751
783
|
(s = r.value) == null || s.zoom(-1), bt();
|
|
752
784
|
}, Dt = () => {
|
|
753
|
-
C.value = { name: "", color: "#2196F3" },
|
|
785
|
+
C.value = { name: "", color: "#2196F3" }, X.value = !0;
|
|
754
786
|
}, dt = () => {
|
|
755
|
-
|
|
787
|
+
X.value = !1;
|
|
756
788
|
}, Pt = () => {
|
|
757
789
|
if (!C.value.name.trim()) {
|
|
758
790
|
alert("请输入标签名称");
|
|
@@ -764,47 +796,47 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
764
796
|
color: C.value.color,
|
|
765
797
|
visible: !0
|
|
766
798
|
};
|
|
767
|
-
_.value.push(i),
|
|
799
|
+
_.value.push(i), l("labelChange", _.value), E(), _.value.length === 1 && tt(i), dt();
|
|
768
800
|
}, tt = (s) => {
|
|
769
801
|
var i;
|
|
770
|
-
|
|
771
|
-
},
|
|
802
|
+
z.value = s.id, (i = r.value) == null || i.setLabelStyle(s.color);
|
|
803
|
+
}, Lt = (s, i) => {
|
|
772
804
|
if (!s.startsWith("#")) return s;
|
|
773
|
-
let
|
|
774
|
-
return s.length === 4 ? (
|
|
775
|
-
},
|
|
805
|
+
let c = 0, d = 0, f = 0;
|
|
806
|
+
return s.length === 4 ? (c = parseInt(s[1] + s[1], 16), d = parseInt(s[2] + s[2], 16), f = parseInt(s[3] + s[3], 16)) : s.length === 7 && (c = parseInt(s.slice(1, 3), 16), d = parseInt(s.slice(3, 5), 16), f = parseInt(s.slice(5, 7), 16)), `rgba(${c}, ${d}, ${f}, ${i})`;
|
|
807
|
+
}, zt = (s) => {
|
|
776
808
|
var i;
|
|
777
|
-
if (s.id ===
|
|
778
|
-
const
|
|
809
|
+
if (s.id === z.value && ((i = r.value) == null || i.setLabelStyle(s.color)), r.value) {
|
|
810
|
+
const c = r.value.getAnnotations();
|
|
779
811
|
let d = !1;
|
|
780
|
-
|
|
781
|
-
f.label === s.name && (f.style || (f.style = {}), f.style.strokeColor = s.color, f.style.fillColor =
|
|
812
|
+
c.forEach((f) => {
|
|
813
|
+
f.label === s.name && (f.style || (f.style = {}), f.style.strokeColor = s.color, f.style.fillColor = Lt(s.color, 0.2), d = !0);
|
|
782
814
|
}), d && r.value.render();
|
|
783
815
|
}
|
|
784
|
-
|
|
785
|
-
},
|
|
816
|
+
l("labelChange", _.value), E();
|
|
817
|
+
}, $t = (s) => {
|
|
786
818
|
s.visible = !s.visible, E();
|
|
787
|
-
},
|
|
788
|
-
const i = _.value.findIndex((
|
|
789
|
-
i > -1 && (_.value.splice(i, 1),
|
|
819
|
+
}, Rt = (s) => {
|
|
820
|
+
const i = _.value.findIndex((c) => c.id === s);
|
|
821
|
+
i > -1 && (_.value.splice(i, 1), l("labelChange", _.value), z.value === s && (z.value = _.value.length > 0 ? _.value[0].id : "", z.value && tt(_.value[0])), E());
|
|
790
822
|
};
|
|
791
823
|
K(() => e.labels, (s) => {
|
|
792
824
|
const i = JSON.parse(JSON.stringify(s || []));
|
|
793
825
|
if (_.value = i, _.value.length > 0)
|
|
794
|
-
if (
|
|
826
|
+
if (!z.value || !_.value.find((c) => c.id === z.value))
|
|
795
827
|
tt(_.value[0]);
|
|
796
828
|
else {
|
|
797
|
-
const
|
|
798
|
-
|
|
829
|
+
const c = _.value.find((d) => d.id === z.value);
|
|
830
|
+
c && tt(c);
|
|
799
831
|
}
|
|
800
832
|
else
|
|
801
|
-
|
|
833
|
+
z.value = "";
|
|
802
834
|
E();
|
|
803
835
|
}, { immediate: !0, deep: !0 });
|
|
804
|
-
const
|
|
805
|
-
w.value > 0 && (gt(), w.value--,
|
|
836
|
+
const Bt = () => {
|
|
837
|
+
w.value > 0 && (gt(), w.value--, N(), ut());
|
|
806
838
|
}, Ht = () => {
|
|
807
|
-
w.value < e.batchImages.length - 1 && (gt(), w.value++,
|
|
839
|
+
w.value < e.batchImages.length - 1 && (gt(), w.value++, N(), ut());
|
|
808
840
|
}, Et = () => {
|
|
809
841
|
w.value > 0 && ot(0);
|
|
810
842
|
}, Ut = () => {
|
|
@@ -816,7 +848,7 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
816
848
|
}
|
|
817
849
|
}, ut = () => {
|
|
818
850
|
const s = e.batchImages[w.value];
|
|
819
|
-
|
|
851
|
+
l("batchChange", {
|
|
820
852
|
currentIndex: w.value,
|
|
821
853
|
total: e.batchImages.length,
|
|
822
854
|
currentImageUrl: s.imageUrl,
|
|
@@ -825,68 +857,68 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
825
857
|
}, Ct = (s = []) => {
|
|
826
858
|
var f;
|
|
827
859
|
if (!r.value) return;
|
|
828
|
-
if (
|
|
860
|
+
if (x.value = JSON.parse(JSON.stringify(s)), x.value.length === 0) {
|
|
829
861
|
S.value = "none";
|
|
830
862
|
return;
|
|
831
863
|
}
|
|
832
864
|
S.value = "loaded";
|
|
833
|
-
const
|
|
834
|
-
const P = JSON.parse(JSON.stringify(
|
|
835
|
-
return P.id = P.id || `pred-${
|
|
865
|
+
const c = (r.value.getAnnotations() || []).filter((I) => !I.predictionId), d = x.value.map((I) => {
|
|
866
|
+
const P = JSON.parse(JSON.stringify(I.annotation));
|
|
867
|
+
return P.id = P.id || `pred-${I.id}`, P.predictionId = I.id, P.modelRunId = I.modelRunId || P.modelRunId, P.confidence = I.confidence ?? P.confidence, P.reviewStatus = P.reviewStatus || "draft", P;
|
|
836
868
|
});
|
|
837
|
-
r.value.setAnnotations([...
|
|
869
|
+
r.value.setAnnotations([...c, ...d]), l("prediction:loaded", {
|
|
838
870
|
meta: j(),
|
|
839
|
-
modelRunId: (f =
|
|
840
|
-
candidates:
|
|
871
|
+
modelRunId: (f = x.value[0]) == null ? void 0 : f.modelRunId,
|
|
872
|
+
candidates: x.value
|
|
841
873
|
});
|
|
842
|
-
},
|
|
874
|
+
}, Ot = (s, i) => {
|
|
843
875
|
var f;
|
|
844
876
|
if (!r.value) return [];
|
|
845
877
|
S.value = "applying";
|
|
846
|
-
const d = (r.value.getAnnotations() || []).filter((
|
|
847
|
-
return d.forEach((
|
|
848
|
-
|
|
849
|
-
}), S.value = "applied",
|
|
878
|
+
const d = (r.value.getAnnotations() || []).filter((I) => I.predictionId && s.includes(I.predictionId));
|
|
879
|
+
return d.forEach((I) => {
|
|
880
|
+
I.reviewStatus = "accepted";
|
|
881
|
+
}), S.value = "applied", l("prediction:apply", {
|
|
850
882
|
meta: j(),
|
|
851
883
|
modelRunId: (f = d[0]) == null ? void 0 : f.modelRunId,
|
|
852
884
|
candidateIds: s,
|
|
853
885
|
threshold: i,
|
|
854
886
|
acceptedAnnotations: d
|
|
855
887
|
}), r.value.render(), d;
|
|
856
|
-
},
|
|
888
|
+
}, Vt = (s, i) => {
|
|
857
889
|
var f;
|
|
858
890
|
if (!r.value) return;
|
|
859
|
-
const
|
|
860
|
-
r.value.setAnnotations(d),
|
|
891
|
+
const c = r.value.getAnnotations() || [], d = c.filter((I) => !(I.predictionId && s.includes(I.predictionId)));
|
|
892
|
+
r.value.setAnnotations(d), l("prediction:reject", {
|
|
861
893
|
meta: j(),
|
|
862
|
-
modelRunId: (f =
|
|
894
|
+
modelRunId: (f = c.find((I) => I.predictionId && s.includes(I.predictionId))) == null ? void 0 : f.modelRunId,
|
|
863
895
|
candidateIds: s,
|
|
864
896
|
reason: i
|
|
865
897
|
});
|
|
866
898
|
}, Ft = (s, i = []) => {
|
|
867
899
|
r.value && (r.value.loadImage(s.url), r.value.setAnnotations(i));
|
|
868
|
-
},
|
|
900
|
+
}, Wt = (s) => {
|
|
869
901
|
var i;
|
|
870
902
|
(i = r.value) == null || i.setAnnotations(s);
|
|
871
903
|
}, _t = () => {
|
|
872
904
|
var s;
|
|
873
905
|
return ((s = r.value) == null ? void 0 : s.getAnnotations()) || [];
|
|
874
|
-
},
|
|
875
|
-
var
|
|
906
|
+
}, Nt = (s = "json") => {
|
|
907
|
+
var c, d;
|
|
876
908
|
const i = _t();
|
|
877
909
|
return {
|
|
878
910
|
format: s,
|
|
879
|
-
image: ((
|
|
911
|
+
image: ((c = e.batchImages[w.value]) == null ? void 0 : c.imageUrl) || ((d = e.image) == null ? void 0 : d.url) || "",
|
|
880
912
|
annotations: i
|
|
881
913
|
};
|
|
882
914
|
}, ot = (s) => {
|
|
883
|
-
s >= 0 && s < e.batchImages.length && (gt(), w.value = s,
|
|
915
|
+
s >= 0 && s < e.batchImages.length && (gt(), w.value = s, N(), ut());
|
|
884
916
|
}, Gt = (s) => {
|
|
885
917
|
var i;
|
|
886
918
|
return s === w.value && r.value ? r.value.getAnnotations() || [] : ((i = e.batchImages[s]) == null ? void 0 : i.annotations) || [];
|
|
887
919
|
}, Yt = (s) => s.type === "rectangle", Jt = (s) => s.type === "polygon", jt = (s) => s.type === "point", Xt = (s) => s.type === "rotatedRect", qt = (s) => s.type === "category", et = (s) => {
|
|
888
|
-
var
|
|
889
|
-
const i = (
|
|
920
|
+
var c, d;
|
|
921
|
+
const i = (c = _.value.find((f) => f.name === s.label)) == null ? void 0 : c.color;
|
|
890
922
|
return ((d = s.style) == null ? void 0 : d.strokeColor) || i || "#409eff";
|
|
891
923
|
}, kt = (s) => {
|
|
892
924
|
const i = s.coordinates;
|
|
@@ -895,24 +927,24 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
895
927
|
const i = e.batchImages[s];
|
|
896
928
|
if (i != null && i.width && (i != null && i.height))
|
|
897
929
|
return { width: i.width, height: i.height };
|
|
898
|
-
const
|
|
899
|
-
return
|
|
930
|
+
const c = i != null && i.imageUrl ? H.value[i.imageUrl] : void 0;
|
|
931
|
+
return c || (i != null && i.imageUrl && it(i.imageUrl), { width: 1, height: 1 });
|
|
900
932
|
}, Kt = (s) => {
|
|
901
933
|
const i = e.batchImages[s];
|
|
902
934
|
return i != null && i.width && (i != null && i.height) ? !0 : i != null && i.imageUrl ? !!H.value[i.imageUrl] : !1;
|
|
903
935
|
}, Zt = (s, i) => {
|
|
904
|
-
const
|
|
936
|
+
const c = i.coordinates, d = st(s), f = et(i), I = Math.min(c.x1, c.x2), P = Math.min(c.y1, c.y2), ne = Math.max(c.x1, c.x2), oe = Math.max(c.y1, c.y2);
|
|
905
937
|
return {
|
|
906
|
-
left: `${
|
|
938
|
+
left: `${I / d.width * 100}%`,
|
|
907
939
|
top: `${P / d.height * 100}%`,
|
|
908
|
-
width: `${(ne -
|
|
940
|
+
width: `${(ne - I) / d.width * 100}%`,
|
|
909
941
|
height: `${(oe - P) / d.height * 100}%`,
|
|
910
942
|
borderColor: f,
|
|
911
943
|
backgroundColor: `${f}22`
|
|
912
944
|
};
|
|
913
945
|
}, Qt = (s, i) => {
|
|
914
|
-
const
|
|
915
|
-
return kt(i).map((d) => `${d.x /
|
|
946
|
+
const c = st(s);
|
|
947
|
+
return kt(i).map((d) => `${d.x / c.width * 100},${d.y / c.height * 100}`).join(" ");
|
|
916
948
|
}, te = (s) => {
|
|
917
949
|
const i = et(s);
|
|
918
950
|
return {
|
|
@@ -920,29 +952,29 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
920
952
|
stroke: i,
|
|
921
953
|
strokeWidth: "1.4"
|
|
922
954
|
};
|
|
923
|
-
}, ee = (s, i,
|
|
924
|
-
const d = st(s), f = et(
|
|
955
|
+
}, ee = (s, i, c) => {
|
|
956
|
+
const d = st(s), f = et(c);
|
|
925
957
|
return {
|
|
926
958
|
left: `${i.x / d.width * 100}%`,
|
|
927
959
|
top: `${i.y / d.height * 100}%`,
|
|
928
960
|
backgroundColor: f
|
|
929
961
|
};
|
|
930
962
|
}, se = (s, i) => {
|
|
931
|
-
const
|
|
963
|
+
const c = i.coordinates, d = st(s), f = et(i), I = Math.abs(c.width), P = Math.abs(c.height);
|
|
932
964
|
return {
|
|
933
|
-
left: `${(
|
|
934
|
-
top: `${(
|
|
935
|
-
width: `${
|
|
965
|
+
left: `${(c.x - I / 2) / d.width * 100}%`,
|
|
966
|
+
top: `${(c.y - P / 2) / d.height * 100}%`,
|
|
967
|
+
width: `${I / d.width * 100}%`,
|
|
936
968
|
height: `${P / d.height * 100}%`,
|
|
937
|
-
transform: `rotate(${
|
|
969
|
+
transform: `rotate(${c.angle || 0}deg)`,
|
|
938
970
|
borderColor: f,
|
|
939
971
|
backgroundColor: `${f}22`
|
|
940
972
|
};
|
|
941
973
|
}, ie = (s, i) => {
|
|
942
|
-
const
|
|
974
|
+
const c = i.coordinates, d = st(s), f = et(i);
|
|
943
975
|
return {
|
|
944
|
-
left: `${
|
|
945
|
-
top: `${
|
|
976
|
+
left: `${c.x / d.width * 100}%`,
|
|
977
|
+
top: `${c.y / d.height * 100}%`,
|
|
946
978
|
backgroundColor: `${f}d9`
|
|
947
979
|
// ~85% opacity
|
|
948
980
|
};
|
|
@@ -950,13 +982,13 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
950
982
|
return t({
|
|
951
983
|
jumpTo: ot,
|
|
952
984
|
setImage: Ft,
|
|
953
|
-
setAnnotations:
|
|
985
|
+
setAnnotations: Wt,
|
|
954
986
|
getAnnotations: _t,
|
|
955
987
|
selectTool: Y,
|
|
956
988
|
loadPredictionCandidates: Ct,
|
|
957
|
-
applyPredictions:
|
|
958
|
-
rejectPredictions:
|
|
959
|
-
exportAnnotations:
|
|
989
|
+
applyPredictions: Ot,
|
|
990
|
+
rejectPredictions: Vt,
|
|
991
|
+
exportAnnotations: Nt,
|
|
960
992
|
getAllAnnotations: () => {
|
|
961
993
|
var s, i;
|
|
962
994
|
return e.batchImages.length > 0 ? e.batchImages : [{
|
|
@@ -965,10 +997,10 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
965
997
|
}];
|
|
966
998
|
},
|
|
967
999
|
getCurrentAnnotation: () => {
|
|
968
|
-
var s, i,
|
|
1000
|
+
var s, i, c;
|
|
969
1001
|
return {
|
|
970
1002
|
imageUrl: ((s = e.batchImages[w.value]) == null ? void 0 : s.imageUrl) || ((i = e.image) == null ? void 0 : i.url) || "",
|
|
971
|
-
annotations: ((
|
|
1003
|
+
annotations: ((c = r.value) == null ? void 0 : c.getAnnotations()) || []
|
|
972
1004
|
};
|
|
973
1005
|
}
|
|
974
1006
|
}), K(() => {
|
|
@@ -976,7 +1008,7 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
976
1008
|
return (s = e.image) == null ? void 0 : s.url;
|
|
977
1009
|
}, () => {
|
|
978
1010
|
var s;
|
|
979
|
-
e.batchImages.length === 0 && ((s = e.image) != null && s.url) &&
|
|
1011
|
+
e.batchImages.length === 0 && ((s = e.image) != null && s.url) && N();
|
|
980
1012
|
}), K(() => e.predictionCandidates, (s) => {
|
|
981
1013
|
s && Ct(s);
|
|
982
1014
|
}, { immediate: !0, deep: !0 }), K(
|
|
@@ -990,31 +1022,36 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
990
1022
|
() => {
|
|
991
1023
|
at(() => Q());
|
|
992
1024
|
}
|
|
1025
|
+
), K(
|
|
1026
|
+
() => e.readOnly,
|
|
1027
|
+
(s) => {
|
|
1028
|
+
r.value && r.value.setShowLabels(s);
|
|
1029
|
+
}
|
|
993
1030
|
), (s, i) => (v(), m("div", {
|
|
994
|
-
class:
|
|
1031
|
+
class: q(["annotation-container", y.theme])
|
|
995
1032
|
}, [
|
|
996
|
-
|
|
997
|
-
h("div",
|
|
1033
|
+
y.batchImages && y.batchImages.length > 0 ? (v(), m("div", Pe, [
|
|
1034
|
+
h("div", Le, "共 " + L(y.batchImages.length) + " 张", 1),
|
|
998
1035
|
h("div", {
|
|
999
1036
|
ref_key: "imageListScrollRef",
|
|
1000
1037
|
ref: g,
|
|
1001
1038
|
class: "image-list-scroll"
|
|
1002
1039
|
}, [
|
|
1003
|
-
(v(!0), m(
|
|
1004
|
-
key: `${
|
|
1040
|
+
(v(!0), m(W, null, J(y.batchImages, (c, d) => (v(), m("button", {
|
|
1041
|
+
key: `${c.imageUrl}-${d}`,
|
|
1005
1042
|
ref_for: !0,
|
|
1006
1043
|
ref: (f) => ht(f, d),
|
|
1007
|
-
class:
|
|
1044
|
+
class: q(["image-list-item", { active: d === w.value }]),
|
|
1008
1045
|
onClick: (f) => ot(d)
|
|
1009
1046
|
}, [
|
|
1010
|
-
h("div",
|
|
1047
|
+
h("div", $e, [
|
|
1011
1048
|
h("img", {
|
|
1012
|
-
src:
|
|
1049
|
+
src: c.imageUrl,
|
|
1013
1050
|
alt: `第${d + 1}张`,
|
|
1014
1051
|
class: "image-list-thumb"
|
|
1015
|
-
}, null, 8,
|
|
1016
|
-
Kt(d) ? (v(), m("div",
|
|
1017
|
-
(v(!0), m(
|
|
1052
|
+
}, null, 8, Re),
|
|
1053
|
+
Kt(d) ? (v(), m("div", Be, [
|
|
1054
|
+
(v(!0), m(W, null, J(Gt(d), (f) => (v(), m(W, {
|
|
1018
1055
|
key: f.id
|
|
1019
1056
|
}, [
|
|
1020
1057
|
Yt(f) ? (v(), m("div", {
|
|
@@ -1026,10 +1063,10 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1026
1063
|
points: Qt(d, f),
|
|
1027
1064
|
style: U(te(f))
|
|
1028
1065
|
}, null, 12, Ee)
|
|
1029
|
-
])) : jt(f) ? (v(!0), m(
|
|
1066
|
+
])) : jt(f) ? (v(!0), m(W, { key: 2 }, J(kt(f), (I, P) => (v(), m("div", {
|
|
1030
1067
|
key: `${f.id}-${P}`,
|
|
1031
1068
|
class: "thumb-overlay-point",
|
|
1032
|
-
style: U(ee(d,
|
|
1069
|
+
style: U(ee(d, I, f))
|
|
1033
1070
|
}, null, 4))), 128)) : Xt(f) ? (v(), m("div", {
|
|
1034
1071
|
key: 3,
|
|
1035
1072
|
class: "thumb-overlay-rotated",
|
|
@@ -1038,39 +1075,39 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1038
1075
|
key: 4,
|
|
1039
1076
|
class: "thumb-overlay-category",
|
|
1040
1077
|
style: U(ie(d, f))
|
|
1041
|
-
},
|
|
1078
|
+
}, L(f.label), 5)) : R("", !0)
|
|
1042
1079
|
], 64))), 128))
|
|
1043
|
-
])) :
|
|
1080
|
+
])) : R("", !0)
|
|
1044
1081
|
]),
|
|
1045
|
-
h("span", Ue, "第 " +
|
|
1046
|
-
], 10,
|
|
1082
|
+
h("span", Ue, "第 " + L(d + 1) + " 张", 1)
|
|
1083
|
+
], 10, ze))), 128))
|
|
1047
1084
|
], 512)
|
|
1048
|
-
])) :
|
|
1049
|
-
h("div",
|
|
1050
|
-
|
|
1085
|
+
])) : R("", !0),
|
|
1086
|
+
h("div", Oe, [
|
|
1087
|
+
y.readOnly ? R("", !0) : (v(), m("div", Ve, [
|
|
1051
1088
|
h("div", {
|
|
1052
|
-
class:
|
|
1053
|
-
onClick: i[0] || (i[0] = (
|
|
1089
|
+
class: q(["tool-btn", { active: A.value === "pan" }]),
|
|
1090
|
+
onClick: i[0] || (i[0] = (c) => Y("pan")),
|
|
1054
1091
|
title: "拖动"
|
|
1055
1092
|
}, [
|
|
1056
|
-
|
|
1093
|
+
B($, { name: "rank" })
|
|
1057
1094
|
], 2),
|
|
1058
1095
|
h("div", {
|
|
1059
|
-
class:
|
|
1060
|
-
onClick: i[1] || (i[1] = (
|
|
1096
|
+
class: q(["tool-btn", { active: A.value === "select" }]),
|
|
1097
|
+
onClick: i[1] || (i[1] = (c) => Y("select")),
|
|
1061
1098
|
title: "选择"
|
|
1062
1099
|
}, [
|
|
1063
|
-
|
|
1100
|
+
B($, { name: "pointer" })
|
|
1064
1101
|
], 2),
|
|
1065
1102
|
i[5] || (i[5] = h("div", { class: "divider" }, null, -1)),
|
|
1066
|
-
(v(!0), m(
|
|
1067
|
-
key:
|
|
1068
|
-
class:
|
|
1069
|
-
onClick: (d) => Y(
|
|
1070
|
-
title: F(
|
|
1103
|
+
(v(!0), m(W, null, J(b.value, (c) => (v(), m("div", {
|
|
1104
|
+
key: c,
|
|
1105
|
+
class: q(["tool-btn", { active: A.value === c }]),
|
|
1106
|
+
onClick: (d) => Y(c),
|
|
1107
|
+
title: F(c)
|
|
1071
1108
|
}, [
|
|
1072
|
-
|
|
1073
|
-
name:
|
|
1109
|
+
B($, {
|
|
1110
|
+
name: k(c)
|
|
1074
1111
|
}, null, 8, ["name"])
|
|
1075
1112
|
], 10, Fe))), 128)),
|
|
1076
1113
|
i[6] || (i[6] = h("div", { class: "divider" }, null, -1)),
|
|
@@ -1079,31 +1116,31 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1079
1116
|
onClick: Mt,
|
|
1080
1117
|
title: "放大"
|
|
1081
1118
|
}, [
|
|
1082
|
-
|
|
1119
|
+
B($, { name: "zoom-in" })
|
|
1083
1120
|
]),
|
|
1084
1121
|
h("div", {
|
|
1085
1122
|
class: "tool-btn",
|
|
1086
1123
|
onClick: Tt,
|
|
1087
1124
|
title: "缩小"
|
|
1088
1125
|
}, [
|
|
1089
|
-
|
|
1126
|
+
B($, { name: "zoom-out" })
|
|
1090
1127
|
]),
|
|
1091
|
-
|
|
1092
|
-
|
|
1128
|
+
V.value ? (v(), m("div", We)) : R("", !0),
|
|
1129
|
+
V.value ? (v(), m("div", {
|
|
1093
1130
|
key: 1,
|
|
1094
1131
|
class: "tool-btn",
|
|
1095
1132
|
onClick: St,
|
|
1096
1133
|
title: "删除选中"
|
|
1097
1134
|
}, [
|
|
1098
|
-
|
|
1099
|
-
])) :
|
|
1135
|
+
B($, { name: "delete" })
|
|
1136
|
+
])) : R("", !0)
|
|
1100
1137
|
]))
|
|
1101
1138
|
]),
|
|
1102
|
-
h("div",
|
|
1139
|
+
h("div", Ne, [
|
|
1103
1140
|
h("div", {
|
|
1104
1141
|
class: "canvas-wrapper",
|
|
1105
1142
|
ref_key: "canvasWrapper",
|
|
1106
|
-
ref:
|
|
1143
|
+
ref: a,
|
|
1107
1144
|
onWheel: i[2] || (i[2] = It(() => {
|
|
1108
1145
|
}, ["prevent"]))
|
|
1109
1146
|
}, [
|
|
@@ -1111,7 +1148,7 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1111
1148
|
ref_key: "canvasRef",
|
|
1112
1149
|
ref: o
|
|
1113
1150
|
}, null, 512),
|
|
1114
|
-
|
|
1151
|
+
y.readOnly ? R("", !0) : (v(), m("div", Ge, [
|
|
1115
1152
|
h("div", {
|
|
1116
1153
|
class: "selector-trigger",
|
|
1117
1154
|
onClick: xt
|
|
@@ -1121,72 +1158,72 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1121
1158
|
class: "color-dot",
|
|
1122
1159
|
style: U({ backgroundColor: Z.value.color })
|
|
1123
1160
|
}, null, 4),
|
|
1124
|
-
h("span", Je,
|
|
1161
|
+
h("span", Je, L(Z.value.name), 1)
|
|
1125
1162
|
])) : (v(), m("div", je, [...i[7] || (i[7] = [
|
|
1126
1163
|
h("span", { class: "label-name" }, "请选择标签", -1)
|
|
1127
1164
|
])])),
|
|
1128
|
-
|
|
1165
|
+
B($, {
|
|
1129
1166
|
name: "right",
|
|
1130
|
-
class:
|
|
1167
|
+
class: q(["arrow-icon", { "is-open": G.value }])
|
|
1131
1168
|
}, null, 8, ["class"])
|
|
1132
1169
|
]),
|
|
1133
1170
|
G.value ? (v(), m("div", Xe, [
|
|
1134
|
-
_.value.length === 0 ? (v(), m("div", qe, "请在右侧创建标签")) : (v(!0), m(
|
|
1135
|
-
key:
|
|
1136
|
-
class:
|
|
1137
|
-
onClick: (d) => wt(
|
|
1171
|
+
_.value.length === 0 ? (v(), m("div", qe, "请在右侧创建标签")) : (v(!0), m(W, { key: 1 }, J(_.value, (c) => (v(), m("div", {
|
|
1172
|
+
key: c.id,
|
|
1173
|
+
class: q(["dropdown-item", { active: z.value === c.id }]),
|
|
1174
|
+
onClick: (d) => wt(c)
|
|
1138
1175
|
}, [
|
|
1139
1176
|
h("span", {
|
|
1140
1177
|
class: "color-dot",
|
|
1141
|
-
style: U({ backgroundColor:
|
|
1178
|
+
style: U({ backgroundColor: c.color })
|
|
1142
1179
|
}, null, 4),
|
|
1143
|
-
h("span", Ze,
|
|
1144
|
-
|
|
1180
|
+
h("span", Ze, L(c.name), 1),
|
|
1181
|
+
z.value === c.id ? (v(), vt($, {
|
|
1145
1182
|
key: 0,
|
|
1146
1183
|
name: "aim",
|
|
1147
1184
|
class: "check-icon"
|
|
1148
|
-
})) :
|
|
1185
|
+
})) : R("", !0)
|
|
1149
1186
|
], 10, Ke))), 128))
|
|
1150
|
-
])) :
|
|
1187
|
+
])) : R("", !0)
|
|
1151
1188
|
]))
|
|
1152
1189
|
], 544),
|
|
1153
|
-
|
|
1190
|
+
y.batchImages && y.batchImages.length > 0 ? (v(), m("div", Qe, [
|
|
1154
1191
|
h("button", {
|
|
1155
1192
|
class: "icon-btn",
|
|
1156
1193
|
onClick: Et,
|
|
1157
1194
|
disabled: w.value <= 0,
|
|
1158
1195
|
title: "第一张"
|
|
1159
1196
|
}, [
|
|
1160
|
-
|
|
1197
|
+
B($, { name: "first" })
|
|
1161
1198
|
], 8, ts),
|
|
1162
1199
|
h("button", {
|
|
1163
1200
|
class: "icon-btn",
|
|
1164
|
-
onClick:
|
|
1201
|
+
onClick: Bt,
|
|
1165
1202
|
disabled: w.value <= 0,
|
|
1166
1203
|
title: "上一张"
|
|
1167
1204
|
}, [
|
|
1168
|
-
|
|
1205
|
+
B($, { name: "back" })
|
|
1169
1206
|
], 8, es),
|
|
1170
|
-
h("span", null,
|
|
1207
|
+
h("span", null, L(w.value + 1) + " / " + L(y.batchImages.length), 1),
|
|
1171
1208
|
h("button", {
|
|
1172
1209
|
class: "icon-btn",
|
|
1173
1210
|
onClick: Ht,
|
|
1174
|
-
disabled: w.value >=
|
|
1211
|
+
disabled: w.value >= y.batchImages.length - 1,
|
|
1175
1212
|
title: "下一张"
|
|
1176
1213
|
}, [
|
|
1177
|
-
|
|
1214
|
+
B($, { name: "right" })
|
|
1178
1215
|
], 8, ss),
|
|
1179
1216
|
h("button", {
|
|
1180
1217
|
class: "icon-btn",
|
|
1181
1218
|
onClick: Ut,
|
|
1182
|
-
disabled: w.value >=
|
|
1219
|
+
disabled: w.value >= y.batchImages.length - 1,
|
|
1183
1220
|
title: "最后一张"
|
|
1184
1221
|
}, [
|
|
1185
|
-
|
|
1222
|
+
B($, { name: "last" })
|
|
1186
1223
|
], 8, is)
|
|
1187
|
-
])) :
|
|
1224
|
+
])) : R("", !0)
|
|
1188
1225
|
]),
|
|
1189
|
-
|
|
1226
|
+
y.readOnly ? R("", !0) : (v(), m("div", ns, [
|
|
1190
1227
|
h("div", { class: "sidebar-header" }, [
|
|
1191
1228
|
i[8] || (i[8] = h("h3", null, "标签", -1)),
|
|
1192
1229
|
h("button", {
|
|
@@ -1195,37 +1232,37 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1195
1232
|
}, "添加标签")
|
|
1196
1233
|
]),
|
|
1197
1234
|
h("div", os, [
|
|
1198
|
-
(v(!0), m(
|
|
1199
|
-
key:
|
|
1235
|
+
(v(!0), m(W, null, J(_.value, (c) => (v(), m("div", {
|
|
1236
|
+
key: c.id,
|
|
1200
1237
|
class: "label-item",
|
|
1201
|
-
style: U({ backgroundColor:
|
|
1238
|
+
style: U({ backgroundColor: c.color + "1A", color: c.color })
|
|
1202
1239
|
}, [
|
|
1203
1240
|
h("div", as, [
|
|
1204
1241
|
h("label", {
|
|
1205
1242
|
class: "color-wrapper",
|
|
1206
|
-
style: U({ backgroundColor:
|
|
1243
|
+
style: U({ backgroundColor: c.color })
|
|
1207
1244
|
}, [
|
|
1208
1245
|
ft(h("input", {
|
|
1209
1246
|
type: "color",
|
|
1210
|
-
"onUpdate:modelValue": (d) =>
|
|
1211
|
-
onChange: (d) =>
|
|
1247
|
+
"onUpdate:modelValue": (d) => c.color = d,
|
|
1248
|
+
onChange: (d) => zt(c),
|
|
1212
1249
|
style: { visibility: "hidden", width: "0", height: "0" }
|
|
1213
1250
|
}, null, 40, ls), [
|
|
1214
|
-
[mt,
|
|
1251
|
+
[mt, c.color]
|
|
1215
1252
|
])
|
|
1216
1253
|
], 4),
|
|
1217
1254
|
h("span", {
|
|
1218
1255
|
class: "label-name",
|
|
1219
|
-
title:
|
|
1220
|
-
},
|
|
1256
|
+
title: c.name
|
|
1257
|
+
}, L(c.name), 9, cs),
|
|
1221
1258
|
h("span", {
|
|
1222
1259
|
class: "action-icon eye",
|
|
1223
|
-
onClick: (d) =>
|
|
1260
|
+
onClick: (d) => $t(c)
|
|
1224
1261
|
}, [
|
|
1225
|
-
|
|
1262
|
+
c.visible ? (v(), vt($, {
|
|
1226
1263
|
key: 0,
|
|
1227
1264
|
name: "view"
|
|
1228
|
-
})) : (v(), vt(
|
|
1265
|
+
})) : (v(), vt($, {
|
|
1229
1266
|
key: 1,
|
|
1230
1267
|
name: "hide"
|
|
1231
1268
|
}))
|
|
@@ -1234,17 +1271,17 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1234
1271
|
i[9] || (i[9] = h("span", { class: "dots" }, "•••", -1)),
|
|
1235
1272
|
h("span", {
|
|
1236
1273
|
class: "delete-btn",
|
|
1237
|
-
onClick: (d) =>
|
|
1274
|
+
onClick: (d) => Rt(c.id),
|
|
1238
1275
|
title: "删除"
|
|
1239
1276
|
}, [
|
|
1240
|
-
|
|
1277
|
+
B($, { name: "delete" })
|
|
1241
1278
|
], 8, ds)
|
|
1242
1279
|
])
|
|
1243
1280
|
])
|
|
1244
1281
|
], 4))), 128))
|
|
1245
1282
|
])
|
|
1246
1283
|
])),
|
|
1247
|
-
|
|
1284
|
+
X.value ? (v(), m("div", {
|
|
1248
1285
|
key: 2,
|
|
1249
1286
|
class: "modal-overlay",
|
|
1250
1287
|
onClick: It(dt, ["self"])
|
|
@@ -1260,7 +1297,7 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1260
1297
|
h("span", { class: "required" }, "*")
|
|
1261
1298
|
], -1)),
|
|
1262
1299
|
ft(h("input", {
|
|
1263
|
-
"onUpdate:modelValue": i[3] || (i[3] = (
|
|
1300
|
+
"onUpdate:modelValue": i[3] || (i[3] = (c) => C.value.name = c),
|
|
1264
1301
|
placeholder: "请输入标签名称",
|
|
1265
1302
|
class: "modal-input",
|
|
1266
1303
|
autofocus: ""
|
|
@@ -1277,13 +1314,13 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1277
1314
|
}, [
|
|
1278
1315
|
ft(h("input", {
|
|
1279
1316
|
type: "color",
|
|
1280
|
-
"onUpdate:modelValue": i[4] || (i[4] = (
|
|
1317
|
+
"onUpdate:modelValue": i[4] || (i[4] = (c) => C.value.color = c),
|
|
1281
1318
|
class: "modal-color-picker"
|
|
1282
1319
|
}, null, 512), [
|
|
1283
1320
|
[mt, C.value.color]
|
|
1284
1321
|
])
|
|
1285
1322
|
], 4),
|
|
1286
|
-
h("span", ps,
|
|
1323
|
+
h("span", ps, L(C.value.color), 1)
|
|
1287
1324
|
])
|
|
1288
1325
|
])
|
|
1289
1326
|
]),
|
|
@@ -1299,16 +1336,16 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1299
1336
|
}, "确认", 8, xs)
|
|
1300
1337
|
])
|
|
1301
1338
|
])
|
|
1302
|
-
])) :
|
|
1339
|
+
])) : R("", !0)
|
|
1303
1340
|
], 2));
|
|
1304
1341
|
}
|
|
1305
|
-
}), bs = /* @__PURE__ */ rt(ws, [["__scopeId", "data-v-
|
|
1342
|
+
}), bs = /* @__PURE__ */ rt(ws, [["__scopeId", "data-v-08cbbaca"]]), Cs = {
|
|
1306
1343
|
class: "thumbnail-wrapper",
|
|
1307
1344
|
ref: "wrapper"
|
|
1308
|
-
}, _s = ["src", "alt"], ks = ["viewBox", "preserveAspectRatio"], Is = ["x", "y", "width", "height", "stroke", "stroke-width"], As = ["points", "stroke", "stroke-width"], Ss = ["transform"], Ms = ["x", "y", "width", "height", "stroke", "stroke-width"], Ts = { key: 3 }, Ds = ["cx", "cy", "r", "fill", "stroke-width"], Ps =
|
|
1345
|
+
}, _s = ["src", "alt"], ks = ["viewBox", "preserveAspectRatio"], Is = ["x", "y", "width", "height", "stroke", "stroke-width"], As = ["points", "stroke", "stroke-width"], Ss = ["transform"], Ms = ["x", "y", "width", "height", "stroke", "stroke-width"], Ts = { key: 3 }, Ds = ["cx", "cy", "r", "fill", "stroke-width"], Ps = { key: 4 }, Ls = ["x", "y", "height"], zs = {
|
|
1309
1346
|
key: 1,
|
|
1310
1347
|
class: "loading-placeholder"
|
|
1311
|
-
},
|
|
1348
|
+
}, $s = /* @__PURE__ */ ct({
|
|
1312
1349
|
__name: "AnnotationThumbnail",
|
|
1313
1350
|
props: {
|
|
1314
1351
|
src: {},
|
|
@@ -1319,21 +1356,21 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1319
1356
|
strokeWidth: {},
|
|
1320
1357
|
fontSize: {}
|
|
1321
1358
|
},
|
|
1322
|
-
setup(
|
|
1323
|
-
const t =
|
|
1324
|
-
n.value && (
|
|
1325
|
-
}, g =
|
|
1359
|
+
setup(y) {
|
|
1360
|
+
const t = y, n = M(null), e = M(!1), l = M(0), o = M(0), a = () => {
|
|
1361
|
+
n.value && (l.value = n.value.naturalWidth, o.value = n.value.naturalHeight, e.value = !0);
|
|
1362
|
+
}, g = O(() => t.fit === "contain" ? "xMidYMid meet" : "xMidYMid slice"), u = O(() => t.strokeWidth ?? 10), r = O(() => t.fontSize ?? 30), A = (C) => {
|
|
1326
1363
|
var S;
|
|
1327
1364
|
if ((S = C.style) != null && S.strokeColor) return C.style.strokeColor;
|
|
1328
1365
|
if (t.labels) {
|
|
1329
|
-
const
|
|
1330
|
-
if (
|
|
1366
|
+
const x = t.labels.find((H) => H.name === C.label);
|
|
1367
|
+
if (x) return x.color;
|
|
1331
1368
|
}
|
|
1332
1369
|
return "#FF0000";
|
|
1333
1370
|
}, w = (C) => {
|
|
1334
|
-
const S = C.coordinates,
|
|
1335
|
-
return { x
|
|
1336
|
-
}, D = (C) => C.coordinates.points.map((
|
|
1371
|
+
const S = C.coordinates, x = Math.min(S.x1, S.x2), H = Math.min(S.y1, S.y2), V = Math.abs(S.x1 - S.x2), G = Math.abs(S.y1 - S.y2);
|
|
1372
|
+
return { x, y: H, width: V, height: G };
|
|
1373
|
+
}, D = (C) => C.coordinates.points.map((x) => `${x.x},${x.y}`).join(" "), _ = (C) => {
|
|
1337
1374
|
if (C.type === "rectangle") {
|
|
1338
1375
|
const S = w(C);
|
|
1339
1376
|
return { x: S.x, y: S.y - 5 };
|
|
@@ -1350,97 +1387,101 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1350
1387
|
return { x: C.coordinates.x, y: C.coordinates.y };
|
|
1351
1388
|
}
|
|
1352
1389
|
return { x: 0, y: 0 };
|
|
1353
|
-
},
|
|
1354
|
-
const { x: S, y:
|
|
1355
|
-
return `translate(${S}, ${
|
|
1356
|
-
},
|
|
1390
|
+
}, z = (C) => {
|
|
1391
|
+
const { x: S, y: x, angle: H } = C.coordinates, V = H * 180 / Math.PI;
|
|
1392
|
+
return `translate(${S}, ${x}) rotate(${V})`;
|
|
1393
|
+
}, X = (C) => ({ x: C.coordinates.x, y: C.coordinates.y });
|
|
1357
1394
|
return (C, S) => (v(), m("div", Cs, [
|
|
1358
1395
|
h("img", {
|
|
1359
1396
|
ref_key: "img",
|
|
1360
1397
|
ref: n,
|
|
1361
|
-
src:
|
|
1398
|
+
src: y.src,
|
|
1362
1399
|
class: "thumbnail-image",
|
|
1363
|
-
style: U({ objectFit:
|
|
1364
|
-
onLoad:
|
|
1365
|
-
alt:
|
|
1400
|
+
style: U({ objectFit: y.fit }),
|
|
1401
|
+
onLoad: a,
|
|
1402
|
+
alt: y.alt
|
|
1366
1403
|
}, null, 44, _s),
|
|
1367
1404
|
e.value ? (v(), m("svg", {
|
|
1368
1405
|
key: 0,
|
|
1369
1406
|
class: "annotation-overlay",
|
|
1370
|
-
viewBox: `0 0 ${
|
|
1407
|
+
viewBox: `0 0 ${l.value} ${o.value}`,
|
|
1371
1408
|
preserveAspectRatio: g.value
|
|
1372
1409
|
}, [
|
|
1373
|
-
(v(!0), m(
|
|
1374
|
-
key:
|
|
1410
|
+
(v(!0), m(W, null, J(y.annotations, (x) => (v(), m(W, {
|
|
1411
|
+
key: x.id
|
|
1375
1412
|
}, [
|
|
1376
|
-
|
|
1413
|
+
x.type === "rectangle" ? (v(), m("rect", {
|
|
1377
1414
|
key: 0,
|
|
1378
|
-
x: w(
|
|
1379
|
-
y: w(
|
|
1380
|
-
width: w(
|
|
1381
|
-
height: w(
|
|
1382
|
-
stroke:
|
|
1415
|
+
x: w(x).x,
|
|
1416
|
+
y: w(x).y,
|
|
1417
|
+
width: w(x).width,
|
|
1418
|
+
height: w(x).height,
|
|
1419
|
+
stroke: A(x),
|
|
1383
1420
|
"stroke-width": u.value,
|
|
1384
1421
|
fill: "transparent"
|
|
1385
|
-
}, null, 8, Is)) :
|
|
1422
|
+
}, null, 8, Is)) : x.type === "polygon" ? (v(), m("polygon", {
|
|
1386
1423
|
key: 1,
|
|
1387
|
-
points: D(
|
|
1388
|
-
stroke:
|
|
1424
|
+
points: D(x),
|
|
1425
|
+
stroke: A(x),
|
|
1389
1426
|
"stroke-width": u.value,
|
|
1390
1427
|
fill: "transparent"
|
|
1391
|
-
}, null, 8, As)) :
|
|
1428
|
+
}, null, 8, As)) : x.type === "rotatedRect" ? (v(), m("g", {
|
|
1392
1429
|
key: 2,
|
|
1393
|
-
transform:
|
|
1430
|
+
transform: z(x)
|
|
1394
1431
|
}, [
|
|
1395
1432
|
h("rect", {
|
|
1396
|
-
x: -
|
|
1397
|
-
y: -
|
|
1398
|
-
width:
|
|
1399
|
-
height:
|
|
1400
|
-
stroke:
|
|
1433
|
+
x: -x.coordinates.width / 2,
|
|
1434
|
+
y: -x.coordinates.height / 2,
|
|
1435
|
+
width: x.coordinates.width,
|
|
1436
|
+
height: x.coordinates.height,
|
|
1437
|
+
stroke: A(x),
|
|
1401
1438
|
"stroke-width": u.value,
|
|
1402
1439
|
fill: "transparent"
|
|
1403
1440
|
}, null, 8, Ms)
|
|
1404
|
-
], 8, Ss)) :
|
|
1405
|
-
(v(!0), m(
|
|
1406
|
-
key:
|
|
1441
|
+
], 8, Ss)) : x.type === "point" ? (v(), m("g", Ts, [
|
|
1442
|
+
(v(!0), m(W, null, J(x.coordinates.points, (H, V) => (v(), m("circle", {
|
|
1443
|
+
key: V,
|
|
1407
1444
|
cx: H.x,
|
|
1408
1445
|
cy: H.y,
|
|
1409
1446
|
r: u.value * 1.5,
|
|
1410
|
-
fill:
|
|
1447
|
+
fill: A(x),
|
|
1411
1448
|
stroke: "white",
|
|
1412
1449
|
"stroke-width": u.value * 0.5
|
|
1413
1450
|
}, null, 8, Ds))), 128))
|
|
1414
|
-
])) :
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1451
|
+
])) : R("", !0),
|
|
1452
|
+
x.label ? (v(), m("g", Ps, [
|
|
1453
|
+
(v(), m("foreignObject", {
|
|
1454
|
+
x: x.type === "category" ? X(x).x - 100 : _(x).x,
|
|
1455
|
+
y: x.type === "category" ? X(x).y - r.value - 8 : _(x).y - r.value - 8,
|
|
1456
|
+
width: "200",
|
|
1457
|
+
height: r.value + 16,
|
|
1458
|
+
style: { overflow: "visible" }
|
|
1459
|
+
}, [
|
|
1460
|
+
h("div", {
|
|
1461
|
+
style: U({
|
|
1462
|
+
display: "inline-flex",
|
|
1463
|
+
alignItems: "center",
|
|
1464
|
+
justifyContent: x.type === "category" ? "center" : "flex-start",
|
|
1465
|
+
backgroundColor: `${A(x)}cc`,
|
|
1466
|
+
color: "#ffffff",
|
|
1467
|
+
fontSize: `${r.value}px`,
|
|
1468
|
+
padding: "4px 8px",
|
|
1469
|
+
borderRadius: "4px",
|
|
1470
|
+
whiteSpace: "nowrap",
|
|
1471
|
+
lineHeight: 1,
|
|
1472
|
+
transform: x.type === "category" ? "translateX(calc(100px - 50%))" : "none"
|
|
1473
|
+
})
|
|
1474
|
+
}, L(x.label), 5)
|
|
1475
|
+
], 8, Ls))
|
|
1476
|
+
])) : R("", !0)
|
|
1436
1477
|
], 64))), 128))
|
|
1437
|
-
], 8, ks)) : (v(), m("div",
|
|
1478
|
+
], 8, ks)) : (v(), m("div", zs, "Loading..."))
|
|
1438
1479
|
], 512));
|
|
1439
1480
|
}
|
|
1440
|
-
}),
|
|
1481
|
+
}), Rs = /* @__PURE__ */ rt($s, [["__scopeId", "data-v-46e27181"]]), Bs = {
|
|
1441
1482
|
key: 0,
|
|
1442
1483
|
class: "gallery-view"
|
|
1443
|
-
}, Hs = { class: "gallery-layout" }, Es = { class: "gallery-sidebar" }, Us = { class: "label-stats-table" },
|
|
1484
|
+
}, Hs = { class: "gallery-layout" }, Es = { class: "gallery-sidebar" }, Us = { class: "label-stats-table" }, Os = { class: "label-cover-wrapper" }, Vs = ["src"], Fs = { class: "gallery-content" }, Ws = ["onClick"], Ns = { class: "thumbnail-wrapper" }, Gs = { class: "img-meta" }, Ys = { class: "img-index" }, Js = { class: "anno-count" }, js = {
|
|
1444
1485
|
key: 0,
|
|
1445
1486
|
class: "bottom-bar"
|
|
1446
1487
|
}, Xs = {
|
|
@@ -1454,113 +1495,114 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1454
1495
|
actionBar: {},
|
|
1455
1496
|
clickToEnterEditor: { type: Boolean },
|
|
1456
1497
|
thumbStrokeWidth: {},
|
|
1457
|
-
thumbFontSize: {}
|
|
1498
|
+
thumbFontSize: {},
|
|
1499
|
+
readOnly: { type: Boolean }
|
|
1458
1500
|
},
|
|
1459
1501
|
emits: ["export", "update:images", "imageClick", "update:labels", "pageChange"],
|
|
1460
|
-
setup(
|
|
1461
|
-
const e =
|
|
1462
|
-
var
|
|
1463
|
-
return ((b = (
|
|
1464
|
-
}), _ =
|
|
1465
|
-
var
|
|
1466
|
-
return ((b = (
|
|
1467
|
-
}),
|
|
1468
|
-
var
|
|
1469
|
-
return ((b = (
|
|
1470
|
-
}), C =
|
|
1471
|
-
var
|
|
1472
|
-
return ((b = (
|
|
1473
|
-
}), S =
|
|
1474
|
-
const
|
|
1475
|
-
g.value.forEach((
|
|
1476
|
-
|
|
1502
|
+
setup(y, { expose: t, emit: n }) {
|
|
1503
|
+
const e = y, l = n, o = M("gallery"), a = M([]), g = M([]), u = M(0), r = M(null), A = M(null), w = M(null), D = O(() => {
|
|
1504
|
+
var p, b;
|
|
1505
|
+
return ((b = (p = e.actionBar) == null ? void 0 : p.annotateButton) == null ? void 0 : b.show) === !0;
|
|
1506
|
+
}), _ = O(() => {
|
|
1507
|
+
var p, b;
|
|
1508
|
+
return ((b = (p = e.actionBar) == null ? void 0 : p.exportButton) == null ? void 0 : b.show) === !0;
|
|
1509
|
+
}), z = O(() => D.value || _.value), X = O(() => {
|
|
1510
|
+
var p, b;
|
|
1511
|
+
return ((b = (p = e.actionBar) == null ? void 0 : p.annotateButton) == null ? void 0 : b.text) || "手动标注";
|
|
1512
|
+
}), C = O(() => {
|
|
1513
|
+
var p, b;
|
|
1514
|
+
return ((b = (p = e.actionBar) == null ? void 0 : p.exportButton) == null ? void 0 : b.text) || "导出";
|
|
1515
|
+
}), S = O(() => e.clickToEnterEditor !== !1), x = O(() => {
|
|
1516
|
+
const p = {};
|
|
1517
|
+
g.value.forEach((k) => {
|
|
1518
|
+
p[k.name] = { count: 0, cover: "" };
|
|
1477
1519
|
});
|
|
1478
1520
|
let b = 0;
|
|
1479
|
-
return
|
|
1480
|
-
|
|
1481
|
-
var
|
|
1482
|
-
const E = F.label || (F.labelId ? (
|
|
1483
|
-
E &&
|
|
1521
|
+
return a.value.forEach((k) => {
|
|
1522
|
+
k.annotations && k.annotations.forEach((F) => {
|
|
1523
|
+
var N;
|
|
1524
|
+
const E = F.label || (F.labelId ? (N = g.value.find((Y) => Y.id === F.labelId)) == null ? void 0 : N.name : null);
|
|
1525
|
+
E && p[E] && (p[E].count++, b++, p[E].cover || (p[E].cover = k.imageUrl));
|
|
1484
1526
|
});
|
|
1485
|
-
}), g.value.map((
|
|
1486
|
-
var
|
|
1487
|
-
const F = ((
|
|
1527
|
+
}), g.value.map((k) => {
|
|
1528
|
+
var N, Y;
|
|
1529
|
+
const F = ((N = p[k.name]) == null ? void 0 : N.count) || 0, E = b === 0 ? "0.00%" : (F / b * 100).toFixed(2) + "%";
|
|
1488
1530
|
return {
|
|
1489
|
-
id:
|
|
1490
|
-
name:
|
|
1491
|
-
color:
|
|
1531
|
+
id: k.id,
|
|
1532
|
+
name: k.name,
|
|
1533
|
+
color: k.color,
|
|
1492
1534
|
count: F,
|
|
1493
1535
|
percentage: E,
|
|
1494
|
-
cover: ((Y =
|
|
1536
|
+
cover: ((Y = p[k.name]) == null ? void 0 : Y.cover) || ""
|
|
1495
1537
|
};
|
|
1496
1538
|
});
|
|
1497
|
-
}), H = (
|
|
1498
|
-
color:
|
|
1499
|
-
backgroundColor:
|
|
1539
|
+
}), H = (p) => ({
|
|
1540
|
+
color: p.color,
|
|
1541
|
+
backgroundColor: p.color + "1A"
|
|
1500
1542
|
// 1A represents ~10% opacity in hex
|
|
1501
1543
|
});
|
|
1502
1544
|
yt(() => {
|
|
1503
|
-
|
|
1504
|
-
}), K(() => e.images, (
|
|
1505
|
-
|
|
1506
|
-
}, { immediate: !0, deep: !0 }), K(() => e.labels, (
|
|
1507
|
-
g.value = JSON.parse(JSON.stringify(
|
|
1545
|
+
l("pageChange", { nowPage: "listPage" });
|
|
1546
|
+
}), K(() => e.images, (p) => {
|
|
1547
|
+
a.value = JSON.parse(JSON.stringify(p));
|
|
1548
|
+
}, { immediate: !0, deep: !0 }), K(() => e.labels, (p) => {
|
|
1549
|
+
g.value = JSON.parse(JSON.stringify(p || []));
|
|
1508
1550
|
}, { immediate: !0, deep: !0 });
|
|
1509
|
-
const
|
|
1510
|
-
u.value =
|
|
1511
|
-
|
|
1512
|
-
var b,
|
|
1513
|
-
(
|
|
1551
|
+
const V = (p) => {
|
|
1552
|
+
u.value = p, o.value = "editor", l("pageChange", { nowPage: "editPage" }), w.value && (w.value.scrollTop = 0), at(() => {
|
|
1553
|
+
A.value && (A.value.scrollTop = 0), window.scrollTo(0, 0), requestAnimationFrame(() => {
|
|
1554
|
+
var b, k;
|
|
1555
|
+
(k = (b = r.value) == null ? void 0 : b.jumpTo) == null || k.call(b, p);
|
|
1514
1556
|
});
|
|
1515
1557
|
});
|
|
1516
|
-
}, G = (
|
|
1558
|
+
}, G = (p, b) => {
|
|
1517
1559
|
if (S.value) {
|
|
1518
|
-
|
|
1560
|
+
V(p);
|
|
1519
1561
|
return;
|
|
1520
1562
|
}
|
|
1521
|
-
|
|
1522
|
-
}, Z = (
|
|
1563
|
+
l("imageClick", { index: p, imageId: b.id, image: b });
|
|
1564
|
+
}, Z = (p) => a.value.findIndex((b) => b.id === p);
|
|
1523
1565
|
t({
|
|
1524
|
-
openImageById: (
|
|
1525
|
-
const b = Z(
|
|
1526
|
-
return b < 0 ? !1 : (
|
|
1566
|
+
openImageById: (p) => {
|
|
1567
|
+
const b = Z(p);
|
|
1568
|
+
return b < 0 ? !1 : (V(b), !0);
|
|
1527
1569
|
},
|
|
1528
|
-
triggerImageClickById: (
|
|
1529
|
-
const b = Z(
|
|
1570
|
+
triggerImageClickById: (p) => {
|
|
1571
|
+
const b = Z(p);
|
|
1530
1572
|
if (b < 0)
|
|
1531
1573
|
return !1;
|
|
1532
|
-
const
|
|
1533
|
-
return
|
|
1574
|
+
const k = a.value[b];
|
|
1575
|
+
return k ? (l("imageClick", { index: b, imageId: k.id, image: k }), !0) : !1;
|
|
1534
1576
|
},
|
|
1535
1577
|
getFinalData: () => ({
|
|
1536
|
-
images: JSON.parse(JSON.stringify(
|
|
1578
|
+
images: JSON.parse(JSON.stringify(a.value)),
|
|
1537
1579
|
labels: JSON.parse(JSON.stringify(g.value))
|
|
1538
1580
|
})
|
|
1539
1581
|
});
|
|
1540
1582
|
const it = () => {
|
|
1541
1583
|
if (r.value && r.value.getCurrentAnnotation) {
|
|
1542
|
-
const
|
|
1543
|
-
|
|
1584
|
+
const p = r.value.getCurrentAnnotation();
|
|
1585
|
+
a.value[u.value] && (a.value[u.value].annotations = p.annotations);
|
|
1544
1586
|
}
|
|
1545
|
-
o.value = "gallery",
|
|
1587
|
+
o.value = "gallery", l("pageChange", { nowPage: "listPage" });
|
|
1546
1588
|
}, nt = () => {
|
|
1547
|
-
|
|
1548
|
-
}, ht = (
|
|
1549
|
-
u.value =
|
|
1550
|
-
}, Q = (
|
|
1589
|
+
l("export", a.value);
|
|
1590
|
+
}, ht = (p) => {
|
|
1591
|
+
u.value = p.currentIndex, a.value[p.currentIndex] && (a.value[p.currentIndex].annotations = p.currentAnnotations);
|
|
1592
|
+
}, Q = (p) => {
|
|
1551
1593
|
if (r.value && r.value.getCurrentAnnotation) {
|
|
1552
1594
|
const b = r.value.getCurrentAnnotation();
|
|
1553
|
-
|
|
1595
|
+
a.value[u.value] && (a.value[u.value].annotations = b.annotations, l("update:images", a.value));
|
|
1554
1596
|
}
|
|
1555
|
-
}, j = (
|
|
1556
|
-
g.value = JSON.parse(JSON.stringify(
|
|
1597
|
+
}, j = (p) => {
|
|
1598
|
+
g.value = JSON.parse(JSON.stringify(p || [])), l("update:labels", g.value);
|
|
1557
1599
|
};
|
|
1558
|
-
return (
|
|
1600
|
+
return (p, b) => (v(), m("div", {
|
|
1559
1601
|
ref_key: "batchRootRef",
|
|
1560
|
-
ref:
|
|
1602
|
+
ref: A,
|
|
1561
1603
|
class: "batch-annotator"
|
|
1562
1604
|
}, [
|
|
1563
|
-
o.value === "gallery" ? (v(), m("div",
|
|
1605
|
+
o.value === "gallery" ? (v(), m("div", Bs, [
|
|
1564
1606
|
h("div", Hs, [
|
|
1565
1607
|
h("div", Es, [
|
|
1566
1608
|
h("table", Us, [
|
|
@@ -1573,26 +1615,26 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1573
1615
|
])
|
|
1574
1616
|
], -1)),
|
|
1575
1617
|
h("tbody", null, [
|
|
1576
|
-
(v(!0), m(
|
|
1577
|
-
key:
|
|
1578
|
-
style: U(H(
|
|
1618
|
+
(v(!0), m(W, null, J(x.value, (k) => (v(), m("tr", {
|
|
1619
|
+
key: k.id,
|
|
1620
|
+
style: U(H(k))
|
|
1579
1621
|
}, [
|
|
1580
1622
|
h("td", null, [
|
|
1581
|
-
h("div",
|
|
1582
|
-
|
|
1623
|
+
h("div", Os, [
|
|
1624
|
+
k.cover ? (v(), m("img", {
|
|
1583
1625
|
key: 0,
|
|
1584
|
-
src:
|
|
1626
|
+
src: k.cover,
|
|
1585
1627
|
class: "label-cover"
|
|
1586
|
-
}, null, 8,
|
|
1628
|
+
}, null, 8, Vs)) : (v(), m("div", {
|
|
1587
1629
|
key: 1,
|
|
1588
1630
|
class: "label-cover-empty",
|
|
1589
|
-
style: U({ backgroundColor:
|
|
1631
|
+
style: U({ backgroundColor: k.color })
|
|
1590
1632
|
}, null, 4))
|
|
1591
1633
|
])
|
|
1592
1634
|
]),
|
|
1593
|
-
h("td", null,
|
|
1594
|
-
h("td", null,
|
|
1595
|
-
h("td", null,
|
|
1635
|
+
h("td", null, L(k.name), 1),
|
|
1636
|
+
h("td", null, L(k.count), 1),
|
|
1637
|
+
h("td", null, L(k.percentage), 1)
|
|
1596
1638
|
], 4))), 128))
|
|
1597
1639
|
])
|
|
1598
1640
|
])
|
|
@@ -1603,15 +1645,15 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1603
1645
|
ref: w,
|
|
1604
1646
|
class: "gallery-grid"
|
|
1605
1647
|
}, [
|
|
1606
|
-
(v(!0), m(
|
|
1648
|
+
(v(!0), m(W, null, J(a.value, (k, F) => (v(), m("div", {
|
|
1607
1649
|
key: F,
|
|
1608
1650
|
class: "gallery-item",
|
|
1609
|
-
onClick: (E) => G(F,
|
|
1651
|
+
onClick: (E) => G(F, k)
|
|
1610
1652
|
}, [
|
|
1611
|
-
h("div",
|
|
1612
|
-
|
|
1613
|
-
src:
|
|
1614
|
-
annotations:
|
|
1653
|
+
h("div", Ns, [
|
|
1654
|
+
B(Rs, {
|
|
1655
|
+
src: k.imageUrl,
|
|
1656
|
+
annotations: k.annotations || [],
|
|
1615
1657
|
labels: g.value,
|
|
1616
1658
|
fit: "cover",
|
|
1617
1659
|
strokeWidth: e.thumbStrokeWidth,
|
|
@@ -1619,31 +1661,31 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1619
1661
|
}, null, 8, ["src", "annotations", "labels", "strokeWidth", "fontSize"])
|
|
1620
1662
|
]),
|
|
1621
1663
|
h("div", Gs, [
|
|
1622
|
-
h("span", Ys, "#" +
|
|
1623
|
-
h("span", Js,
|
|
1664
|
+
h("span", Ys, "#" + L(F + 1), 1),
|
|
1665
|
+
h("span", Js, L((k.annotations || []).length) + " 标注", 1)
|
|
1624
1666
|
])
|
|
1625
|
-
], 8,
|
|
1667
|
+
], 8, Ws))), 128))
|
|
1626
1668
|
], 512)
|
|
1627
1669
|
])
|
|
1628
1670
|
]),
|
|
1629
|
-
|
|
1671
|
+
z.value ? (v(), m("div", js, [
|
|
1630
1672
|
D.value ? (v(), m("button", {
|
|
1631
1673
|
key: 0,
|
|
1632
1674
|
class: "action-btn primary",
|
|
1633
|
-
onClick: b[0] || (b[0] = (
|
|
1675
|
+
onClick: b[0] || (b[0] = (k) => V(0))
|
|
1634
1676
|
}, [
|
|
1635
|
-
|
|
1636
|
-
lt(" " +
|
|
1637
|
-
])) :
|
|
1677
|
+
B($, { name: "edit" }),
|
|
1678
|
+
lt(" " + L(X.value), 1)
|
|
1679
|
+
])) : R("", !0),
|
|
1638
1680
|
_.value ? (v(), m("button", {
|
|
1639
1681
|
key: 1,
|
|
1640
1682
|
class: "action-btn success",
|
|
1641
1683
|
onClick: nt
|
|
1642
1684
|
}, [
|
|
1643
|
-
|
|
1644
|
-
lt(" " +
|
|
1645
|
-
])) :
|
|
1646
|
-
])) :
|
|
1685
|
+
B($, { name: "download" }),
|
|
1686
|
+
lt(" " + L(C.value), 1)
|
|
1687
|
+
])) : R("", !0)
|
|
1688
|
+
])) : R("", !0)
|
|
1647
1689
|
])) : (v(), m("div", Xs, [
|
|
1648
1690
|
h("div", qs, [
|
|
1649
1691
|
h("div", Ks, [
|
|
@@ -1651,32 +1693,33 @@ const de = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//D
|
|
|
1651
1693
|
class: "back-btn",
|
|
1652
1694
|
onClick: it
|
|
1653
1695
|
}, [
|
|
1654
|
-
|
|
1696
|
+
B($, {
|
|
1655
1697
|
name: "back",
|
|
1656
1698
|
class: "back-icon"
|
|
1657
1699
|
}),
|
|
1658
1700
|
b[2] || (b[2] = lt()),
|
|
1659
1701
|
b[3] || (b[3] = h("span", { class: "back-text" }, "返回", -1))
|
|
1660
1702
|
]),
|
|
1661
|
-
h("span", Zs, "
|
|
1703
|
+
h("span", Zs, L(y.readOnly ? "正在查看" : "正在标注") + ": " + L(u.value + 1) + " / " + L(a.value.length), 1)
|
|
1662
1704
|
])
|
|
1663
1705
|
]),
|
|
1664
1706
|
h("div", Qs, [
|
|
1665
|
-
|
|
1707
|
+
B(bs, {
|
|
1666
1708
|
ref_key: "annotatorRef",
|
|
1667
1709
|
ref: r,
|
|
1668
|
-
batchImages:
|
|
1710
|
+
batchImages: a.value,
|
|
1669
1711
|
labels: g.value,
|
|
1712
|
+
readOnly: y.readOnly,
|
|
1670
1713
|
annotationTypes: ["rectangle", "polygon", "point", "rotatedRect", "category"],
|
|
1671
1714
|
onBatchChange: ht,
|
|
1672
1715
|
onAnnotationChange: Q,
|
|
1673
1716
|
onLabelChange: j
|
|
1674
|
-
}, null, 8, ["batchImages", "labels"])
|
|
1717
|
+
}, null, 8, ["batchImages", "labels", "readOnly"])
|
|
1675
1718
|
])
|
|
1676
1719
|
]))
|
|
1677
1720
|
], 512));
|
|
1678
1721
|
}
|
|
1679
|
-
}), ii = /* @__PURE__ */ rt(ti, [["__scopeId", "data-v-
|
|
1722
|
+
}), ii = /* @__PURE__ */ rt(ti, [["__scopeId", "data-v-448a060c"]]);
|
|
1680
1723
|
export {
|
|
1681
1724
|
ii as BatchAnnotator,
|
|
1682
1725
|
bs as ImageAnnotator,
|