kfb-view 2.1.18 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/workspace.xml +130 -123
- package/example/index.js +13 -4
- package/lib/kfb-view.js +1 -1
- package/package.json +1 -1
- package/src/components/area/index.js +74 -45
- package/src/components/board/index.js +127 -26
- package/src/components/rotation/index.js +2 -3
- package/src/components/shape/index.js +72 -52
- package/src/components/tailoring/index.js +1 -2
- package/src/const/event.js +3 -0
- package/src/tool/Brush.js +1 -1
- package/src/tool/Combination.js +1 -0
- package/src/tool/Polygon.js +8 -1
- package/src/tool/Thumb.js +2 -2
- package/src/util/calculate.js +26 -3
- package/src/view.js +103 -22
package/package.json
CHANGED
|
@@ -12,9 +12,10 @@ import {
|
|
|
12
12
|
baseNumber, getAngle, getDistance, getPoint,
|
|
13
13
|
getRectPoint,
|
|
14
14
|
isPointInMatrix,
|
|
15
|
-
pointInOtherPoint, isPointInPolygon, pointsToRegion,
|
|
15
|
+
pointInOtherPoint, isPointInPolygon, pointsToRegion, isPointInLine,
|
|
16
16
|
} from '../../util/calculate';
|
|
17
17
|
import {
|
|
18
|
+
EVENT_ADD_POLYGON_POINT,
|
|
18
19
|
EVENT_AREA_MOVE_END,
|
|
19
20
|
EVENT_AREA_MOVE_START, EVENT_AREA_MOVING, EVENT_CANCEL_SELECT_LABEL,
|
|
20
21
|
EVENT_DB_CLICK_LABEL,
|
|
@@ -48,12 +49,19 @@ export class Area extends ViewerCommon {
|
|
|
48
49
|
/**
|
|
49
50
|
* 画点
|
|
50
51
|
* @param {Object} point
|
|
51
|
-
* @param {
|
|
52
|
+
* @param {Boolean=} active 是否是激活状态
|
|
52
53
|
*/
|
|
53
|
-
drawPoint(point,
|
|
54
|
+
drawPoint(point, active) {
|
|
54
55
|
this.thumb.draw(point, {
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
radius: !active ?
|
|
57
|
+
this.options.thumb.radius :
|
|
58
|
+
this.options.thumb.activeRadius,
|
|
59
|
+
strokeStyle: !active ?
|
|
60
|
+
this.options.thumb.color :
|
|
61
|
+
this.options.thumb.activeColor,
|
|
62
|
+
fillStyle: !active ?
|
|
63
|
+
this.options.thumb.bgColor :
|
|
64
|
+
this.options.thumb.activeBgColor,
|
|
57
65
|
});
|
|
58
66
|
}
|
|
59
67
|
|
|
@@ -78,7 +86,11 @@ export class Area extends ViewerCommon {
|
|
|
78
86
|
this.draging = false;
|
|
79
87
|
let selectList = [];
|
|
80
88
|
let selectLabel;
|
|
89
|
+
let prevSelectLabel = undefined;
|
|
81
90
|
this.labelList.forEach((item) => {
|
|
91
|
+
if (item.select) {
|
|
92
|
+
prevSelectLabel = item;
|
|
93
|
+
}
|
|
82
94
|
item.select = false;
|
|
83
95
|
// 如果有可移动的点了,不做操作
|
|
84
96
|
if (this.movePoint) {
|
|
@@ -202,13 +214,39 @@ export class Area extends ViewerCommon {
|
|
|
202
214
|
}
|
|
203
215
|
selectLabel ?
|
|
204
216
|
this.$emit(EVENT_SELECT_LABEL, selectLabel) :
|
|
205
|
-
!this.movePoint
|
|
217
|
+
!this.movePoint && prevSelectLabel ?
|
|
218
|
+
this.$emit(EVENT_CANCEL_SELECT_LABEL, prevSelectLabel) : '';
|
|
206
219
|
this.change();
|
|
207
220
|
}
|
|
208
221
|
|
|
209
222
|
onCanvasDblClick({x, y}) {
|
|
210
223
|
setTimeout(() => {
|
|
211
|
-
this
|
|
224
|
+
const label = this.labelList.find((item) => item.select);
|
|
225
|
+
if (label?.tool === POLYGON) {
|
|
226
|
+
const points = this.imageToViewerElementPoints(label.points);
|
|
227
|
+
let index = -1;
|
|
228
|
+
for (let i = 0, l = points.length, j = l - 1; i < l; j = i, i++) {
|
|
229
|
+
const s = points[i];
|
|
230
|
+
const t = points[j];
|
|
231
|
+
if (isPointInLine({x, y}, [s, t])) {
|
|
232
|
+
index = i;
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (index > -1) {
|
|
237
|
+
const p = this.viewerElementToImageCoordinates(x, y);
|
|
238
|
+
label.points.splice(index, 0, {
|
|
239
|
+
...p,
|
|
240
|
+
canMove: true,
|
|
241
|
+
});
|
|
242
|
+
this.$emit(EVENT_ADD_POLYGON_POINT, label);
|
|
243
|
+
this.change();
|
|
244
|
+
} else {
|
|
245
|
+
this.$emit(EVENT_DB_CLICK_LABEL, label);
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
this.$emit(EVENT_DB_CLICK_LABEL, label);
|
|
249
|
+
}
|
|
212
250
|
});
|
|
213
251
|
}
|
|
214
252
|
|
|
@@ -231,11 +269,12 @@ export class Area extends ViewerCommon {
|
|
|
231
269
|
|
|
232
270
|
/**
|
|
233
271
|
* 监听鼠标拖动事件
|
|
272
|
+
* @param {Object} position
|
|
273
|
+
* @param {number} position.x
|
|
274
|
+
* @param {number} position.y
|
|
234
275
|
* @param {Object} e
|
|
235
|
-
* @param {number} e.x
|
|
236
|
-
* @param {number} e.y
|
|
237
276
|
*/
|
|
238
|
-
onCanvasDrag({x, y}) {
|
|
277
|
+
onCanvasDrag({x, y}, e) {
|
|
239
278
|
if (this.options.drag === false) return;
|
|
240
279
|
if (!this.lastPoint) this.lastPoint = {x, y};
|
|
241
280
|
const label = this.movePoint.label;
|
|
@@ -245,6 +284,7 @@ export class Area extends ViewerCommon {
|
|
|
245
284
|
if (!isMove && !isResize) return;
|
|
246
285
|
if (position === 4 && !isMove) return;
|
|
247
286
|
if (position !== 4 && !isResize) return;
|
|
287
|
+
e.preventDefaultAction = true;
|
|
248
288
|
const scale = this.getImageZoom(true) / label.scale;
|
|
249
289
|
const tool = label.tool;
|
|
250
290
|
const region = label.region;
|
|
@@ -422,53 +462,42 @@ export class Area extends ViewerCommon {
|
|
|
422
462
|
this.lastPoint = {x, y};
|
|
423
463
|
}
|
|
424
464
|
|
|
425
|
-
/**
|
|
426
|
-
* 监听鼠标按钮事件
|
|
427
|
-
* @param {Object} e
|
|
428
|
-
*/
|
|
429
|
-
onCanvasKey(e) {
|
|
430
|
-
const {originalEvent} = e;
|
|
431
|
-
if (originalEvent.code === 'Escape') {
|
|
432
|
-
this.$emit(EVENT_CANCEL_SELECT_LABEL);
|
|
433
|
-
this.change();
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
465
|
/**
|
|
438
466
|
* 绘制点
|
|
439
467
|
* @param {Object} points
|
|
440
468
|
* @param {string} type
|
|
441
469
|
*/
|
|
442
|
-
|
|
443
|
-
if (this.options.thumb === false) {
|
|
470
|
+
drawThumbPoints(points, type) {
|
|
471
|
+
if (this.options.thumb.show === false) {
|
|
444
472
|
return;
|
|
445
473
|
}
|
|
446
|
-
const
|
|
474
|
+
const position = this.movePoint?.position;
|
|
447
475
|
if (LINE_TYPES.includes(type)) {
|
|
448
|
-
this.drawPoint(points[0],
|
|
476
|
+
this.drawPoint(points[0], position === 1);
|
|
449
477
|
this.drawPoint({
|
|
450
478
|
x: (points[0].x + points[1].x) / 2,
|
|
451
479
|
y: (points[0].y + points[1].y) / 2,
|
|
452
|
-
},
|
|
453
|
-
this.drawPoint(points[1],
|
|
480
|
+
}, position === 4);
|
|
481
|
+
this.drawPoint(points[1], position === 7);
|
|
454
482
|
} else if (REGION_TYPES.includes(type)) {
|
|
455
|
-
getRectPoint(points[0], points[1]).forEach((point) => {
|
|
456
|
-
this.drawPoint(point,
|
|
483
|
+
getRectPoint(points[0], points[1]).forEach((point, i) => {
|
|
484
|
+
this.drawPoint(point, position === i);
|
|
457
485
|
});
|
|
458
486
|
} else if (type === POLYGON) {
|
|
459
|
-
points.forEach((point) => {
|
|
487
|
+
points.forEach((point, i) => {
|
|
460
488
|
if (point.canMove) {
|
|
461
|
-
this.drawPoint(point,
|
|
489
|
+
this.drawPoint(point, position === i);
|
|
462
490
|
}
|
|
463
491
|
});
|
|
464
492
|
} else if (type === FONT || type === DOT) {
|
|
465
|
-
this.drawPoint(points[0],
|
|
493
|
+
this.drawPoint(points[0], position === 4);
|
|
466
494
|
} else if (type === STAR || type === FLAG) {
|
|
467
495
|
getRectPoint(points[0], points[1]).
|
|
468
|
-
|
|
469
|
-
index ===
|
|
470
|
-
|
|
471
|
-
|
|
496
|
+
forEach((point, index) => {
|
|
497
|
+
if (index === 0 || index === 2 || index === 4 ||
|
|
498
|
+
index === 6 || index === 8) {
|
|
499
|
+
this.drawPoint(point, position === index);
|
|
500
|
+
}
|
|
472
501
|
});
|
|
473
502
|
}
|
|
474
503
|
}
|
|
@@ -489,17 +518,17 @@ export class Area extends ViewerCommon {
|
|
|
489
518
|
region.x + region.width, region.y + region.height);
|
|
490
519
|
const scale = this.getImageZoom(true) / label.scale;
|
|
491
520
|
if (!NO_NORMAL_REGION_TYPES.includes(label.tool)) {
|
|
492
|
-
this.
|
|
521
|
+
this.drawThumbPoints([startPoint, endPoint], label.tool);
|
|
493
522
|
} else if (label.tool === FONT) {
|
|
494
523
|
const fontWidth = this.getFontWidth(label.text, label.fontSize);
|
|
495
524
|
const pt = getPoint(startPoint, {
|
|
496
525
|
x: startPoint.x + fontWidth / 2 * scale,
|
|
497
526
|
y: startPoint.y - label.fontSize / 2 * scale + 4,
|
|
498
527
|
}, label.angle);
|
|
499
|
-
this.
|
|
528
|
+
this.drawThumbPoints([pt], label.tool);
|
|
500
529
|
} else if (label.tool === STAR) {
|
|
501
530
|
const dist = label.lineWidth * scale;
|
|
502
|
-
this.
|
|
531
|
+
this.drawThumbPoints([
|
|
503
532
|
{
|
|
504
533
|
x: startPoint.x - dist,
|
|
505
534
|
y: startPoint.y - dist,
|
|
@@ -508,14 +537,14 @@ export class Area extends ViewerCommon {
|
|
|
508
537
|
y: startPoint.y + dist,
|
|
509
538
|
}], label.tool);
|
|
510
539
|
} else if (label.tool === DOT) {
|
|
511
|
-
this.
|
|
540
|
+
this.drawThumbPoints([
|
|
512
541
|
{
|
|
513
542
|
x: startPoint.x,
|
|
514
543
|
y: startPoint.y,
|
|
515
544
|
}], label.tool);
|
|
516
545
|
} else if (label.tool === FLAG) {
|
|
517
546
|
const dist = label.lineWidth * scale;
|
|
518
|
-
this.
|
|
547
|
+
this.drawThumbPoints([
|
|
519
548
|
{
|
|
520
549
|
x: startPoint.x,
|
|
521
550
|
y: startPoint.y - dist,
|
|
@@ -526,10 +555,10 @@ export class Area extends ViewerCommon {
|
|
|
526
555
|
} else if (label.tool === POLYGON) {
|
|
527
556
|
if (this.draging) {
|
|
528
557
|
const points = this.imageToViewerElementPoints(label.points);
|
|
529
|
-
this.
|
|
558
|
+
this.drawThumbPoints(points, label.tool);
|
|
530
559
|
} else {
|
|
531
560
|
const points = this.setPointsMove(label);
|
|
532
|
-
this.
|
|
561
|
+
this.drawThumbPoints(points, label.tool);
|
|
533
562
|
}
|
|
534
563
|
}
|
|
535
564
|
this[label.tool].setContent(this.canvas, {...label});
|
|
@@ -552,7 +581,7 @@ export class Area extends ViewerCommon {
|
|
|
552
581
|
label.points[index].canMove = false;
|
|
553
582
|
if (index === 0 || (!pointInOtherPoint(lastPoint, point, 30) &&
|
|
554
583
|
!pointInOtherPoint(movePoints[0], point, 30)) ||
|
|
555
|
-
(
|
|
584
|
+
(index === movePoints.length - 1)) {
|
|
556
585
|
lastPoint = point;
|
|
557
586
|
point.canMove = true;
|
|
558
587
|
label.points[index].canMove = true;
|
|
@@ -48,6 +48,7 @@ export class Board extends ViewerCommon {
|
|
|
48
48
|
* @param {boolean} [options.measure=true] 绘画时显示信息
|
|
49
49
|
* @param {boolean} [options.clear=true] 是否结束绘画时清空画布
|
|
50
50
|
* @param {boolean} [options.isClose=true] 是否自动闭合曲线
|
|
51
|
+
* @param {boolean} [options.enableDbClickClose=true] 是否双击结束曲线绘制
|
|
51
52
|
* @param {boolean} [options.once=false] 是否绘画一次后自动结束
|
|
52
53
|
* @param {boolean} [options.isROI=false] 是否是感性区域
|
|
53
54
|
* @param {boolean} [options.move=true] 是否可移动
|
|
@@ -74,6 +75,7 @@ export class Board extends ViewerCommon {
|
|
|
74
75
|
measure: true,
|
|
75
76
|
clear: true,
|
|
76
77
|
isClose: true,
|
|
78
|
+
enableDbClickClose: true,
|
|
77
79
|
...options,
|
|
78
80
|
lineWidth: !options.lineWidth ?
|
|
79
81
|
(this.tool === STAR ? 15 :
|
|
@@ -103,6 +105,8 @@ export class Board extends ViewerCommon {
|
|
|
103
105
|
text: '',
|
|
104
106
|
measure: true,
|
|
105
107
|
clear: true,
|
|
108
|
+
isClose: true,
|
|
109
|
+
enableDbClickClose: true,
|
|
106
110
|
...options,
|
|
107
111
|
lineWidth: !options.lineWidth ?
|
|
108
112
|
(this.tool === STAR ? 15 :
|
|
@@ -141,8 +145,16 @@ export class Board extends ViewerCommon {
|
|
|
141
145
|
}
|
|
142
146
|
this.clearCanvas();
|
|
143
147
|
this[tool].startDraw();
|
|
144
|
-
this
|
|
148
|
+
const points = this.imageToViewerElementPoints(this.points);
|
|
149
|
+
this[tool].draw(points);
|
|
145
150
|
this[tool].endDraw();
|
|
151
|
+
if (tool === POLYGON) {
|
|
152
|
+
this[tool].drawPoints(points, {
|
|
153
|
+
radius: this.options.thumb.radius,
|
|
154
|
+
strokeStyle: this.options.thumb.color,
|
|
155
|
+
fillStyle: this.options.thumb.bgColor,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
146
158
|
this.$emit(EVENT_START_PAINTING, this.getPaintOptions());
|
|
147
159
|
}
|
|
148
160
|
|
|
@@ -164,13 +176,22 @@ export class Board extends ViewerCommon {
|
|
|
164
176
|
this.points = [this.points[0] || point, point];
|
|
165
177
|
} else if (tool === POLYGON) {
|
|
166
178
|
this.points.push(point);
|
|
179
|
+
this.setEnablePoints(false);
|
|
167
180
|
} else if (POINT_TYPES.includes(tool)) {
|
|
168
181
|
this.points = [point, point];
|
|
169
182
|
}
|
|
170
183
|
this.clearCanvas();
|
|
171
184
|
this[tool].startDraw();
|
|
172
|
-
this
|
|
185
|
+
const points = this.imageToViewerElementPoints(this.points);
|
|
186
|
+
this[tool].draw(points);
|
|
173
187
|
this[tool].endDraw();
|
|
188
|
+
if (tool === POLYGON) {
|
|
189
|
+
this[tool].drawPoints(points, {
|
|
190
|
+
radius: this.options.thumb.radius,
|
|
191
|
+
strokeStyle: this.options.thumb.color,
|
|
192
|
+
fillStyle: this.options.thumb.bgColor,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
174
195
|
this.$emit(EVENT_IN_PAINTING, this.getPaintOptions());
|
|
175
196
|
}
|
|
176
197
|
|
|
@@ -195,30 +216,60 @@ export class Board extends ViewerCommon {
|
|
|
195
216
|
} else if (POINT_TYPES.includes(tool)) {
|
|
196
217
|
this.points = [point, point];
|
|
197
218
|
} else if (tool === POLYGON) {
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
//
|
|
201
|
-
const isClose = this[this.tool].options.isClose;
|
|
202
|
-
if (
|
|
203
|
-
|
|
204
|
-
|
|
219
|
+
const firstPoint = this.imageToViewerElementCoordinates(this.points[0].x,
|
|
220
|
+
this.points[0].y);
|
|
221
|
+
const enableDbClickClose = this[this.tool].options.enableDbClickClose; // 是否启用双击结束绘制
|
|
222
|
+
const isClose = this[this.tool].options.isClose; // 是否自动关闭
|
|
223
|
+
if (enableDbClickClose) {
|
|
224
|
+
if (isClose && pointInOtherPoint(firstPoint, {x, y})) {
|
|
225
|
+
this.setEnablePoints();
|
|
226
|
+
if (this.points.length < 5) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
} else {
|
|
205
230
|
return;
|
|
206
231
|
}
|
|
207
|
-
} else
|
|
232
|
+
} else {
|
|
233
|
+
this.setEnablePoints();
|
|
234
|
+
// 如果点小于5个,任务标注不符合规范
|
|
235
|
+
if (this.points.length < 5) {
|
|
236
|
+
this.points = [];
|
|
237
|
+
this.clearCanvas();
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
this.$emit(EVENT_END_PAINTING, this.getPaintOptions());
|
|
243
|
+
// 是否只绘制一次
|
|
244
|
+
if (this[this.tool].options.once) {
|
|
245
|
+
this.endDraw();
|
|
246
|
+
} else if (this[this.tool].options.clear) { // 是否结束绘画时清空画布
|
|
247
|
+
this.points = [];
|
|
248
|
+
this.clearCanvas();
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* 监听鼠标双击事件
|
|
254
|
+
* @param {Object} e
|
|
255
|
+
* @param {number} e.x
|
|
256
|
+
* @param {number} e.y
|
|
257
|
+
*/
|
|
258
|
+
onCanvasDblClick({x, y}) {
|
|
259
|
+
const point = this.viewerElementToImageCoordinates(x, y);
|
|
260
|
+
if (!this.isInROI(point) || this.points.length === 0) {
|
|
261
|
+
this.points = [];
|
|
262
|
+
this.clearCanvas();
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (this.tool === POLYGON) {
|
|
266
|
+
this.setEnablePoints();
|
|
267
|
+
// 如果点小于5个,任务标注不符合规范
|
|
268
|
+
if (this.points.length < 5) {
|
|
269
|
+
this.points = [];
|
|
270
|
+
this.clearCanvas();
|
|
208
271
|
return;
|
|
209
272
|
}
|
|
210
|
-
// 过滤曲线的点,点之间的距离小于10默认为一个点,取第一个
|
|
211
|
-
this.points = this.points.filter((p, index) => {
|
|
212
|
-
const _p = this.imageToViewerElementCoordinates(p.x, p.y);
|
|
213
|
-
if (index === 0) return true;
|
|
214
|
-
if (!isClose && index === this.points.length - 1) return true;
|
|
215
|
-
if (pointInOtherPoint(firstPoint, _p)) {
|
|
216
|
-
return false;
|
|
217
|
-
} else {
|
|
218
|
-
firstPoint = _p;
|
|
219
|
-
return true;
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
273
|
}
|
|
223
274
|
this.$emit(EVENT_END_PAINTING, this.getPaintOptions());
|
|
224
275
|
// 是否只绘制一次
|
|
@@ -245,12 +296,22 @@ export class Board extends ViewerCommon {
|
|
|
245
296
|
}
|
|
246
297
|
const tool = this.tool;
|
|
247
298
|
if (tool === POLYGON && this.points.length > 0) {
|
|
248
|
-
this.points.
|
|
299
|
+
if (this.points.length > 1) {
|
|
300
|
+
this.points.pop();
|
|
301
|
+
}
|
|
249
302
|
this.points.push(point);
|
|
250
303
|
this.clearCanvas();
|
|
251
304
|
this[tool].startDraw();
|
|
252
|
-
this
|
|
305
|
+
const points = this.imageToViewerElementPoints(this.points);
|
|
306
|
+
this[tool].draw(points);
|
|
253
307
|
this[tool].endDraw();
|
|
308
|
+
if (tool === POLYGON) {
|
|
309
|
+
this[tool].drawPoints(points, {
|
|
310
|
+
radius: this.options.thumb.radius,
|
|
311
|
+
strokeStyle: this.options.thumb.color,
|
|
312
|
+
fillStyle: this.options.thumb.bgColor,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
254
315
|
this.$emit(EVENT_IN_PAINTING, this.getPaintOptions());
|
|
255
316
|
}
|
|
256
317
|
}
|
|
@@ -261,10 +322,43 @@ export class Board extends ViewerCommon {
|
|
|
261
322
|
*/
|
|
262
323
|
onCanvasKey(e) {
|
|
263
324
|
const {originalEvent} = e;
|
|
264
|
-
|
|
265
|
-
if (originalEvent.code === 'Escape') {
|
|
325
|
+
if (originalEvent.key === 'Escape') {
|
|
266
326
|
this.endDraw();
|
|
267
327
|
}
|
|
328
|
+
if (originalEvent.key === 'Delete' || originalEvent.key ===
|
|
329
|
+
'Backspace') {
|
|
330
|
+
// 曲线绘制中,按删除键,删除上一个标注点
|
|
331
|
+
if (this.tool === POLYGON && this.points.length > 1) {
|
|
332
|
+
this.points.splice(this.points.length - 2, 1);
|
|
333
|
+
this.change();
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
setEnablePoints(end = true) {
|
|
339
|
+
const points = this.imageToViewerElementPoints(this.points);
|
|
340
|
+
let firstPoint = points[0];
|
|
341
|
+
// 过滤曲线的点,点之间的距离小于10默认为一个点,取第一个
|
|
342
|
+
this.points = this.points.filter((p, index) => {
|
|
343
|
+
const _p = points[index];
|
|
344
|
+
if (index === 0) return true;
|
|
345
|
+
if (index === this.points.length - 1) return true;
|
|
346
|
+
if (pointInOtherPoint(firstPoint, _p, 30)) {
|
|
347
|
+
return false;
|
|
348
|
+
} else {
|
|
349
|
+
firstPoint = _p;
|
|
350
|
+
return true;
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
if (end && this.points.length > 1) {
|
|
354
|
+
const lastPoint = this.points[this.points.length - 1];
|
|
355
|
+
const lastTwoPoint = this.points[this.points.length - 2];
|
|
356
|
+
if (pointInOtherPoint(
|
|
357
|
+
this.imageToViewerElementCoordinates(lastPoint.x, lastPoint.y),
|
|
358
|
+
this.imageToViewerElementCoordinates(lastTwoPoint.x, lastTwoPoint.y))) {
|
|
359
|
+
this.points.splice(this.points.length - 2, 1);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
268
362
|
}
|
|
269
363
|
|
|
270
364
|
getPaintOptions() {
|
|
@@ -328,6 +422,13 @@ export class Board extends ViewerCommon {
|
|
|
328
422
|
this[this.tool].startDraw();
|
|
329
423
|
this[this.tool].draw(points);
|
|
330
424
|
this[this.tool].endDraw();
|
|
425
|
+
if (this.tool === POLYGON) {
|
|
426
|
+
this[this.tool].drawPoints(points, {
|
|
427
|
+
radius: this.options.thumb.radius,
|
|
428
|
+
strokeStyle: this.options.thumb.color,
|
|
429
|
+
fillStyle: this.options.thumb.bgColor,
|
|
430
|
+
});
|
|
431
|
+
}
|
|
331
432
|
this.$emit(EVENT_IN_PAINTING, this.getPaintOptions());
|
|
332
433
|
}
|
|
333
434
|
}
|
|
@@ -91,7 +91,7 @@ class Rotation extends ViewerCommon {
|
|
|
91
91
|
this.drawPoint({
|
|
92
92
|
x: point.x,
|
|
93
93
|
y: point.y,
|
|
94
|
-
}, {
|
|
94
|
+
}, {radius: 5});
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
97
|
|
|
@@ -152,8 +152,7 @@ class Rotation extends ViewerCommon {
|
|
|
152
152
|
*/
|
|
153
153
|
onCanvasKey(e) {
|
|
154
154
|
const {originalEvent} = e;
|
|
155
|
-
|
|
156
|
-
if (originalEvent.code === 'Escape') {
|
|
155
|
+
if (originalEvent.key === 'Escape') {
|
|
157
156
|
this.viewport.setRotation(0);
|
|
158
157
|
this.stopRotation();
|
|
159
158
|
}
|
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
import {ViewerCommon} from '../common/common';
|
|
6
6
|
import * as Tools from '../../tool';
|
|
7
7
|
import {Combination} from '../../tool/Combination';
|
|
8
|
+
import {EVENT_CANCEL_SELECT_LABEL} from '../../const/event';
|
|
9
|
+
import * as EVENTS from '../../const/event';
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* 用来显示标注线的canvas
|
|
@@ -25,6 +27,7 @@ export class Shape extends ViewerCommon {
|
|
|
25
27
|
this[mark] = new Tools[mark];
|
|
26
28
|
});
|
|
27
29
|
this.combination = new Combination();
|
|
30
|
+
this.delaytimer = [];
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
/**
|
|
@@ -32,15 +35,6 @@ export class Shape extends ViewerCommon {
|
|
|
32
35
|
* @param {Object} e
|
|
33
36
|
*/
|
|
34
37
|
onCanvasKey(e) {
|
|
35
|
-
const {originalEvent} = e;
|
|
36
|
-
e.preventDefaultAction = true;
|
|
37
|
-
if (originalEvent.code === 'Escape') {
|
|
38
|
-
this.labelList.forEach((item) => {
|
|
39
|
-
item.select = false;
|
|
40
|
-
item.show = true;
|
|
41
|
-
});
|
|
42
|
-
this.change();
|
|
43
|
-
}
|
|
44
38
|
}
|
|
45
39
|
|
|
46
40
|
/**
|
|
@@ -59,29 +53,24 @@ export class Shape extends ViewerCommon {
|
|
|
59
53
|
this.clearCanvas();
|
|
60
54
|
// 区域标注列表
|
|
61
55
|
const regionLabelList = [];
|
|
62
|
-
this.labelList.
|
|
63
|
-
(item)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
56
|
+
const labelList = this.labelList.filter((item) => {
|
|
57
|
+
if (item.show === false) return false;
|
|
58
|
+
if (!this[item.tool]) return false;
|
|
59
|
+
if (!this.isInCanvas(item.region)) return false;
|
|
60
|
+
if (REGION_TYPES.includes(item.tool) || item.isClose && item.tool ===
|
|
61
|
+
POLYGON && item.fillStyle) {
|
|
62
|
+
regionLabelList.push({
|
|
63
|
+
...item,
|
|
64
|
+
child: [],
|
|
65
|
+
self: item,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
});
|
|
73
70
|
// strokeStyle, lineWidth, fillStyle 相同认为是一个路径下的图形,一起绘制,优化性能
|
|
74
71
|
const sameFixWidthLabel = {}; // star, flag, star, font lineWidth固定为2
|
|
75
72
|
const sameNormalLabel = {};
|
|
76
|
-
|
|
77
|
-
if (item.show === false) return;
|
|
78
|
-
if (!this[item.tool]) return;
|
|
79
|
-
if (!this.isInCanvas(item.region)) return;
|
|
80
|
-
/* const point = this.imageToViewerElementCoordinates(item.points[0].x,
|
|
81
|
-
item.points[0].y);
|
|
82
|
-
if ((point.x > this.canvas.width ||
|
|
83
|
-
point.y > this.canvas.height ||
|
|
84
|
-
point.x < 0 || point.y < 0)) return;*/
|
|
73
|
+
labelList.forEach((item) => {
|
|
85
74
|
const key = `${item.strokeStyle ?? ''}_${item.lineWidth ??
|
|
86
75
|
''}_${item.fillStyle ?? ''}`;
|
|
87
76
|
const regionKey = `${item.strokeStyle ?? ''}_${item.lineWidth ?? ''}`;
|
|
@@ -106,11 +95,41 @@ export class Shape extends ViewerCommon {
|
|
|
106
95
|
parent.child.push(item);
|
|
107
96
|
}
|
|
108
97
|
});
|
|
98
|
+
if (this.delaytimer) {
|
|
99
|
+
clearTimeout(this.delaytimer);
|
|
100
|
+
this.delaytimer = undefined;
|
|
101
|
+
}
|
|
102
|
+
this.deepDrawLabel(sameFixWidthLabel, sameNormalLabel, 1);
|
|
103
|
+
regionLabelList.forEach((item) => {
|
|
104
|
+
this.combination.setContent(this.canvas, item);
|
|
105
|
+
this.combination.draw({
|
|
106
|
+
points: this.imageToViewerElementPoints(item.points),
|
|
107
|
+
tool: item.tool,
|
|
108
|
+
}, item.child.map(({points, tool}) => ({
|
|
109
|
+
points: this.imageToViewerElementPoints(points),
|
|
110
|
+
tool,
|
|
111
|
+
})), this.viewport.getRotation());
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
deepDrawLabel(sameFixWidthLabel, sameNormalLabel, count) {
|
|
116
|
+
let currentDrawCount = 0; // 当前已绘制数量
|
|
109
117
|
const ctx = this.canvas.getContext('2d');
|
|
110
|
-
|
|
118
|
+
const remainFixLabel = {};
|
|
119
|
+
Object.keys(sameFixWidthLabel).forEach((key) => {
|
|
120
|
+
const labels = sameFixWidthLabel[key];
|
|
111
121
|
ctx.beginPath();
|
|
112
122
|
labels.forEach((item) => {
|
|
113
|
-
|
|
123
|
+
if (currentDrawCount >= 5000) { // 一次最多绘制5000个标注,多余标注延迟绘制
|
|
124
|
+
if (remainFixLabel[key]) {
|
|
125
|
+
remainFixLabel[key].push(item);
|
|
126
|
+
} else {
|
|
127
|
+
remainFixLabel[key] = [item];
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
this.drawLabel(item);
|
|
131
|
+
}
|
|
132
|
+
currentDrawCount++;
|
|
114
133
|
});
|
|
115
134
|
const firstLabel = labels?.[0];
|
|
116
135
|
if (firstLabel?.fillStyle) {
|
|
@@ -120,35 +139,36 @@ export class Shape extends ViewerCommon {
|
|
|
120
139
|
ctx.strokeStyle = firstLabel.strokeStyle;
|
|
121
140
|
ctx.stroke();
|
|
122
141
|
});
|
|
123
|
-
|
|
142
|
+
const remainNormalLabel = {};
|
|
143
|
+
Object.keys(sameNormalLabel).forEach((key) => {
|
|
144
|
+
const labels = sameNormalLabel[key];
|
|
124
145
|
ctx.beginPath();
|
|
125
146
|
labels.forEach((item) => {
|
|
126
|
-
|
|
147
|
+
if (currentDrawCount >= 5000) { // 一次最多绘制5000个标注,多余标注延迟绘制
|
|
148
|
+
if (remainNormalLabel[key]) {
|
|
149
|
+
remainNormalLabel[key].push(item);
|
|
150
|
+
} else {
|
|
151
|
+
remainNormalLabel[key] = [item];
|
|
152
|
+
}
|
|
153
|
+
} else {
|
|
154
|
+
this.drawLabel(item);
|
|
155
|
+
}
|
|
156
|
+
currentDrawCount++;
|
|
127
157
|
});
|
|
128
158
|
const firstLabel = labels?.[0];
|
|
129
159
|
ctx.lineWidth = firstLabel.lineWidth;
|
|
130
160
|
ctx.strokeStyle = firstLabel.strokeStyle;
|
|
131
161
|
ctx.stroke();
|
|
132
162
|
});
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
point.x < 0 || point.y < 0)) return;*/
|
|
143
|
-
this.combination.setContent(this.canvas, item);
|
|
144
|
-
this.combination.draw({
|
|
145
|
-
points: this.imageToViewerElementPoints(item.points),
|
|
146
|
-
tool: item.tool,
|
|
147
|
-
}, item.child.map(({points, tool}) => ({
|
|
148
|
-
points: this.imageToViewerElementPoints(points),
|
|
149
|
-
tool,
|
|
150
|
-
})), this.viewport.getRotation());
|
|
151
|
-
});
|
|
163
|
+
if (Object.keys(remainFixLabel).length === 0 &&
|
|
164
|
+
Object.keys(remainNormalLabel).length === 0) {
|
|
165
|
+
console.log(`end deep draw label, draw count: ${count}`);
|
|
166
|
+
this.delaytimer = undefined;
|
|
167
|
+
} else {
|
|
168
|
+
this.delaytimer = setTimeout(() => {
|
|
169
|
+
this.deepDrawLabel(remainFixLabel, remainNormalLabel, count + 1);
|
|
170
|
+
}, 100);
|
|
171
|
+
}
|
|
152
172
|
}
|
|
153
173
|
|
|
154
174
|
drawLabel(item) {
|
|
@@ -220,8 +220,7 @@ export class Tailoring extends ViewerCommon {
|
|
|
220
220
|
*/
|
|
221
221
|
onCanvasKey(e) {
|
|
222
222
|
const {originalEvent} = e;
|
|
223
|
-
|
|
224
|
-
if (originalEvent.code === 'Escape') {
|
|
223
|
+
if (originalEvent.key === 'Escape') {
|
|
225
224
|
this.stopTailoring();
|
|
226
225
|
}
|
|
227
226
|
}
|