kfb-view 3.2.6 → 3.2.8
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/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 +79 -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
|
}
|
|
@@ -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,38 @@ 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
|
+
let areaInterval = 4;
|
|
141
|
+
let areaDist = 100;
|
|
142
|
+
if (rightTop.x + areaDist + areaInterval > this.canvas.width) {
|
|
143
|
+
areaDist = -100;
|
|
144
|
+
areaInterval = -4;
|
|
145
|
+
}
|
|
146
|
+
ctx.rect(rightTop.x + areaInterval, rightTop.y, areaDist, 40);
|
|
147
|
+
ctx.fill();
|
|
148
|
+
ctx.save();
|
|
149
|
+
ctx.beginPath();
|
|
150
|
+
ctx.translate(rightTop.x + areaInterval + areaDist / 2, rightTop.y - 5);
|
|
151
|
+
ctx.fillStyle = '#ffffff';
|
|
152
|
+
ctx.drawConfirm();
|
|
153
|
+
ctx.restore();
|
|
154
|
+
ctx.save();
|
|
155
|
+
ctx.beginPath();
|
|
156
|
+
if (areaDist < 0) {
|
|
157
|
+
ctx.translate(rightTop.x + areaDist + areaInterval, rightTop.y - 5);
|
|
158
|
+
} else {
|
|
159
|
+
ctx.translate(rightTop.x + areaInterval, rightTop.y - 5);
|
|
160
|
+
}
|
|
161
|
+
ctx.fillStyle = '#ffffff';
|
|
162
|
+
ctx.drawCancel();
|
|
163
|
+
ctx.restore();
|
|
150
164
|
}
|
|
151
165
|
|
|
152
166
|
/**
|
|
@@ -158,6 +172,24 @@ export class Tailoring extends ViewerCommon {
|
|
|
158
172
|
onCanvasPress({x, y}) {
|
|
159
173
|
this.movePointIndex = this.tailoringPoints.findIndex(
|
|
160
174
|
(point) => pointInOtherPoint(point, {x, y}, 30));
|
|
175
|
+
const rightTopPoint = this.tailoringPoints[1];
|
|
176
|
+
|
|
177
|
+
let areaInterval = 4;
|
|
178
|
+
let areaDist = 100;
|
|
179
|
+
let cancelArea = new Rect(rightTopPoint.x + 14, rightTopPoint.y, 30, 40);
|
|
180
|
+
let confirmArea = new Rect(rightTopPoint.x + 64, rightTopPoint.y, 30, 40);
|
|
181
|
+
if (rightTopPoint.x + areaDist + areaInterval > this.canvas.width) {
|
|
182
|
+
cancelArea = new Rect(rightTopPoint.x - 94, rightTopPoint.y, 30, 40);
|
|
183
|
+
confirmArea = new Rect(rightTopPoint.x - 44, rightTopPoint.y, 30, 40);
|
|
184
|
+
}
|
|
185
|
+
const point = new Point(x, y);
|
|
186
|
+
if (cancelArea.containsPoint(point)) {
|
|
187
|
+
this.stopTailoring();
|
|
188
|
+
}
|
|
189
|
+
if (confirmArea.containsPoint(point)) {
|
|
190
|
+
this.emitScreenShot();
|
|
191
|
+
this.stopTailoring();
|
|
192
|
+
}
|
|
161
193
|
}
|
|
162
194
|
|
|
163
195
|
/**
|
|
@@ -242,6 +274,20 @@ export class Tailoring extends ViewerCommon {
|
|
|
242
274
|
};
|
|
243
275
|
break;
|
|
244
276
|
}
|
|
277
|
+
this.tailoringPoints.forEach((i) => {
|
|
278
|
+
if (i.x < 0) {
|
|
279
|
+
i.x = 0;
|
|
280
|
+
}
|
|
281
|
+
if (i.y < 0) {
|
|
282
|
+
i.y = 0;
|
|
283
|
+
}
|
|
284
|
+
if (i.x > this.canvas.width) {
|
|
285
|
+
i.x = this.canvas.width;
|
|
286
|
+
}
|
|
287
|
+
if (i.y > this.canvas.height) {
|
|
288
|
+
i.y = this.canvas.height;
|
|
289
|
+
}
|
|
290
|
+
});
|
|
245
291
|
this.clearCanvas();
|
|
246
292
|
this.drawRect();
|
|
247
293
|
this.drawTailoring();
|
|
@@ -262,19 +308,23 @@ export class Tailoring extends ViewerCommon {
|
|
|
262
308
|
|
|
263
309
|
onCanvasDblClick(position) {
|
|
264
310
|
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
|
-
});
|
|
311
|
+
this.emitScreenShot();
|
|
274
312
|
}
|
|
275
313
|
this.stopTailoring();
|
|
276
314
|
}
|
|
277
315
|
|
|
316
|
+
emitScreenShot() {
|
|
317
|
+
this.emitTailoringRegion();
|
|
318
|
+
this.mitt.$emit(EVENT_TAILORING_SCREENSHOT, {
|
|
319
|
+
base64: this.getScreenCanvasImage(),
|
|
320
|
+
region: this.viewerElementToImageRectangle({
|
|
321
|
+
x: this.tailoringPoints[0].x, y: this.tailoringPoints[0].y,
|
|
322
|
+
width: this.tailoringPoints[3].x - this.tailoringPoints[0].x,
|
|
323
|
+
height: this.tailoringPoints[3].y - this.tailoringPoints[0].y,
|
|
324
|
+
}),
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
278
328
|
/**
|
|
279
329
|
* 判断鼠标在区域内
|
|
280
330
|
* @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: {
|