kfb-view 2.1.17 → 2.1.20
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 +119 -119
- package/example/index.js +10 -2
- package/lib/kfb-view.js +1 -1
- package/package.json +1 -1
- package/src/components/area/index.js +12 -5
- package/src/components/board/index.js +116 -28
- package/src/components/rotation/index.js +6 -5
- package/src/components/shape/index.js +9 -7
- package/src/components/tailoring/index.js +5 -4
- package/src/tool/Polygon.js +11 -1
- package/src/view.js +45 -3
package/package.json
CHANGED
|
@@ -78,7 +78,11 @@ export class Area extends ViewerCommon {
|
|
|
78
78
|
this.draging = false;
|
|
79
79
|
let selectList = [];
|
|
80
80
|
let selectLabel;
|
|
81
|
+
let prevSelectLabel = undefined;
|
|
81
82
|
this.labelList.forEach((item) => {
|
|
83
|
+
if (item.select) {
|
|
84
|
+
prevSelectLabel = item;
|
|
85
|
+
}
|
|
82
86
|
item.select = false;
|
|
83
87
|
// 如果有可移动的点了,不做操作
|
|
84
88
|
if (this.movePoint) {
|
|
@@ -202,13 +206,15 @@ export class Area extends ViewerCommon {
|
|
|
202
206
|
}
|
|
203
207
|
selectLabel ?
|
|
204
208
|
this.$emit(EVENT_SELECT_LABEL, selectLabel) :
|
|
205
|
-
!this.movePoint
|
|
209
|
+
!this.movePoint && prevSelectLabel ?
|
|
210
|
+
this.$emit(EVENT_CANCEL_SELECT_LABEL, prevSelectLabel) : '';
|
|
206
211
|
this.change();
|
|
207
212
|
}
|
|
208
213
|
|
|
209
214
|
onCanvasDblClick({x, y}) {
|
|
210
215
|
setTimeout(() => {
|
|
211
|
-
this
|
|
216
|
+
const label = this.labelList.find((item) => item.select);
|
|
217
|
+
this.$emit(EVENT_DB_CLICK_LABEL, label);
|
|
212
218
|
});
|
|
213
219
|
}
|
|
214
220
|
|
|
@@ -428,8 +434,9 @@ export class Area extends ViewerCommon {
|
|
|
428
434
|
*/
|
|
429
435
|
onCanvasKey(e) {
|
|
430
436
|
const {originalEvent} = e;
|
|
431
|
-
|
|
432
|
-
|
|
437
|
+
const label = this.labelList.find((item) => item.select);
|
|
438
|
+
if (originalEvent.code === 'Escape' && label) {
|
|
439
|
+
this.$emit(EVENT_CANCEL_SELECT_LABEL, label);
|
|
433
440
|
this.change();
|
|
434
441
|
}
|
|
435
442
|
}
|
|
@@ -552,7 +559,7 @@ export class Area extends ViewerCommon {
|
|
|
552
559
|
label.points[index].canMove = false;
|
|
553
560
|
if (index === 0 || (!pointInOtherPoint(lastPoint, point, 30) &&
|
|
554
561
|
!pointInOtherPoint(movePoints[0], point, 30)) ||
|
|
555
|
-
(
|
|
562
|
+
(index === movePoints.length - 1)) {
|
|
556
563
|
lastPoint = point;
|
|
557
564
|
point.canMove = true;
|
|
558
565
|
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,12 @@ 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
|
+
}
|
|
146
154
|
this.$emit(EVENT_START_PAINTING, this.getPaintOptions());
|
|
147
155
|
}
|
|
148
156
|
|
|
@@ -164,13 +172,18 @@ export class Board extends ViewerCommon {
|
|
|
164
172
|
this.points = [this.points[0] || point, point];
|
|
165
173
|
} else if (tool === POLYGON) {
|
|
166
174
|
this.points.push(point);
|
|
175
|
+
this.setEnablePoints(false);
|
|
167
176
|
} else if (POINT_TYPES.includes(tool)) {
|
|
168
177
|
this.points = [point, point];
|
|
169
178
|
}
|
|
170
179
|
this.clearCanvas();
|
|
171
180
|
this[tool].startDraw();
|
|
172
|
-
this
|
|
181
|
+
const points = this.imageToViewerElementPoints(this.points);
|
|
182
|
+
this[tool].draw(points);
|
|
173
183
|
this[tool].endDraw();
|
|
184
|
+
if (tool === POLYGON) {
|
|
185
|
+
this[tool].drawPoints(points);
|
|
186
|
+
}
|
|
174
187
|
this.$emit(EVENT_IN_PAINTING, this.getPaintOptions());
|
|
175
188
|
}
|
|
176
189
|
|
|
@@ -195,30 +208,60 @@ export class Board extends ViewerCommon {
|
|
|
195
208
|
} else if (POINT_TYPES.includes(tool)) {
|
|
196
209
|
this.points = [point, point];
|
|
197
210
|
} else if (tool === POLYGON) {
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
//
|
|
201
|
-
const isClose = this[this.tool].options.isClose;
|
|
202
|
-
if (
|
|
203
|
-
|
|
204
|
-
|
|
211
|
+
const firstPoint = this.imageToViewerElementCoordinates(this.points[0].x,
|
|
212
|
+
this.points[0].y);
|
|
213
|
+
const enableDbClickClose = this[this.tool].options.enableDbClickClose; // 是否启用双击结束绘制
|
|
214
|
+
const isClose = this[this.tool].options.isClose; // 是否自动关闭
|
|
215
|
+
if (enableDbClickClose) {
|
|
216
|
+
if (isClose && pointInOtherPoint(firstPoint, {x, y})) {
|
|
217
|
+
this.setEnablePoints();
|
|
218
|
+
if (this.points.length < 5) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
} else {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
} else {
|
|
225
|
+
this.setEnablePoints();
|
|
226
|
+
// 如果点小于5个,任务标注不符合规范
|
|
227
|
+
if (this.points.length < 5) {
|
|
228
|
+
this.points = [];
|
|
229
|
+
this.clearCanvas();
|
|
205
230
|
return;
|
|
206
231
|
}
|
|
207
|
-
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
this.$emit(EVENT_END_PAINTING, this.getPaintOptions());
|
|
235
|
+
// 是否只绘制一次
|
|
236
|
+
if (this[this.tool].options.once) {
|
|
237
|
+
this.endDraw();
|
|
238
|
+
} else if (this[this.tool].options.clear) { // 是否结束绘画时清空画布
|
|
239
|
+
this.points = [];
|
|
240
|
+
this.clearCanvas();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* 监听鼠标双击事件
|
|
246
|
+
* @param {Object} e
|
|
247
|
+
* @param {number} e.x
|
|
248
|
+
* @param {number} e.y
|
|
249
|
+
*/
|
|
250
|
+
onCanvasDblClick({x, y}) {
|
|
251
|
+
const point = this.viewerElementToImageCoordinates(x, y);
|
|
252
|
+
if (!this.isInROI(point) || this.points.length === 0) {
|
|
253
|
+
this.points = [];
|
|
254
|
+
this.clearCanvas();
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (this.tool === POLYGON) {
|
|
258
|
+
this.setEnablePoints();
|
|
259
|
+
// 如果点小于5个,任务标注不符合规范
|
|
260
|
+
if (this.points.length < 5) {
|
|
261
|
+
this.points = [];
|
|
262
|
+
this.clearCanvas();
|
|
208
263
|
return;
|
|
209
264
|
}
|
|
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
265
|
}
|
|
223
266
|
this.$emit(EVENT_END_PAINTING, this.getPaintOptions());
|
|
224
267
|
// 是否只绘制一次
|
|
@@ -245,12 +288,18 @@ export class Board extends ViewerCommon {
|
|
|
245
288
|
}
|
|
246
289
|
const tool = this.tool;
|
|
247
290
|
if (tool === POLYGON && this.points.length > 0) {
|
|
248
|
-
this.points.
|
|
291
|
+
if (this.points.length > 1) {
|
|
292
|
+
this.points.pop();
|
|
293
|
+
}
|
|
249
294
|
this.points.push(point);
|
|
250
295
|
this.clearCanvas();
|
|
251
296
|
this[tool].startDraw();
|
|
252
|
-
this
|
|
297
|
+
const points = this.imageToViewerElementPoints(this.points);
|
|
298
|
+
this[tool].draw(points);
|
|
253
299
|
this[tool].endDraw();
|
|
300
|
+
if (tool === POLYGON) {
|
|
301
|
+
this[tool].drawPoints(points);
|
|
302
|
+
}
|
|
254
303
|
this.$emit(EVENT_IN_PAINTING, this.getPaintOptions());
|
|
255
304
|
}
|
|
256
305
|
}
|
|
@@ -260,10 +309,46 @@ export class Board extends ViewerCommon {
|
|
|
260
309
|
* @param {Object} e
|
|
261
310
|
*/
|
|
262
311
|
onCanvasKey(e) {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
312
|
+
if (this.isInDraw) {
|
|
313
|
+
const {originalEvent} = e;
|
|
314
|
+
if (originalEvent.code === 'Escape') {
|
|
315
|
+
this.endDraw();
|
|
316
|
+
}
|
|
317
|
+
if (originalEvent.code === 'Delete' || originalEvent.key ===
|
|
318
|
+
'Backspace') {
|
|
319
|
+
// 曲线绘制中,按删除键,删除上一个标注点
|
|
320
|
+
if (this.tool === POLYGON && this.points.length > 1) {
|
|
321
|
+
this.points.splice(this.points.length - 2, 1);
|
|
322
|
+
this.change();
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
setEnablePoints(end = true) {
|
|
329
|
+
const points = this.imageToViewerElementPoints(this.points);
|
|
330
|
+
let firstPoint = points[0];
|
|
331
|
+
// 过滤曲线的点,点之间的距离小于10默认为一个点,取第一个
|
|
332
|
+
this.points = this.points.filter((p, index) => {
|
|
333
|
+
const _p = points[index];
|
|
334
|
+
if (index === 0) return true;
|
|
335
|
+
if (index === this.points.length - 1) return true;
|
|
336
|
+
if (pointInOtherPoint(firstPoint, _p, 30)) {
|
|
337
|
+
return false;
|
|
338
|
+
} else {
|
|
339
|
+
firstPoint = _p;
|
|
340
|
+
return true;
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
if (end && this.points.length > 1) {
|
|
344
|
+
const lastPoint = this.points[this.points.length - 1];
|
|
345
|
+
const lastTwoPoint = this.points[this.points.length - 2];
|
|
346
|
+
if (pointInOtherPoint(
|
|
347
|
+
this.imageToViewerElementCoordinates(lastPoint.x, lastPoint.y),
|
|
348
|
+
this.imageToViewerElementCoordinates(lastTwoPoint.x, lastTwoPoint.y),
|
|
349
|
+
30)) {
|
|
350
|
+
this.points.splice(this.points.length - 2, 1);
|
|
351
|
+
}
|
|
267
352
|
}
|
|
268
353
|
}
|
|
269
354
|
|
|
@@ -328,6 +413,9 @@ export class Board extends ViewerCommon {
|
|
|
328
413
|
this[this.tool].startDraw();
|
|
329
414
|
this[this.tool].draw(points);
|
|
330
415
|
this[this.tool].endDraw();
|
|
416
|
+
if (this.tool === POLYGON) {
|
|
417
|
+
this[this.tool].drawPoints(points);
|
|
418
|
+
}
|
|
331
419
|
this.$emit(EVENT_IN_PAINTING, this.getPaintOptions());
|
|
332
420
|
}
|
|
333
421
|
}
|
|
@@ -151,11 +151,12 @@ class Rotation extends ViewerCommon {
|
|
|
151
151
|
* @param {Object} e
|
|
152
152
|
*/
|
|
153
153
|
onCanvasKey(e) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
154
|
+
if (this.isInRotation) {
|
|
155
|
+
const {originalEvent} = e;
|
|
156
|
+
if (originalEvent.code === 'Escape') {
|
|
157
|
+
this.viewport.setRotation(0);
|
|
158
|
+
this.stopRotation();
|
|
159
|
+
}
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
162
|
|
|
@@ -76,11 +76,12 @@ export class Shape extends ViewerCommon {
|
|
|
76
76
|
this.labelList.forEach((item) => {
|
|
77
77
|
if (item.show === false) return;
|
|
78
78
|
if (!this[item.tool]) return;
|
|
79
|
-
|
|
79
|
+
if (!this.isInCanvas(item.region)) return;
|
|
80
|
+
/* const point = this.imageToViewerElementCoordinates(item.points[0].x,
|
|
80
81
|
item.points[0].y);
|
|
81
82
|
if ((point.x > this.canvas.width ||
|
|
82
83
|
point.y > this.canvas.height ||
|
|
83
|
-
point.x < 0 || point.y < 0)) return
|
|
84
|
+
point.x < 0 || point.y < 0)) return;*/
|
|
84
85
|
const key = `${item.strokeStyle ?? ''}_${item.lineWidth ??
|
|
85
86
|
''}_${item.fillStyle ?? ''}`;
|
|
86
87
|
const regionKey = `${item.strokeStyle ?? ''}_${item.lineWidth ?? ''}`;
|
|
@@ -133,11 +134,12 @@ export class Shape extends ViewerCommon {
|
|
|
133
134
|
regionLabelList.forEach((item) => {
|
|
134
135
|
if (item.show === false) return;
|
|
135
136
|
if (!this[item.tool]) return;
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
point.
|
|
140
|
-
|
|
137
|
+
if (!this.isInCanvas(item.region)) return;
|
|
138
|
+
/* const point = this.imageToViewerElementCoordinates(item.points[0].x,
|
|
139
|
+
item.points[0].y);
|
|
140
|
+
if ((point.x > this.canvas.width ||
|
|
141
|
+
point.y > this.canvas.height ||
|
|
142
|
+
point.x < 0 || point.y < 0)) return;*/
|
|
141
143
|
this.combination.setContent(this.canvas, item);
|
|
142
144
|
this.combination.draw({
|
|
143
145
|
points: this.imageToViewerElementPoints(item.points),
|
|
@@ -219,10 +219,11 @@ export class Tailoring extends ViewerCommon {
|
|
|
219
219
|
* @param {Object} e
|
|
220
220
|
*/
|
|
221
221
|
onCanvasKey(e) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
222
|
+
if (this.isInTailoring) {
|
|
223
|
+
const {originalEvent} = e;
|
|
224
|
+
if (originalEvent.code === 'Escape') {
|
|
225
|
+
this.stopTailoring();
|
|
226
|
+
}
|
|
226
227
|
}
|
|
227
228
|
}
|
|
228
229
|
|
package/src/tool/Polygon.js
CHANGED
|
@@ -16,7 +16,8 @@ class Polygon extends Brush {
|
|
|
16
16
|
ctx.lineWidth = this.options.lineWidth;
|
|
17
17
|
ctx.strokeStyle = this.options.strokeStyle;
|
|
18
18
|
ctx.moveTo(points[0].x, points[0].y);
|
|
19
|
-
points.forEach((point) => {
|
|
19
|
+
points.forEach((point, index) => {
|
|
20
|
+
if (index === 0) return;
|
|
20
21
|
ctx.lineTo(point.x, point.y);
|
|
21
22
|
});
|
|
22
23
|
if (this.options.isClose) {
|
|
@@ -26,6 +27,15 @@ class Polygon extends Brush {
|
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
}
|
|
30
|
+
|
|
31
|
+
drawPoints(points) {
|
|
32
|
+
points.forEach((point) => {
|
|
33
|
+
this.thumb.draw(point, {
|
|
34
|
+
thumbRadius: this.options.thumbRadius ?? 5,
|
|
35
|
+
strokeStyle: this.options.thumbColor,
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
29
39
|
}
|
|
30
40
|
|
|
31
41
|
export {
|
package/src/view.js
CHANGED
|
@@ -309,16 +309,21 @@ function initEvent(kv) {
|
|
|
309
309
|
const {originalEvent} = e;
|
|
310
310
|
handlerCacheEvent(originalEvent, kv);
|
|
311
311
|
handlerLabelEvent(originalEvent, kv);
|
|
312
|
-
kv.shape?.onCanvasKey?.(e);
|
|
313
312
|
kv.area?.onCanvasKey?.(e);
|
|
313
|
+
kv.shape?.onCanvasKey?.(e);
|
|
314
314
|
kv.board?.onCanvasKey?.(e);
|
|
315
315
|
kv.tailoring?.onCanvasKey?.(e);
|
|
316
316
|
kv.rotation?.onCanvasKey?.(e);
|
|
317
317
|
}, 100));
|
|
318
318
|
|
|
319
319
|
kv.viewer.addHandler('canvas-double-click', (e) => {
|
|
320
|
-
kv.
|
|
321
|
-
|
|
320
|
+
if (kv.board?.isInDraw) {
|
|
321
|
+
kv.board.onCanvasDblClick(e.position);
|
|
322
|
+
} else if (kv.tailoring?.isInTailoring) {
|
|
323
|
+
kv.tailoring?.onCanvasDblClick?.(e.position);
|
|
324
|
+
} else {
|
|
325
|
+
kv.area?.onCanvasDblClick?.(e.position);
|
|
326
|
+
}
|
|
322
327
|
});
|
|
323
328
|
|
|
324
329
|
kv.viewer.addHandler('resize', (e) => {
|
|
@@ -331,6 +336,43 @@ function initEvent(kv) {
|
|
|
331
336
|
kv.board.onCanvasMove(e);
|
|
332
337
|
}
|
|
333
338
|
}, true, kv.$el);
|
|
339
|
+
|
|
340
|
+
let isRightDown = false;
|
|
341
|
+
let dragPosition;
|
|
342
|
+
|
|
343
|
+
kv.viewer.canvas.addEventListener('contextmenu', function(event) {
|
|
344
|
+
if (kv.board?.isInDraw) {
|
|
345
|
+
event.preventDefault();
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
kv.viewer.addHandler('canvas-nonprimary-press', function(e) {
|
|
350
|
+
console.log('nonprimary press');
|
|
351
|
+
if (e.button === 2) {
|
|
352
|
+
isRightDown = true;
|
|
353
|
+
}
|
|
354
|
+
dragPosition = e.position.clone();
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
kv.viewer.addHandler('canvas-nonprimary-release', function(e) {
|
|
358
|
+
console.log('nonprimary release');
|
|
359
|
+
if (e.button === 2) {
|
|
360
|
+
isRightDown = false;
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
new openSeadragon.MouseTracker({
|
|
365
|
+
element: kv.viewer.canvas,
|
|
366
|
+
moveHandler: function(event) {
|
|
367
|
+
if (isRightDown && kv.board?.isInDraw) {
|
|
368
|
+
console.log('nonprimary drag');
|
|
369
|
+
let delta = event.position.minus(dragPosition);
|
|
370
|
+
dragPosition = event.position.clone();
|
|
371
|
+
kv.viewer.viewport.panBy(
|
|
372
|
+
kv.viewer.viewport.deltaPointsFromPixels(delta.negate()));
|
|
373
|
+
}
|
|
374
|
+
},
|
|
375
|
+
});
|
|
334
376
|
}
|
|
335
377
|
|
|
336
378
|
function handlerCacheEvent(e, kv) {
|