kfb-view 2.2.2 → 2.2.5
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 +98 -84
- package/config/webpack.dev.conf.js +2 -1
- package/example/index.js +23 -5
- package/lib/kfb-view.js +1 -1
- package/package.json +1 -1
- package/src/components/area/index.js +14 -4
- package/src/components/board/index.js +31 -33
- package/src/components/common/common.js +24 -7
- package/src/components/graduation/index.js +9 -19
- package/src/components/grid/index.js +120 -0
- package/src/components/index.js +1 -0
- package/src/components/navigator/index.js +6 -4
- package/src/components/shape/index.js +9 -3
- package/src/const/component.js +1 -0
- package/src/const/mark.js +3 -1
- package/src/model/label.model.js +9 -0
- package/src/tool/Brush.js +13 -8
- package/src/tool/Image.js +41 -0
- package/src/tool/Polygon.js +0 -6
- package/src/tool/index.js +1 -0
- package/src/view.js +20 -1
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
LINE_TYPES, MARKS,
|
|
7
7
|
NO_NORMAL_REGION_TYPES,
|
|
8
8
|
REGION_TYPES,
|
|
9
|
-
STAR,
|
|
9
|
+
STAR, IMAGE,
|
|
10
10
|
} from '../../const/mark';
|
|
11
11
|
import {
|
|
12
12
|
baseNumber, getAngle, getDistance, getPoint,
|
|
@@ -39,6 +39,7 @@ export class Area extends ViewerCommon {
|
|
|
39
39
|
super(viewer, canvas, cache, options);
|
|
40
40
|
this.labelList = [];
|
|
41
41
|
this.movePoint = undefined;
|
|
42
|
+
this.currentPressPoint = undefined;
|
|
42
43
|
this.lastPoint = undefined;
|
|
43
44
|
this.draging = false;
|
|
44
45
|
MARKS.forEach((mark) => {
|
|
@@ -82,12 +83,16 @@ export class Area extends ViewerCommon {
|
|
|
82
83
|
*/
|
|
83
84
|
onCanvasPress({x, y}) {
|
|
84
85
|
this.movePoint = undefined;
|
|
86
|
+
this.currentPressPoint = undefined;
|
|
85
87
|
this.lastPoint = undefined;
|
|
86
88
|
this.draging = false;
|
|
87
89
|
let selectList = [];
|
|
88
90
|
let selectLabel;
|
|
89
91
|
let prevSelectLabel = undefined;
|
|
90
92
|
this.labelList.forEach((item) => {
|
|
93
|
+
if (item.tool === IMAGE) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
91
96
|
if (item.select) {
|
|
92
97
|
prevSelectLabel = item;
|
|
93
98
|
}
|
|
@@ -181,6 +186,7 @@ export class Area extends ViewerCommon {
|
|
|
181
186
|
// moveIndex>-1,表示选中的是图形中可移动的点
|
|
182
187
|
if (~moveIndex) {
|
|
183
188
|
this.movePoint = {position: moveIndex, label: item};
|
|
189
|
+
this.currentPressPoint = {x, y};
|
|
184
190
|
} else if ((item.tool !== POLYGON &&
|
|
185
191
|
isPointInMatrix(pointList[0], pointList[2], pointList[6], pointList[8],
|
|
186
192
|
{x, y})) ||
|
|
@@ -258,10 +264,14 @@ export class Area extends ViewerCommon {
|
|
|
258
264
|
*/
|
|
259
265
|
onCanvasRelease({x, y}) {
|
|
260
266
|
if (this.movePoint && this.options.drag !== false) {
|
|
261
|
-
const
|
|
262
|
-
|
|
267
|
+
const dist = getDistance(this.currentPressPoint, {x, y});
|
|
268
|
+
if (Math.abs(dist) > 1) {
|
|
269
|
+
const label = this.movePoint.label;
|
|
270
|
+
this.$emit(EVENT_AREA_MOVE_END, label);
|
|
271
|
+
}
|
|
263
272
|
}
|
|
264
273
|
this.movePoint = undefined;
|
|
274
|
+
this.currentPressPoint = undefined;
|
|
265
275
|
this.lastPoint = undefined;
|
|
266
276
|
this.draging = false;
|
|
267
277
|
this.change();
|
|
@@ -563,7 +573,7 @@ export class Area extends ViewerCommon {
|
|
|
563
573
|
}
|
|
564
574
|
this[label.tool].setContent(this.canvas, {...label});
|
|
565
575
|
if (label.measure && label.select) {
|
|
566
|
-
this[label.tool].drawMeasureInfo(label,
|
|
576
|
+
this[label.tool].drawMeasureInfo.call(this, label,
|
|
567
577
|
this.getMeasureContent(label), scale);
|
|
568
578
|
}
|
|
569
579
|
}
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
EVENT_IN_PAINTING,
|
|
12
12
|
} from '../../const/event';
|
|
13
13
|
import {
|
|
14
|
+
getDistance,
|
|
14
15
|
pointInOtherPoint,
|
|
15
16
|
pointsToRegion,
|
|
16
17
|
} from '../../util/calculate';
|
|
@@ -148,13 +149,11 @@ export class Board extends ViewerCommon {
|
|
|
148
149
|
const points = this.imageToViewerElementPoints(this.points);
|
|
149
150
|
this[tool].draw(points);
|
|
150
151
|
this[tool].endDraw();
|
|
151
|
-
|
|
152
|
-
this
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
});
|
|
157
|
-
}
|
|
152
|
+
this[tool].drawPoints(points, {
|
|
153
|
+
radius: this.options.thumb.radius,
|
|
154
|
+
strokeStyle: this.options.thumb.color,
|
|
155
|
+
fillStyle: this.options.thumb.bgColor,
|
|
156
|
+
});
|
|
158
157
|
this.$emit(EVENT_START_PAINTING, this.getPaintOptions());
|
|
159
158
|
}
|
|
160
159
|
|
|
@@ -185,13 +184,11 @@ export class Board extends ViewerCommon {
|
|
|
185
184
|
const points = this.imageToViewerElementPoints(this.points);
|
|
186
185
|
this[tool].draw(points);
|
|
187
186
|
this[tool].endDraw();
|
|
188
|
-
|
|
189
|
-
this
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
});
|
|
194
|
-
}
|
|
187
|
+
this[tool].drawPoints(points, {
|
|
188
|
+
radius: this.options.thumb.radius,
|
|
189
|
+
strokeStyle: this.options.thumb.color,
|
|
190
|
+
fillStyle: this.options.thumb.bgColor,
|
|
191
|
+
});
|
|
195
192
|
this.$emit(EVENT_IN_PAINTING, this.getPaintOptions());
|
|
196
193
|
}
|
|
197
194
|
|
|
@@ -209,10 +206,15 @@ export class Board extends ViewerCommon {
|
|
|
209
206
|
return;
|
|
210
207
|
}
|
|
211
208
|
const tool = this.tool;
|
|
212
|
-
if (
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
209
|
+
if (!NO_NORMAL_REGION_TYPES.includes(tool)) {
|
|
210
|
+
const firstPoint = this.imageToViewerElementCoordinates(this.points[0].x,
|
|
211
|
+
this.points[0].y);
|
|
212
|
+
const dist = getDistance(firstPoint, {x, y});
|
|
213
|
+
if (Math.abs(dist) < 10) {
|
|
214
|
+
this.points = [];
|
|
215
|
+
this.clearCanvas();
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
216
218
|
} else if (POINT_TYPES.includes(tool)) {
|
|
217
219
|
this.points = [point, point];
|
|
218
220
|
} else if (tool === POLYGON) {
|
|
@@ -305,13 +307,11 @@ export class Board extends ViewerCommon {
|
|
|
305
307
|
const points = this.imageToViewerElementPoints(this.points);
|
|
306
308
|
this[tool].draw(points);
|
|
307
309
|
this[tool].endDraw();
|
|
308
|
-
|
|
309
|
-
this
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
});
|
|
314
|
-
}
|
|
310
|
+
this[tool].drawPoints(points, {
|
|
311
|
+
radius: this.options.thumb.radius,
|
|
312
|
+
strokeStyle: this.options.thumb.color,
|
|
313
|
+
fillStyle: this.options.thumb.bgColor,
|
|
314
|
+
});
|
|
315
315
|
this.$emit(EVENT_IN_PAINTING, this.getPaintOptions());
|
|
316
316
|
}
|
|
317
317
|
}
|
|
@@ -370,7 +370,7 @@ export class Board extends ViewerCommon {
|
|
|
370
370
|
tool: this.tool,
|
|
371
371
|
});
|
|
372
372
|
if (form.measure) {
|
|
373
|
-
this[this.tool].drawMeasureInfo(form,
|
|
373
|
+
this[this.tool].drawMeasureInfo.call(this, form,
|
|
374
374
|
this.getMeasureContent(form));
|
|
375
375
|
}
|
|
376
376
|
return form;
|
|
@@ -422,13 +422,11 @@ export class Board extends ViewerCommon {
|
|
|
422
422
|
this[this.tool].startDraw();
|
|
423
423
|
this[this.tool].draw(points);
|
|
424
424
|
this[this.tool].endDraw();
|
|
425
|
-
|
|
426
|
-
this
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
});
|
|
431
|
-
}
|
|
425
|
+
this[this.tool].drawPoints(points, {
|
|
426
|
+
radius: this.options.thumb.radius,
|
|
427
|
+
strokeStyle: this.options.thumb.color,
|
|
428
|
+
fillStyle: this.options.thumb.bgColor,
|
|
429
|
+
});
|
|
432
430
|
this.$emit(EVENT_IN_PAINTING, this.getPaintOptions());
|
|
433
431
|
}
|
|
434
432
|
}
|
|
@@ -185,7 +185,7 @@ export class ViewerCommon extends EventEmitter {
|
|
|
185
185
|
left: 0,
|
|
186
186
|
top: 0,
|
|
187
187
|
angle: 0,
|
|
188
|
-
|
|
188
|
+
texts: [],
|
|
189
189
|
};
|
|
190
190
|
if (label.points.length <= 1) return content;
|
|
191
191
|
const scale = this.getImageZoom(true) / label.scale;
|
|
@@ -230,7 +230,7 @@ export class ViewerCommon extends EventEmitter {
|
|
|
230
230
|
left: p.x + distX * scale,
|
|
231
231
|
top: p.y + distY * scale,
|
|
232
232
|
angle: deg,
|
|
233
|
-
|
|
233
|
+
texts: [
|
|
234
234
|
`长:${(Math.sqrt(w * w + h * h) * this.options.imageCapRes).toFixed(
|
|
235
235
|
2)}${this.options.unit}`],
|
|
236
236
|
};
|
|
@@ -250,7 +250,7 @@ export class ViewerCommon extends EventEmitter {
|
|
|
250
250
|
left: p.x + 10 * scale,
|
|
251
251
|
top: p.y,
|
|
252
252
|
angle: 0,
|
|
253
|
-
|
|
253
|
+
texts: [
|
|
254
254
|
`长轴:${(w * this.options.imageCapRes).toFixed(
|
|
255
255
|
2)}${this.options.unit}`,
|
|
256
256
|
`短轴:${(h * this.options.imageCapRes).toFixed(
|
|
@@ -274,7 +274,7 @@ export class ViewerCommon extends EventEmitter {
|
|
|
274
274
|
left: p.x + 10 * scale,
|
|
275
275
|
top: p.y,
|
|
276
276
|
angle: 0,
|
|
277
|
-
|
|
277
|
+
texts: [
|
|
278
278
|
`长:${(w * this.options.imageCapRes).toFixed(
|
|
279
279
|
2)}${this.options.unit}`,
|
|
280
280
|
`宽:${(h * this.options.imageCapRes).toFixed(
|
|
@@ -298,7 +298,7 @@ export class ViewerCommon extends EventEmitter {
|
|
|
298
298
|
left: p.x,
|
|
299
299
|
top: p.y,
|
|
300
300
|
angle: 0,
|
|
301
|
-
|
|
301
|
+
texts: [
|
|
302
302
|
`周长:${(pt * this.options.imageCapRes).toFixed(
|
|
303
303
|
2)}${this.options.unit}`],
|
|
304
304
|
};
|
|
@@ -309,12 +309,17 @@ export class ViewerCommon extends EventEmitter {
|
|
|
309
309
|
left: 0,
|
|
310
310
|
right: 0,
|
|
311
311
|
angle: 0,
|
|
312
|
-
|
|
312
|
+
texts: [],
|
|
313
313
|
};
|
|
314
314
|
}
|
|
315
315
|
break;
|
|
316
316
|
}
|
|
317
|
-
return
|
|
317
|
+
return {
|
|
318
|
+
...content,
|
|
319
|
+
texts: this.options.measure.handler ?
|
|
320
|
+
this.options.measure.handler(content.texts, label) :
|
|
321
|
+
content.texts,
|
|
322
|
+
};
|
|
318
323
|
}
|
|
319
324
|
|
|
320
325
|
/**
|
|
@@ -417,6 +422,18 @@ export class ViewerCommon extends EventEmitter {
|
|
|
417
422
|
|
|
418
423
|
}
|
|
419
424
|
|
|
425
|
+
/**
|
|
426
|
+
* updated
|
|
427
|
+
* @param {Object=} options
|
|
428
|
+
*/
|
|
429
|
+
updated(options = {}) {
|
|
430
|
+
this.options = {
|
|
431
|
+
...this.options,
|
|
432
|
+
...options,
|
|
433
|
+
};
|
|
434
|
+
this.change();
|
|
435
|
+
}
|
|
436
|
+
|
|
420
437
|
/**
|
|
421
438
|
* 清除canvas
|
|
422
439
|
*/
|
|
@@ -15,28 +15,15 @@ export class Graduation extends ViewerCommon {
|
|
|
15
15
|
constructor({viewer, canvas, cache, options}) {
|
|
16
16
|
super(viewer, canvas, cache, options);
|
|
17
17
|
this.scales = options.scales ||
|
|
18
|
-
[0.1, 0.4, 0.6, 1, 2, 4, 8, 10, 20, 40,
|
|
18
|
+
[0.1, 0.4, 0.6, 1, 2, 4, 8, 10, 20, 40, 60, 100, 140, 200];
|
|
19
19
|
this.microns = options.microns ||
|
|
20
|
-
[5000, 2000, 1250, 1000, 500, 250, 200, 100, 50, 25, 10, 5];
|
|
21
|
-
this.init();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* 初始化函数
|
|
26
|
-
*/
|
|
27
|
-
init() {
|
|
28
|
-
this.viewer.addHandler('animation', (res) => {
|
|
29
|
-
this.changeZoom();
|
|
30
|
-
});
|
|
31
|
-
setTimeout(() => {
|
|
32
|
-
this.changeZoom();
|
|
33
|
-
}, 100);
|
|
20
|
+
[5000, 2000, 1250, 1000, 500, 250, 200, 100, 50, 25, 20, 10, 5, 2];
|
|
34
21
|
}
|
|
35
22
|
|
|
36
23
|
/**
|
|
37
24
|
* 倍率大小改变
|
|
38
25
|
*/
|
|
39
|
-
|
|
26
|
+
change() {
|
|
40
27
|
const scales = [...this.scales];
|
|
41
28
|
const zoom = this.viewport.viewportToImageZoom(
|
|
42
29
|
this.viewport.getZoom(true)) * 40;
|
|
@@ -72,6 +59,9 @@ export class Graduation extends ViewerCommon {
|
|
|
72
59
|
const height = this.canvas.height;
|
|
73
60
|
ctx.beginPath();
|
|
74
61
|
ctx.clearRect(0, 0, width, height);
|
|
62
|
+
if (!this.options.show) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
75
65
|
const {left, top, right, bottom} = this.options;
|
|
76
66
|
let x = 10;
|
|
77
67
|
let y = height - 10;
|
|
@@ -88,16 +78,16 @@ export class Graduation extends ViewerCommon {
|
|
|
88
78
|
ctx.beginPath();
|
|
89
79
|
ctx.strokeStyle = '#000000';
|
|
90
80
|
ctx.lineWidth = 3;
|
|
91
|
-
ctx.moveTo(x, y -
|
|
81
|
+
ctx.moveTo(x, y - 8);
|
|
92
82
|
ctx.lineTo(x, y);
|
|
93
83
|
ctx.lineTo(x + lineWidth, y);
|
|
94
|
-
ctx.lineTo(x + lineWidth, y -
|
|
84
|
+
ctx.lineTo(x + lineWidth, y - 8);
|
|
95
85
|
ctx.stroke();
|
|
96
86
|
ctx.beginPath();
|
|
97
87
|
ctx.fillStyle = '#000000';
|
|
98
88
|
ctx.font = 'bold 16px Arial';
|
|
99
89
|
const t = txt.toFixed(0) + this.options.unit;
|
|
100
90
|
const fontWidth = ctx.measureText(t).width;
|
|
101
|
-
ctx.fillText(t, x + lineWidth / 2 - fontWidth / 2, top ? y +
|
|
91
|
+
ctx.fillText(t, x + lineWidth / 2 - fontWidth / 2, top ? y + 12 : y - 12);
|
|
102
92
|
}
|
|
103
93
|
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import {ViewerCommon} from '../common/common';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 网格
|
|
5
|
+
* @class
|
|
6
|
+
*/
|
|
7
|
+
export class Grid extends ViewerCommon {
|
|
8
|
+
/**
|
|
9
|
+
* 初始化视图测量工具
|
|
10
|
+
* @param {Object} viewer
|
|
11
|
+
* @param {Object} canvas
|
|
12
|
+
* @param {Object} cache
|
|
13
|
+
* @param {Object} options
|
|
14
|
+
*/
|
|
15
|
+
constructor({viewer, canvas, cache, options}) {
|
|
16
|
+
super(viewer, canvas, cache, options);
|
|
17
|
+
if (!this.options.scale) {
|
|
18
|
+
this.options.scale = 20;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
change() {
|
|
23
|
+
const imageViewStartPoint = this.viewerElementToImageCoordinates(0, 0);
|
|
24
|
+
const imageViewXEndPoint = this.viewerElementToImageCoordinates(
|
|
25
|
+
this.canvas.width, 0);
|
|
26
|
+
const imageViewYEndPoint = this.viewerElementToImageCoordinates(0,
|
|
27
|
+
this.canvas.height);
|
|
28
|
+
let currentZoom = this.getImageZoom(true) * this.options.scale;
|
|
29
|
+
let baseScale = this.options.scale === 40 ? 3200 : 1600;
|
|
30
|
+
let twoCount = 0;
|
|
31
|
+
if (currentZoom >= 1) {
|
|
32
|
+
while (currentZoom / 2 >= 1) {
|
|
33
|
+
twoCount++;
|
|
34
|
+
currentZoom = currentZoom / 2;
|
|
35
|
+
}
|
|
36
|
+
if (twoCount) {
|
|
37
|
+
baseScale /= Math.pow(2, twoCount);
|
|
38
|
+
}
|
|
39
|
+
} else if (currentZoom < 1) {
|
|
40
|
+
while (currentZoom * 2 <= 1) {
|
|
41
|
+
twoCount++;
|
|
42
|
+
currentZoom = currentZoom * 2;
|
|
43
|
+
}
|
|
44
|
+
if (twoCount) {
|
|
45
|
+
baseScale *= Math.pow(2, twoCount);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const distX = imageViewXEndPoint.distanceTo(imageViewStartPoint);
|
|
49
|
+
const distY = imageViewYEndPoint.distanceTo(imageViewStartPoint);
|
|
50
|
+
const minX = Math.floor(imageViewStartPoint.x / baseScale);
|
|
51
|
+
const maxX = Math.floor((imageViewXEndPoint.x + distX) / baseScale);
|
|
52
|
+
const minY = Math.floor(imageViewStartPoint.y / baseScale);
|
|
53
|
+
const maxY = Math.floor((imageViewYEndPoint.y + distY) / baseScale);
|
|
54
|
+
const ctx = this.canvas.getContext('2d');
|
|
55
|
+
ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
56
|
+
if (this.options.show) {
|
|
57
|
+
ctx.beginPath();
|
|
58
|
+
ctx.lineWidth = 1;
|
|
59
|
+
for (let i = minX; i <= maxX + 1; i++) {
|
|
60
|
+
const point = this.imageToViewerElementCoordinates(i * baseScale, 0);
|
|
61
|
+
ctx.moveTo(point.x, 0);
|
|
62
|
+
ctx.lineTo(point.x, this.canvas.height);
|
|
63
|
+
}
|
|
64
|
+
for (let i = minY; i <= maxY + 1; i++) {
|
|
65
|
+
const point = this.imageToViewerElementCoordinates(0, i * baseScale);
|
|
66
|
+
ctx.moveTo(0, point.y);
|
|
67
|
+
ctx.lineTo(this.canvas.width, point.y);
|
|
68
|
+
}
|
|
69
|
+
ctx.stroke();
|
|
70
|
+
}
|
|
71
|
+
if (this.options.ruler) {
|
|
72
|
+
const basePx = this.imageToViewerElementCoordinates(baseScale, 0).
|
|
73
|
+
minus(this.imageToViewerElementCoordinates(0, 0)).x;
|
|
74
|
+
ctx.beginPath();
|
|
75
|
+
ctx.font = '14px Arial';
|
|
76
|
+
ctx.fillStyle = '#fff';
|
|
77
|
+
ctx.fillRect(0, 0, 20, this.canvas.height);
|
|
78
|
+
ctx.fillRect(0, 0, this.canvas.width, 20);
|
|
79
|
+
ctx.beginPath();
|
|
80
|
+
ctx.fillStyle = 'rgba(0, 0, 0, .3)';
|
|
81
|
+
ctx.strokeStyle = 'rgba(0, 0, 0, .8)';
|
|
82
|
+
ctx.moveTo(20, 20);
|
|
83
|
+
ctx.lineTo(20, this.canvas.height);
|
|
84
|
+
ctx.moveTo(20, 20);
|
|
85
|
+
ctx.lineTo(this.canvas.width, 20);
|
|
86
|
+
for (let i = minX; i <= maxX + 1; i++) {
|
|
87
|
+
const point = this.imageToViewerElementCoordinates(i * baseScale, 0);
|
|
88
|
+
ctx.moveTo(point.x, 0);
|
|
89
|
+
ctx.lineTo(point.x, 20);
|
|
90
|
+
for (let j = 1; j < 5; j++) {
|
|
91
|
+
ctx.moveTo(point.x + (basePx / 5) * j, 16);
|
|
92
|
+
ctx.lineTo(point.x + (basePx / 5) * j, 20);
|
|
93
|
+
if (i !== minX) {
|
|
94
|
+
ctx.fillText(i * baseScale, point.x + 5, 13);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
for (let i = minY; i <= maxY + 1; i++) {
|
|
99
|
+
const point = this.imageToViewerElementCoordinates(0, i * baseScale);
|
|
100
|
+
ctx.moveTo(0, point.y);
|
|
101
|
+
ctx.lineTo(20, point.y);
|
|
102
|
+
for (let j = 1; j < 5; j++) {
|
|
103
|
+
ctx.moveTo(16, point.y + (basePx / 5) * j);
|
|
104
|
+
ctx.lineTo(20, point.y + (basePx / 5) * j);
|
|
105
|
+
if (i !== minY) {
|
|
106
|
+
ctx.save();
|
|
107
|
+
ctx.translate(3, point.y + 5);
|
|
108
|
+
ctx.rotate(Math.PI / 2);
|
|
109
|
+
ctx.fillText(i * baseScale, 0, 0);
|
|
110
|
+
ctx.restore();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
ctx.stroke();
|
|
115
|
+
ctx.beginPath();
|
|
116
|
+
ctx.fillStyle = '#fff';
|
|
117
|
+
ctx.fillRect(0, 0, 20, 20);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
package/src/components/index.js
CHANGED
|
@@ -81,6 +81,7 @@ export class Navigator extends EventEmitter {
|
|
|
81
81
|
top: top,
|
|
82
82
|
width: rect.clientWidth,
|
|
83
83
|
height: rect.clientHeight,
|
|
84
|
+
scale: [...this.vestige.zooms].reverse()[index],
|
|
84
85
|
color: [...this.vestige.colors].reverse()[index],
|
|
85
86
|
};
|
|
86
87
|
this.pointList.push(rectObj);
|
|
@@ -104,9 +105,10 @@ export class Navigator extends EventEmitter {
|
|
|
104
105
|
const colorCanvas = this.element.getElementsByClassName(
|
|
105
106
|
'navigator-color-rect')[0];
|
|
106
107
|
const ctx = colorCanvas.getContext('2d');
|
|
107
|
-
this.pointList.
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
this.pointList.sort((a, b) => a.scale > b.scale ? 1 : -1).
|
|
109
|
+
forEach((item) => {
|
|
110
|
+
this.drawRect(ctx, item);
|
|
111
|
+
});
|
|
110
112
|
}
|
|
111
113
|
|
|
112
114
|
/**
|
|
@@ -301,7 +303,7 @@ export class Navigator extends EventEmitter {
|
|
|
301
303
|
if (this.clearTimeId) window.clearTimeout(this.clearTimeId);
|
|
302
304
|
const currentImageZoom = this.viewport.viewportToImageZoom(currentZoom);
|
|
303
305
|
const index = [...this.vestige.zooms].reverse().findIndex(
|
|
304
|
-
(z) => currentImageZoom
|
|
306
|
+
(z) => currentImageZoom >= (z / (this.options.scale || 40)));
|
|
305
307
|
if (index !== -1) {
|
|
306
308
|
this.clearTimeId = window.setTimeout(() => {
|
|
307
309
|
this.$emit('rect-draw', index);
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
-
HAS_REGION_TYPES,
|
|
2
|
+
HAS_REGION_TYPES, IMAGE,
|
|
3
3
|
MARKS, NO_NORMAL_REGION_TYPES, POINT_TYPES, POLYGON, REGION_TYPES,
|
|
4
4
|
} from '../../const/mark';
|
|
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';
|
|
10
8
|
|
|
11
9
|
/**
|
|
12
10
|
* 用来显示标注线的canvas
|
|
@@ -70,7 +68,12 @@ export class Shape extends ViewerCommon {
|
|
|
70
68
|
// strokeStyle, lineWidth, fillStyle 相同认为是一个路径下的图形,一起绘制,优化性能
|
|
71
69
|
const sameFixWidthLabel = {}; // star, flag, star, font lineWidth固定为2
|
|
72
70
|
const sameNormalLabel = {};
|
|
71
|
+
const imageLabel = [];
|
|
73
72
|
labelList.forEach((item) => {
|
|
73
|
+
if (item.tool === IMAGE) {
|
|
74
|
+
imageLabel.push(item);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
74
77
|
const key = `${item.strokeStyle ?? ''}_${item.lineWidth ??
|
|
75
78
|
''}_${item.fillStyle ?? ''}`;
|
|
76
79
|
const regionKey = `${item.strokeStyle ?? ''}_${item.lineWidth ?? ''}`;
|
|
@@ -111,6 +114,9 @@ export class Shape extends ViewerCommon {
|
|
|
111
114
|
tool,
|
|
112
115
|
})), this.viewport.getRotation());
|
|
113
116
|
});
|
|
117
|
+
imageLabel.forEach((item) => {
|
|
118
|
+
this.drawLabel(item);
|
|
119
|
+
});
|
|
114
120
|
}
|
|
115
121
|
|
|
116
122
|
deepDrawLabel(sameFixWidthLabel, sameNormalLabel, count, bounds) {
|
package/src/const/component.js
CHANGED
package/src/const/mark.js
CHANGED
|
@@ -8,6 +8,7 @@ export const FONT = 'Font';
|
|
|
8
8
|
export const STAR = 'Star';
|
|
9
9
|
export const FLAG = 'Flag';
|
|
10
10
|
export const DOT = 'Dot';
|
|
11
|
+
export const IMAGE = 'Image';
|
|
11
12
|
|
|
12
13
|
export const POINT_TYPES = [FONT, STAR, FLAG, DOT];
|
|
13
14
|
export const REGION_TYPES = [RECTANGLE, ELLIPSE];
|
|
@@ -24,4 +25,5 @@ export const MARKS = [
|
|
|
24
25
|
FONT,
|
|
25
26
|
STAR,
|
|
26
27
|
FLAG,
|
|
27
|
-
DOT
|
|
28
|
+
DOT,
|
|
29
|
+
IMAGE];
|
package/src/model/label.model.js
CHANGED
|
@@ -17,6 +17,7 @@ export class LabelModel {
|
|
|
17
17
|
this.measure = data.measure; // 是否显示测量信息
|
|
18
18
|
this.points = data.points; // 绘制点
|
|
19
19
|
this.tool = data.tool; // 绘制工具
|
|
20
|
+
this.src = data.src; // 图片地址
|
|
20
21
|
this.scale = data.scale; // 绘制倍率
|
|
21
22
|
this.region = data.region; // 绘制区域
|
|
22
23
|
this.move = data.move; // 是否可移动
|
|
@@ -27,5 +28,13 @@ export class LabelModel {
|
|
|
27
28
|
this.show = data.show ?? true; // 是否显示
|
|
28
29
|
this.__other__ = data.__other__ || {}; // 其他信息
|
|
29
30
|
this.__data__ = data.__data__ ?? data; // 记录原始数据
|
|
31
|
+
if (this.src) {
|
|
32
|
+
this.img = new Image();
|
|
33
|
+
this.img.src = this.src;
|
|
34
|
+
this.imgLoadSuccess = false;
|
|
35
|
+
this.img.onload = () => {
|
|
36
|
+
this.imgLoadSuccess = true;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
30
39
|
}
|
|
31
40
|
}
|
package/src/tool/Brush.js
CHANGED
|
@@ -46,6 +46,12 @@ class Brush {
|
|
|
46
46
|
this.thumb.draw(point, config);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
drawPoints(points, config) {
|
|
50
|
+
points.forEach((point) => {
|
|
51
|
+
this.drawThumb(point, config);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
49
55
|
/**
|
|
50
56
|
* 画笔具体操作
|
|
51
57
|
* @param {Object[]} points - 绘制的点
|
|
@@ -62,27 +68,26 @@ class Brush {
|
|
|
62
68
|
* @param {number} [scale=1]
|
|
63
69
|
*/
|
|
64
70
|
drawMeasureInfo(label, info, scale = 1) {
|
|
65
|
-
const {left, top,
|
|
71
|
+
const {left, top, texts, angle} = info;
|
|
66
72
|
const ctx = this.canvas.getContext('2d');
|
|
67
73
|
ctx.save();
|
|
68
74
|
ctx.beginPath();
|
|
69
75
|
ctx.translate(left, top);
|
|
70
76
|
ctx.rotate(angle);
|
|
71
77
|
ctx.scale(scale, scale);
|
|
72
|
-
ctx.font = `14px Arial`;
|
|
73
78
|
const widthList = [];
|
|
74
|
-
|
|
79
|
+
ctx.font = `${this.options.measure.fontSize}px Arial`;
|
|
80
|
+
texts.forEach((info) => {
|
|
75
81
|
widthList.push(ctx.measureText(info).width);
|
|
76
82
|
});
|
|
77
83
|
const width = Math.max(...widthList);
|
|
78
|
-
ctx.fillStyle =
|
|
79
|
-
const height =
|
|
84
|
+
ctx.fillStyle = this.options.measure.backgroundColor;
|
|
85
|
+
const height = texts.length * 20 + 16 + (texts.length - 1) * 4;
|
|
80
86
|
ctx.rect(0, 0, width + 22, height);
|
|
81
87
|
ctx.fill();
|
|
82
88
|
ctx.beginPath();
|
|
83
|
-
ctx.
|
|
84
|
-
|
|
85
|
-
content.forEach((info, index) => {
|
|
89
|
+
ctx.fillStyle = this.options.measure.color;
|
|
90
|
+
texts.forEach((info, index) => {
|
|
86
91
|
ctx.fillText(info, 11, 8 + 14 + index * 24);
|
|
87
92
|
});
|
|
88
93
|
ctx.fill();
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {Brush} from './Brush';
|
|
2
|
+
import {pointsToRegion} from '../util/calculate';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 线段类
|
|
6
|
+
* @class
|
|
7
|
+
*/
|
|
8
|
+
class Image extends Brush {
|
|
9
|
+
/**
|
|
10
|
+
* 初始化数据
|
|
11
|
+
*/
|
|
12
|
+
constructor() {
|
|
13
|
+
super();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 画线
|
|
18
|
+
* @param {Object[]} points - 绘制的点
|
|
19
|
+
* @param {number} points[].x - 绘制的点x坐标
|
|
20
|
+
* @param {number} points[].y - 绘制的点y坐标
|
|
21
|
+
* @param {number=} scale
|
|
22
|
+
*/
|
|
23
|
+
draw(points, scale = 1) {
|
|
24
|
+
const region = pointsToRegion(points);
|
|
25
|
+
const ctx = this.canvas.getContext('2d');
|
|
26
|
+
const drawImage = () => {
|
|
27
|
+
ctx.drawImage(this.options.img, region.x, region.y, region.width,
|
|
28
|
+
region.height);
|
|
29
|
+
this.options.img.removeEventListener('load', drawImage);
|
|
30
|
+
};
|
|
31
|
+
if (this.options.imgLoadSuccess) {
|
|
32
|
+
drawImage();
|
|
33
|
+
} else if (this.options.img) {
|
|
34
|
+
this.options.img.addEventListener('load', drawImage);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export {
|
|
40
|
+
Image,
|
|
41
|
+
};
|
package/src/tool/Polygon.js
CHANGED
package/src/tool/index.js
CHANGED