kfb-view 3.2.5 → 3.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/kfb-view.js +1 -1
- package/package.json +1 -1
- package/src/components/common/common.js +17 -11
- package/src/components/grid/index.js +3 -2
- package/src/components/locale/index.js +7 -0
- package/src/components/locale/lang/en.js +12 -0
- package/src/components/locale/lang/zh-cn.js +12 -0
- package/src/components/tailoring/index.js +48 -29
- package/src/util/canvas.js +53 -0
- package/src/view.js +2 -0
package/package.json
CHANGED
|
@@ -18,6 +18,8 @@ import {
|
|
|
18
18
|
RECTANGLE,
|
|
19
19
|
} from '../../const/mark';
|
|
20
20
|
|
|
21
|
+
import locale from '../locale';
|
|
22
|
+
|
|
21
23
|
/**
|
|
22
24
|
* 通用方法类
|
|
23
25
|
* @class
|
|
@@ -202,6 +204,10 @@ export class ViewerCommon {
|
|
|
202
204
|
this.viewport.getZoom(current));
|
|
203
205
|
}
|
|
204
206
|
|
|
207
|
+
translate(key) {
|
|
208
|
+
return locale[(this.options.lang ?? 'zh-cn').toLocaleLowerCase()][key];
|
|
209
|
+
}
|
|
210
|
+
|
|
205
211
|
getMeasureContent(label) {
|
|
206
212
|
let content = {
|
|
207
213
|
left: 0,
|
|
@@ -245,7 +251,7 @@ export class ViewerCommon {
|
|
|
245
251
|
top: p.y,
|
|
246
252
|
angle: 0,
|
|
247
253
|
texts: [
|
|
248
|
-
|
|
254
|
+
`${this.translate('length')}:${this.getUnitNumber(Math.sqrt(w * w + h * h) * this.options.imageCapRes)}`],
|
|
249
255
|
};
|
|
250
256
|
}
|
|
251
257
|
break;
|
|
@@ -262,10 +268,10 @@ export class ViewerCommon {
|
|
|
262
268
|
top: p.y,
|
|
263
269
|
angle: 0,
|
|
264
270
|
texts: [
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
271
|
+
`${this.translate('long_axis')}:${this.getUnitNumber(a)}`,
|
|
272
|
+
`${this.translate('short_axis')}:${this.getUnitNumber(b)}`,
|
|
273
|
+
`${this.translate('perimeter')}:${this.getUnitNumber(4 * (a - b) + 2 * Math.PI * b)}`,
|
|
274
|
+
`${this.translate('area')}:${this.getUnitNumber(Math.PI * a * b / this.options.binary)}²`],
|
|
269
275
|
};
|
|
270
276
|
}
|
|
271
277
|
break;
|
|
@@ -282,10 +288,10 @@ export class ViewerCommon {
|
|
|
282
288
|
top: p.y,
|
|
283
289
|
angle: 0,
|
|
284
290
|
texts: [
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
291
|
+
`${this.translate('length')}:${this.getUnitNumber(w)}`,
|
|
292
|
+
`${this.translate('width')}:${this.getUnitNumber(h)}`,
|
|
293
|
+
`${this.translate('perimeter')}:${this.getUnitNumber(pt)}`,
|
|
294
|
+
`${this.translate('area')}:${this.getUnitNumber(ac)}²`],
|
|
289
295
|
};
|
|
290
296
|
}
|
|
291
297
|
break;
|
|
@@ -304,8 +310,8 @@ export class ViewerCommon {
|
|
|
304
310
|
top: p.y,
|
|
305
311
|
angle: 0,
|
|
306
312
|
texts: [
|
|
307
|
-
|
|
308
|
-
|
|
313
|
+
`${this.translate('perimeter')}:${this.getUnitNumber((pt * this.options.imageCapRes).toFixed(2))}`,
|
|
314
|
+
`${this.translate('area')}:${this.getUnitNumber(
|
|
309
315
|
calculatePolygonArea(points, this.options.imageCapRes) / this.options.binary)}²`],
|
|
310
316
|
};
|
|
311
317
|
}
|
|
@@ -28,6 +28,7 @@ export class Grid extends ViewerCommon {
|
|
|
28
28
|
let currentZoom = this.getImageZoom(true) * this.options.scale;
|
|
29
29
|
const pxConversion = this.options.pxConversion ?
|
|
30
30
|
this.options.imageCapRes : 1;
|
|
31
|
+
const binary = Math.pow(this.options.binary, this.options.unitsIndex || 0);
|
|
31
32
|
let baseScale = this.options.scale === 40 ?
|
|
32
33
|
(this.options.pxConversion ? 1600 / this.options.imageCapRes : 3200) :
|
|
33
34
|
(this.options.pxConversion ? 800 / this.options.imageCapRes : 1600);
|
|
@@ -95,7 +96,7 @@ export class Grid extends ViewerCommon {
|
|
|
95
96
|
ctx.moveTo(point.x + (basePx / 5) * j, 16);
|
|
96
97
|
ctx.lineTo(point.x + (basePx / 5) * j, 20);
|
|
97
98
|
if (i !== minX) {
|
|
98
|
-
ctx.fillText((i * baseScale * pxConversion).toFixed(
|
|
99
|
+
ctx.fillText((i * baseScale * pxConversion / binary).toFixed(2) / 1, point.x + 5,
|
|
99
100
|
13);
|
|
100
101
|
}
|
|
101
102
|
}
|
|
@@ -111,7 +112,7 @@ export class Grid extends ViewerCommon {
|
|
|
111
112
|
ctx.save();
|
|
112
113
|
ctx.translate(3, point.y + 5);
|
|
113
114
|
ctx.rotate(Math.PI / 2);
|
|
114
|
-
ctx.fillText((i * baseScale * pxConversion).toFixed(0), 0, 0);
|
|
115
|
+
ctx.fillText((i * baseScale * pxConversion / binary).toFixed(0), 0, 0);
|
|
115
116
|
ctx.restore();
|
|
116
117
|
}
|
|
117
118
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
length: 'Length',
|
|
3
|
+
width: 'Width',
|
|
4
|
+
perimeter: 'Perimeter',
|
|
5
|
+
area: 'Area',
|
|
6
|
+
long_axis: 'Long Axis',
|
|
7
|
+
short_axis: 'Short Axis',
|
|
8
|
+
complete_screenshot: 'Double-click within the area to complete screenshot',
|
|
9
|
+
cancel_screenshot: 'Double-click outside or press ESC to cancel screenshot',
|
|
10
|
+
area_size: 'Area size is ',
|
|
11
|
+
drag_resize: 'drag resize',
|
|
12
|
+
};
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
pointInOtherPoint,
|
|
9
9
|
isPointInMatrix,
|
|
10
10
|
} from '../../util/calculate';
|
|
11
|
+
import {Point, Rect} from '../../plugin/openseadragon/openseadragon';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* 用来裁剪/截图
|
|
@@ -57,21 +58,13 @@ export class Tailoring extends ViewerCommon {
|
|
|
57
58
|
pointList[6],
|
|
58
59
|
pointList[8]];
|
|
59
60
|
if (now) {
|
|
60
|
-
this.
|
|
61
|
-
this.mitt.$emit(EVENT_TAILORING_SCREENSHOT, {
|
|
62
|
-
base64: this.getScreenCanvasImage(),
|
|
63
|
-
region: this.viewerElementToImageRectangle({
|
|
64
|
-
x: this.tailoringPoints[0].x, y: this.tailoringPoints[0].y,
|
|
65
|
-
width: this.tailoringPoints[3].x - this.tailoringPoints[0].x,
|
|
66
|
-
height: this.tailoringPoints[3].y - this.tailoringPoints[0].y,
|
|
67
|
-
}),
|
|
68
|
-
});
|
|
61
|
+
this.emitScreenShot();
|
|
69
62
|
this.stopTailoring();
|
|
70
63
|
} else {
|
|
71
64
|
this.color = color || '#FFF';
|
|
72
65
|
this.contents = contents?.length ?
|
|
73
66
|
contents :
|
|
74
|
-
[
|
|
67
|
+
[];
|
|
75
68
|
this.change();
|
|
76
69
|
}
|
|
77
70
|
}
|
|
@@ -136,17 +129,28 @@ export class Tailoring extends ViewerCommon {
|
|
|
136
129
|
ctx.font = '18px Arial';
|
|
137
130
|
const width = (rightTop.x - leftTop.x).toFixed(2) / 1;
|
|
138
131
|
const height = (rightBottom.y - rightTop.y).toFixed(2) / 1;
|
|
139
|
-
ctx.fillText(
|
|
140
|
-
this.contents
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
ctx.fillText(this.contents?.[0] ?? `双击区域内表示完成截图`, leftTop.x,
|
|
145
|
-
leftTop.y - 30);
|
|
146
|
-
ctx.fillText(this.contents?.[1] ?? `双击区域外或按ESC表示取消截图`,
|
|
147
|
-
leftTop.x,
|
|
148
|
-
leftTop.y - 10);
|
|
132
|
+
ctx.fillText(this.contents?.[2] ?
|
|
133
|
+
this.contents[2](width, height) :
|
|
134
|
+
(`${this.translate('area_size')}${width}*${height},${this.translate('drag_resize')}`), leftTop.x, leftTop.y - 50);
|
|
135
|
+
ctx.fillText(this.contents?.[0] ?? `${this.translate('complete_screenshot')}`, leftTop.x, leftTop.y - 30);
|
|
136
|
+
ctx.fillText(this.contents?.[1] ?? `${this.translate('cancel_screenshot')}`, leftTop.x, leftTop.y - 10);
|
|
149
137
|
ctx.stroke();
|
|
138
|
+
ctx.beginPath();
|
|
139
|
+
ctx.fillStyle = '#000000';
|
|
140
|
+
ctx.rect(rightTop.x + 4, rightTop.y, 100, 40);
|
|
141
|
+
ctx.fill();
|
|
142
|
+
ctx.save();
|
|
143
|
+
ctx.beginPath();
|
|
144
|
+
ctx.translate(rightTop.x + 54, rightTop.y - 5);
|
|
145
|
+
ctx.fillStyle = '#ffffff';
|
|
146
|
+
ctx.drawConfirm();
|
|
147
|
+
ctx.restore();
|
|
148
|
+
ctx.save();
|
|
149
|
+
ctx.beginPath();
|
|
150
|
+
ctx.translate(rightTop.x + 4, rightTop.y - 5);
|
|
151
|
+
ctx.fillStyle = '#ffffff';
|
|
152
|
+
ctx.drawCancel();
|
|
153
|
+
ctx.restore();
|
|
150
154
|
}
|
|
151
155
|
|
|
152
156
|
/**
|
|
@@ -158,6 +162,17 @@ export class Tailoring extends ViewerCommon {
|
|
|
158
162
|
onCanvasPress({x, y}) {
|
|
159
163
|
this.movePointIndex = this.tailoringPoints.findIndex(
|
|
160
164
|
(point) => pointInOtherPoint(point, {x, y}, 30));
|
|
165
|
+
const rightTopPoint = this.tailoringPoints[1];
|
|
166
|
+
const cancelArea = new Rect(rightTopPoint.x + 14, rightTopPoint.y, 30, 40);
|
|
167
|
+
const confirmArea = new Rect(rightTopPoint.x + 64, rightTopPoint.y, 30, 40);
|
|
168
|
+
const point = new Point(x, y);
|
|
169
|
+
if (cancelArea.containsPoint(point)) {
|
|
170
|
+
this.stopTailoring();
|
|
171
|
+
}
|
|
172
|
+
if (confirmArea.containsPoint(point)) {
|
|
173
|
+
this.emitScreenShot();
|
|
174
|
+
this.stopTailoring();
|
|
175
|
+
}
|
|
161
176
|
}
|
|
162
177
|
|
|
163
178
|
/**
|
|
@@ -262,19 +277,23 @@ export class Tailoring extends ViewerCommon {
|
|
|
262
277
|
|
|
263
278
|
onCanvasDblClick(position) {
|
|
264
279
|
if (this.tailoringPoints.length > 0 && this.isPointInMatrix(position)) {
|
|
265
|
-
this.
|
|
266
|
-
this.mitt.$emit(EVENT_TAILORING_SCREENSHOT, {
|
|
267
|
-
base64: this.getScreenCanvasImage(),
|
|
268
|
-
region: this.viewerElementToImageRectangle({
|
|
269
|
-
x: this.tailoringPoints[0].x, y: this.tailoringPoints[0].y,
|
|
270
|
-
width: this.tailoringPoints[3].x - this.tailoringPoints[0].x,
|
|
271
|
-
height: this.tailoringPoints[3].y - this.tailoringPoints[0].y,
|
|
272
|
-
}),
|
|
273
|
-
});
|
|
280
|
+
this.emitScreenShot();
|
|
274
281
|
}
|
|
275
282
|
this.stopTailoring();
|
|
276
283
|
}
|
|
277
284
|
|
|
285
|
+
emitScreenShot() {
|
|
286
|
+
this.emitTailoringRegion();
|
|
287
|
+
this.mitt.$emit(EVENT_TAILORING_SCREENSHOT, {
|
|
288
|
+
base64: this.getScreenCanvasImage(),
|
|
289
|
+
region: this.viewerElementToImageRectangle({
|
|
290
|
+
x: this.tailoringPoints[0].x, y: this.tailoringPoints[0].y,
|
|
291
|
+
width: this.tailoringPoints[3].x - this.tailoringPoints[0].x,
|
|
292
|
+
height: this.tailoringPoints[3].y - this.tailoringPoints[0].y,
|
|
293
|
+
}),
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
|
|
278
297
|
/**
|
|
279
298
|
* 判断鼠标在区域内
|
|
280
299
|
* @param {Object} point 鼠标位置
|
package/src/util/canvas.js
CHANGED
|
@@ -192,3 +192,56 @@ CanvasRenderingContext2D.prototype.bezierCurve = function(...rest) {
|
|
|
192
192
|
};
|
|
193
193
|
|
|
194
194
|
|
|
195
|
+
CanvasRenderingContext2D.prototype.drawConfirm = function drawConfirm() {
|
|
196
|
+
this.save();
|
|
197
|
+
this.miterLimit = 4;
|
|
198
|
+
this.scale(0.046875, 0.046875);
|
|
199
|
+
this.save();
|
|
200
|
+
this.beginPath();
|
|
201
|
+
this.moveTo(836.266667, 311.466667);
|
|
202
|
+
this.lineTo(806.4, 281.59999999999997);
|
|
203
|
+
this.bezierCurveTo(797.866667, 273.06666699999994, 785.0666669999999, 273.06666699999994, 776.533333,
|
|
204
|
+
281.59999999999997);
|
|
205
|
+
this.lineTo(435.2, 622.933333);
|
|
206
|
+
this.bezierCurveTo(430.933333, 627.1999999999999, 430.933333, 627.1999999999999, 426.66666699999996, 622.933333);
|
|
207
|
+
this.lineTo(264.53333399999997, 460.79999999999995);
|
|
208
|
+
this.bezierCurveTo(256.00000099999994, 452.2666669999999, 243.20000099999996, 452.2666669999999, 234.66666699999996,
|
|
209
|
+
460.79999999999995);
|
|
210
|
+
this.lineTo(204.79999999999995, 490.66666699999996);
|
|
211
|
+
this.bezierCurveTo(196.26666699999996, 499.2, 196.26666699999996, 511.99999999999994, 204.79999999999995, 520.533334);
|
|
212
|
+
this.lineTo(422.4, 738.133334);
|
|
213
|
+
this.bezierCurveTo(426.66666699999996, 742.400001, 435.2, 742.400001, 439.466667, 738.133334);
|
|
214
|
+
this.lineTo(836.266667, 341.333333);
|
|
215
|
+
this.bezierCurveTo(844.8, 332.8, 844.8, 320, 836.266667, 311.466667);
|
|
216
|
+
this.closePath();
|
|
217
|
+
this.fill();
|
|
218
|
+
this.stroke();
|
|
219
|
+
this.restore();
|
|
220
|
+
this.restore();
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
CanvasRenderingContext2D.prototype.drawCancel = function drawCancel() {
|
|
224
|
+
this.save();
|
|
225
|
+
this.miterLimit = 4;
|
|
226
|
+
this.scale(0.046875, 0.046875);
|
|
227
|
+
this.save();
|
|
228
|
+
this.beginPath();
|
|
229
|
+
this.moveTo(768, 307.552);
|
|
230
|
+
this.lineTo(716.448, 256);
|
|
231
|
+
this.lineTo(512, 460.448);
|
|
232
|
+
this.lineTo(307.552, 256);
|
|
233
|
+
this.lineTo(256, 307.552);
|
|
234
|
+
this.lineTo(460.448, 512);
|
|
235
|
+
this.lineTo(256, 716.448);
|
|
236
|
+
this.lineTo(307.552, 768);
|
|
237
|
+
this.lineTo(512, 563.552);
|
|
238
|
+
this.lineTo(716.448, 768);
|
|
239
|
+
this.lineTo(768, 716.448);
|
|
240
|
+
this.lineTo(563.552, 512);
|
|
241
|
+
this.lineTo(768, 307.552);
|
|
242
|
+
this.closePath();
|
|
243
|
+
this.fill();
|
|
244
|
+
this.stroke();
|
|
245
|
+
this.restore();
|
|
246
|
+
this.restore();
|
|
247
|
+
};
|
package/src/view.js
CHANGED
|
@@ -86,6 +86,7 @@ export default class KfbView extends EventEmitter {
|
|
|
86
86
|
* @param {function=} config.labelDrawing 标注绘制回调 @deprecated Use label.drawing instead
|
|
87
87
|
* @param {array} config.labelList 标注列表
|
|
88
88
|
* @param {function} config.handleKey 按钮处理回调
|
|
89
|
+
* @param {string} config.lang 语言
|
|
89
90
|
*/
|
|
90
91
|
constructor(config) {
|
|
91
92
|
super();
|
|
@@ -299,6 +300,7 @@ function initComponentsOptions(kv, type) {
|
|
|
299
300
|
options: {
|
|
300
301
|
mitt: kv.mitt,
|
|
301
302
|
scale: config.scale,
|
|
303
|
+
lang: config.lang,
|
|
302
304
|
labelDrawing: config.labelDrawing,
|
|
303
305
|
label: config.label || {},
|
|
304
306
|
measure: {
|