kfb-view 3.1.5 → 3.2.1
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 +2 -1
- package/src/components/area/index.js +9 -9
- package/src/components/board/index.js +8 -8
- package/src/components/common/common.js +26 -27
- package/src/components/graduation/index.js +45 -21
- package/src/components/navigator/index.js +66 -123
- package/src/components/tailoring/index.js +3 -3
- package/src/const/event.js +1 -0
- package/src/util/calculate.js +5 -0
- package/src/util/event-emitter.js +37 -17
- package/src/util/index.js +14 -0
- package/src/view.js +17 -2
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import './navigator.scss';
|
|
2
2
|
import {Point} from '../../plugin/openseadragon/openseadragon';
|
|
3
3
|
import {navigatorHtml} from './navigator.html';
|
|
4
|
-
import {EventEmitter} from '../../util/event-emitter';
|
|
5
4
|
import {EVENT_NAVIGATOR_VESTIGE} from '../../const/event';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* 视图导航器
|
|
9
8
|
* @class
|
|
10
9
|
*/
|
|
11
|
-
export class Navigator
|
|
10
|
+
export class Navigator {
|
|
12
11
|
/**
|
|
13
12
|
* 初始化导航器数据
|
|
13
|
+
* @param {Object=} mitt 事件
|
|
14
14
|
* @param {Object=} rest openseadragon的导航器参数
|
|
15
15
|
*/
|
|
16
|
-
constructor(rest
|
|
17
|
-
|
|
16
|
+
constructor({mitt, ...rest}) {
|
|
17
|
+
this.mitt = mitt;
|
|
18
18
|
this.options = rest;
|
|
19
19
|
this.viewport = rest.viewer.viewport;
|
|
20
20
|
this.viewer = rest.viewer;
|
|
@@ -24,6 +24,7 @@ export class Navigator extends EventEmitter {
|
|
|
24
24
|
this.containerHeight = rest.containerHeight || window.innerHeight;
|
|
25
25
|
this.containerWidth = rest.containerWidth || window.innerWidth;
|
|
26
26
|
this.element = rest.element;
|
|
27
|
+
this.canvas = document.createElement('canvas');
|
|
27
28
|
this.pointList = rest.pointList || [];
|
|
28
29
|
this.loadStatus = false; // 导航图加载状态
|
|
29
30
|
this.init();
|
|
@@ -52,42 +53,11 @@ export class Navigator extends EventEmitter {
|
|
|
52
53
|
*/
|
|
53
54
|
init() {
|
|
54
55
|
this.element.innerHTML = navigatorHtml;
|
|
55
|
-
const navigatorMain = this.element.getElementsByClassName(
|
|
56
|
-
|
|
57
|
-
this.
|
|
56
|
+
const navigatorMain = this.element.getElementsByClassName('navigator-main')[0];
|
|
57
|
+
this.rect = this.element.getElementsByClassName('view-rect')[0];
|
|
58
|
+
this.updateNavigatorImg(this.options.thumbnail);
|
|
58
59
|
navigatorMain.appendChild(this.canvas);
|
|
59
60
|
this.handleMouseDrag(navigatorMain);
|
|
60
|
-
|
|
61
|
-
const rect = this.element.getElementsByClassName('view-rect')[0];
|
|
62
|
-
this.rect = rect;
|
|
63
|
-
this.$on('rect-change', (e) => {
|
|
64
|
-
const vLine = navigatorMain.getElementsByClassName('v-line')[0];
|
|
65
|
-
const hLine = navigatorMain.getElementsByClassName('h-line')[0];
|
|
66
|
-
vLine.style.left =
|
|
67
|
-
Math.round(rect.getBoundingClientRect().width / 2 +
|
|
68
|
-
rect.offsetLeft) + 'px';
|
|
69
|
-
hLine.style.top =
|
|
70
|
-
Math.round(rect.getBoundingClientRect().height / 2 +
|
|
71
|
-
rect.offsetTop) + 'px';
|
|
72
|
-
vLine.style.backgroundColor = 'red';
|
|
73
|
-
hLine.style.backgroundColor = 'red';
|
|
74
|
-
});
|
|
75
|
-
this.$on('rect-draw', (e) => {
|
|
76
|
-
const left = rect.offsetLeft;
|
|
77
|
-
const top = rect.offsetTop;
|
|
78
|
-
const index = e.detail;
|
|
79
|
-
const rectObj = {
|
|
80
|
-
left: left,
|
|
81
|
-
top: top,
|
|
82
|
-
width: rect.clientWidth,
|
|
83
|
-
height: rect.clientHeight,
|
|
84
|
-
scale: [...this.vestige.zooms].reverse()[index],
|
|
85
|
-
color: [...this.vestige.colors].reverse()[index],
|
|
86
|
-
};
|
|
87
|
-
this.pointList.push(rectObj);
|
|
88
|
-
this.drawPointList(this.pointList);
|
|
89
|
-
this.$emit(EVENT_NAVIGATOR_VESTIGE, this.pointList);
|
|
90
|
-
});
|
|
91
61
|
this.viewer.addHandler('pan', (res) => {
|
|
92
62
|
this.navigatorChange(this.viewport.getZoom(true), res.center);
|
|
93
63
|
});
|
|
@@ -96,6 +66,39 @@ export class Navigator extends EventEmitter {
|
|
|
96
66
|
});
|
|
97
67
|
}
|
|
98
68
|
|
|
69
|
+
rectChange() {
|
|
70
|
+
const navigatorMain = this.element.getElementsByClassName(
|
|
71
|
+
'navigator-main')[0];
|
|
72
|
+
const rect = this.rect;
|
|
73
|
+
const vLine = navigatorMain.getElementsByClassName('v-line')[0];
|
|
74
|
+
const hLine = navigatorMain.getElementsByClassName('h-line')[0];
|
|
75
|
+
vLine.style.left =
|
|
76
|
+
Math.round(rect.getBoundingClientRect().width / 2 +
|
|
77
|
+
rect.offsetLeft) + 'px';
|
|
78
|
+
hLine.style.top =
|
|
79
|
+
Math.round(rect.getBoundingClientRect().height / 2 +
|
|
80
|
+
rect.offsetTop) + 'px';
|
|
81
|
+
vLine.style.backgroundColor = 'red';
|
|
82
|
+
hLine.style.backgroundColor = 'red';
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
rectDraw(index) {
|
|
86
|
+
const rect = this.rect;
|
|
87
|
+
const left = rect.offsetLeft;
|
|
88
|
+
const top = rect.offsetTop;
|
|
89
|
+
const rectObj = {
|
|
90
|
+
left: left,
|
|
91
|
+
top: top,
|
|
92
|
+
width: rect.clientWidth,
|
|
93
|
+
height: rect.clientHeight,
|
|
94
|
+
scale: [...this.vestige.zooms].reverse()[index],
|
|
95
|
+
color: [...this.vestige.colors].reverse()[index],
|
|
96
|
+
};
|
|
97
|
+
this.pointList.push(rectObj);
|
|
98
|
+
this.drawPointList(this.pointList);
|
|
99
|
+
this.mitt.$emit(EVENT_NAVIGATOR_VESTIGE, this.pointList);
|
|
100
|
+
}
|
|
101
|
+
|
|
99
102
|
/**
|
|
100
103
|
* 绘制一系列点坐标
|
|
101
104
|
* @param {Array} pointList
|
|
@@ -129,19 +132,15 @@ export class Navigator extends EventEmitter {
|
|
|
129
132
|
* 导航器改变
|
|
130
133
|
* @param {number} zoom 缩放倍数
|
|
131
134
|
* @param {Object} refPoint 缩放点
|
|
132
|
-
* @param {Object=} rect 遮罩层元素
|
|
133
135
|
*/
|
|
134
|
-
navigatorChange(zoom, refPoint
|
|
136
|
+
navigatorChange(zoom, refPoint) {
|
|
135
137
|
if (!this.loadStatus) {
|
|
136
138
|
return;
|
|
137
139
|
}
|
|
138
140
|
if (!refPoint) {
|
|
139
141
|
refPoint = this.viewport.getCenter(true);
|
|
140
142
|
}
|
|
141
|
-
|
|
142
|
-
rect = this.element.getElementsByClassName('view-rect')[0];
|
|
143
|
-
}
|
|
144
|
-
this.setViewRect(rect, refPoint);
|
|
143
|
+
this.setViewRect(refPoint);
|
|
145
144
|
}
|
|
146
145
|
|
|
147
146
|
/**
|
|
@@ -169,24 +168,6 @@ export class Navigator extends EventEmitter {
|
|
|
169
168
|
* @param {Document|Element} navigator
|
|
170
169
|
*/
|
|
171
170
|
handleMouseDrag(navigator) {
|
|
172
|
-
/* this.$on('mousedown', (e) => {
|
|
173
|
-
this.$on('selectstart', () => 1);
|
|
174
|
-
this.$on('dragstart', () => 1);
|
|
175
|
-
this.panTo({
|
|
176
|
-
x: e.x - navigator.getBoundingClientRect().left,
|
|
177
|
-
y: e.y - navigator.getBoundingClientRect().top,
|
|
178
|
-
}, navigator);
|
|
179
|
-
}, true, navigator);
|
|
180
|
-
|
|
181
|
-
this.$on('touchstart', (e) => {
|
|
182
|
-
const x = e.touches[0].clientX;
|
|
183
|
-
const y = e.touches[0].clientY;
|
|
184
|
-
this.panTo({
|
|
185
|
-
x: x - navigator.getBoundingClientRect().left,
|
|
186
|
-
y: y - navigator.getBoundingClientRect().top,
|
|
187
|
-
}, navigator);
|
|
188
|
-
}, true, navigator);*/
|
|
189
|
-
|
|
190
171
|
let lastPoint;
|
|
191
172
|
let centerPoint;
|
|
192
173
|
const mouseMove = ({x, y}) => {
|
|
@@ -205,8 +186,8 @@ export class Navigator extends EventEmitter {
|
|
|
205
186
|
x: this.centerPoint.x,
|
|
206
187
|
y: this.centerPoint.y,
|
|
207
188
|
};
|
|
208
|
-
this.$off('mousemove', mouseMove);
|
|
209
|
-
this.$off('mouseup', mouseUp);
|
|
189
|
+
this.mitt.$off('mousemove', mouseMove);
|
|
190
|
+
this.mitt.$off('mouseup', mouseUp);
|
|
210
191
|
};
|
|
211
192
|
const touchend = () => {
|
|
212
193
|
lastPoint = '';
|
|
@@ -214,8 +195,8 @@ export class Navigator extends EventEmitter {
|
|
|
214
195
|
x: this.centerPoint.x,
|
|
215
196
|
y: this.centerPoint.y,
|
|
216
197
|
};
|
|
217
|
-
this.$off('touchmove', touchmove);
|
|
218
|
-
this.$off('touchend', touchend);
|
|
198
|
+
this.mitt.$off('touchmove', touchmove);
|
|
199
|
+
this.mitt.$off('touchend', touchend);
|
|
219
200
|
};
|
|
220
201
|
const touchmove = (e) => {
|
|
221
202
|
const x = e.touches[0].clientX;
|
|
@@ -229,9 +210,9 @@ export class Navigator extends EventEmitter {
|
|
|
229
210
|
y: centerPoint.y + distY,
|
|
230
211
|
}, navigator);
|
|
231
212
|
};
|
|
232
|
-
this.$on('mousedown', (e) => {
|
|
233
|
-
this.$on('selectstart', () => 1);
|
|
234
|
-
this.$on('dragstart', () => 1);
|
|
213
|
+
this.mitt.$on('mousedown', (e) => {
|
|
214
|
+
this.mitt.$on('selectstart', () => 1);
|
|
215
|
+
this.mitt.$on('dragstart', () => 1);
|
|
235
216
|
this.panTo({
|
|
236
217
|
x: e.x - navigator.getBoundingClientRect().left,
|
|
237
218
|
y: e.y - navigator.getBoundingClientRect().top,
|
|
@@ -240,11 +221,11 @@ export class Navigator extends EventEmitter {
|
|
|
240
221
|
x: this.centerPoint.x,
|
|
241
222
|
y: this.centerPoint.y,
|
|
242
223
|
};
|
|
243
|
-
this.$on('mousemove', mouseMove);
|
|
244
|
-
this.$on('mouseup', mouseUp);
|
|
224
|
+
this.mitt.$on('mousemove', mouseMove);
|
|
225
|
+
this.mitt.$on('mouseup', mouseUp);
|
|
245
226
|
}, true, navigator);
|
|
246
227
|
|
|
247
|
-
this.$on('touchstart', (e) => {
|
|
228
|
+
this.mitt.$on('touchstart', (e) => {
|
|
248
229
|
const x = e.touches[0].clientX;
|
|
249
230
|
const y = e.touches[0].clientY;
|
|
250
231
|
this.panTo({
|
|
@@ -255,18 +236,17 @@ export class Navigator extends EventEmitter {
|
|
|
255
236
|
x: this.centerPoint.x,
|
|
256
237
|
y: this.centerPoint.y,
|
|
257
238
|
};
|
|
258
|
-
this.$on('touchmove', touchmove);
|
|
259
|
-
this.$on('touchend', touchend);
|
|
239
|
+
this.mitt.$on('touchmove', touchmove);
|
|
240
|
+
this.mitt.$on('touchend', touchend);
|
|
260
241
|
}, true, navigator);
|
|
261
242
|
}
|
|
262
243
|
|
|
263
244
|
/**
|
|
264
245
|
* 设置缩率图上的遮罩区域
|
|
265
|
-
* @param {Object} rect 缩率图上的长方形元素
|
|
266
246
|
* @param {Object=} point viewport的中心点
|
|
267
247
|
*/
|
|
268
|
-
setViewRect(
|
|
269
|
-
if (!rect) throw new Error('找不到对应的导航器遮罩元素');
|
|
248
|
+
setViewRect(point) {
|
|
249
|
+
if (!this.rect) throw new Error('找不到对应的导航器遮罩元素');
|
|
270
250
|
if (!point) point = this.viewport.getCenter(true);
|
|
271
251
|
const bounds = this.viewport.getHomeBounds();
|
|
272
252
|
const imageBounds = this.viewport.viewportToImageRectangle(bounds);
|
|
@@ -284,7 +264,7 @@ export class Navigator extends EventEmitter {
|
|
|
284
264
|
const currentZoom = this.viewport.getZoom();
|
|
285
265
|
const height = trueHeight * homeZoom / currentZoom;
|
|
286
266
|
const width = trueWidth * homeZoom / currentZoom;
|
|
287
|
-
rect.style.cssText = `height:${height * ratio}px;
|
|
267
|
+
this.rect.style.cssText = `height:${height * ratio}px;
|
|
288
268
|
width: ${width * ratio}px;`;
|
|
289
269
|
const refImagePoint = this.viewport.viewportToImageCoordinates(point);
|
|
290
270
|
this.centerPoint = {
|
|
@@ -295,10 +275,10 @@ export class Navigator extends EventEmitter {
|
|
|
295
275
|
y: this.centerPoint.y - height * ratio / 2,
|
|
296
276
|
x: this.centerPoint.x - width * ratio / 2,
|
|
297
277
|
};
|
|
298
|
-
rect.style.left = refPoint.x + 'px';
|
|
299
|
-
rect.style.top = refPoint.y + 'px';
|
|
300
|
-
rect.style.border = '1px solid red';
|
|
301
|
-
this
|
|
278
|
+
this.rect.style.left = refPoint.x + 'px';
|
|
279
|
+
this.rect.style.top = refPoint.y + 'px';
|
|
280
|
+
this.rect.style.border = '1px solid red';
|
|
281
|
+
this.rectChange();
|
|
302
282
|
if (this.vestige.show !== false) {
|
|
303
283
|
if (this.clearTimeId) window.clearTimeout(this.clearTimeId);
|
|
304
284
|
const currentImageZoom = this.viewport.viewportToImageZoom(currentZoom);
|
|
@@ -306,49 +286,12 @@ export class Navigator extends EventEmitter {
|
|
|
306
286
|
(z) => currentImageZoom >= (z / (this.options.scale || 40)));
|
|
307
287
|
if (index !== -1) {
|
|
308
288
|
this.clearTimeId = window.setTimeout(() => {
|
|
309
|
-
this
|
|
289
|
+
this.rectDraw(index);
|
|
310
290
|
}, this.vestige.delay || 1000);
|
|
311
291
|
}
|
|
312
292
|
}
|
|
313
293
|
}
|
|
314
294
|
|
|
315
|
-
/**
|
|
316
|
-
* 创建Navigator的canvas
|
|
317
|
-
* @return {Object} canvas
|
|
318
|
-
*/
|
|
319
|
-
createNavigatorCanvas() {
|
|
320
|
-
const canvas = document.createElement('canvas');
|
|
321
|
-
const ctx = canvas.getContext('2d');
|
|
322
|
-
const img = new Image(); // 创建img元素
|
|
323
|
-
img.onload = () => {
|
|
324
|
-
const imgWidth = img.width;
|
|
325
|
-
const imgHeight = img.height;
|
|
326
|
-
let scale = 1;
|
|
327
|
-
if (imgWidth >= imgHeight) {
|
|
328
|
-
scale = imgWidth / this.width;
|
|
329
|
-
const trueHeight = imgHeight / scale;
|
|
330
|
-
canvas.width = this.width;
|
|
331
|
-
canvas.height = trueHeight;
|
|
332
|
-
ctx.drawImage(img, 0, 0, canvas.width, trueHeight);
|
|
333
|
-
}
|
|
334
|
-
if (imgHeight > imgWidth) {
|
|
335
|
-
scale = imgHeight / this.height;
|
|
336
|
-
const trueWidth = imgWidth / scale;
|
|
337
|
-
canvas.height = this.height;
|
|
338
|
-
canvas.width = trueWidth;
|
|
339
|
-
ctx.drawImage(img, 0, 0, trueWidth, canvas.height);
|
|
340
|
-
}
|
|
341
|
-
this.setViewRect(this.element.getElementsByClassName('view-rect')[0]);
|
|
342
|
-
const colorCanvas = this.element.getElementsByClassName(
|
|
343
|
-
'navigator-color-rect')[0];
|
|
344
|
-
colorCanvas.width = this.canvas.width;
|
|
345
|
-
colorCanvas.height = this.canvas.height;
|
|
346
|
-
this.loadStatus = true;
|
|
347
|
-
};
|
|
348
|
-
img.src = this.options.thumbnail; // 设置图片源地
|
|
349
|
-
return canvas;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
295
|
updateNavigatorImg(url) {
|
|
353
296
|
this.options.thumbnail = url;
|
|
354
297
|
const ctx = this.canvas.getContext('2d');
|
|
@@ -373,11 +316,11 @@ export class Navigator extends EventEmitter {
|
|
|
373
316
|
ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
374
317
|
ctx.drawImage(img, 0, 0, trueWidth, this.canvas.height);
|
|
375
318
|
}
|
|
376
|
-
this.setViewRect(
|
|
377
|
-
const colorCanvas = this.element.getElementsByClassName(
|
|
378
|
-
'navigator-color-rect')[0];
|
|
319
|
+
this.setViewRect();
|
|
320
|
+
const colorCanvas = this.element.getElementsByClassName('navigator-color-rect')[0];
|
|
379
321
|
colorCanvas.width = this.canvas.width;
|
|
380
322
|
colorCanvas.height = this.canvas.height;
|
|
323
|
+
this.loadStatus = true;
|
|
381
324
|
};
|
|
382
325
|
img.src = this.options.thumbnail; // 设置图片源地
|
|
383
326
|
}
|
|
@@ -58,7 +58,7 @@ export class Tailoring extends ViewerCommon {
|
|
|
58
58
|
pointList[8]];
|
|
59
59
|
if (now) {
|
|
60
60
|
this.emitTailoringRegion();
|
|
61
|
-
this.$emit(EVENT_TAILORING_SCREENSHOT, {
|
|
61
|
+
this.mitt.$emit(EVENT_TAILORING_SCREENSHOT, {
|
|
62
62
|
base64: this.getScreenCanvasImage(),
|
|
63
63
|
region: this.viewerElementToImageRectangle({
|
|
64
64
|
x: this.tailoringPoints[0].x, y: this.tailoringPoints[0].y,
|
|
@@ -77,7 +77,7 @@ export class Tailoring extends ViewerCommon {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
emitTailoringRegion() {
|
|
80
|
-
this.$emit(EVENT_TAILORING_REGION, this.viewerElementToImageRectangle({
|
|
80
|
+
this.mitt.$emit(EVENT_TAILORING_REGION, this.viewerElementToImageRectangle({
|
|
81
81
|
x: this.tailoringPoints[0].x, y: this.tailoringPoints[0].y,
|
|
82
82
|
width: this.tailoringPoints[3].x - this.tailoringPoints[0].x,
|
|
83
83
|
height: this.tailoringPoints[3].y - this.tailoringPoints[0].y,
|
|
@@ -263,7 +263,7 @@ export class Tailoring extends ViewerCommon {
|
|
|
263
263
|
onCanvasDblClick(position) {
|
|
264
264
|
if (this.tailoringPoints.length > 0 && this.isPointInMatrix(position)) {
|
|
265
265
|
this.emitTailoringRegion();
|
|
266
|
-
this.$emit(EVENT_TAILORING_SCREENSHOT, {
|
|
266
|
+
this.mitt.$emit(EVENT_TAILORING_SCREENSHOT, {
|
|
267
267
|
base64: this.getScreenCanvasImage(),
|
|
268
268
|
region: this.viewerElementToImageRectangle({
|
|
269
269
|
x: this.tailoringPoints[0].x, y: this.tailoringPoints[0].y,
|
package/src/const/event.js
CHANGED
|
@@ -18,3 +18,4 @@ export const EVENT_DELETE_LABEL = 'delete-label';
|
|
|
18
18
|
export const EVENT_DELETE_POLYGON_POINT = 'delete-polygon-point';
|
|
19
19
|
export const EVENT_ADD_POLYGON_POINT = 'add-polygon-point';
|
|
20
20
|
export const EVENT_NAVIGATOR_VESTIGE = 'navigator-vestige';
|
|
21
|
+
export const EVENT_GRADUATION_CHANGE = 'graduation-change';
|
package/src/util/calculate.js
CHANGED
|
@@ -450,6 +450,10 @@ function perimeter(type, startPoint, endPoint, imageCapRes = 1) {
|
|
|
450
450
|
return pt;
|
|
451
451
|
}
|
|
452
452
|
|
|
453
|
+
const getRandomId = () => {
|
|
454
|
+
return (((1 + Math.random()) * 0x100000000) | 0).toString(16).substring(1);
|
|
455
|
+
};
|
|
456
|
+
|
|
453
457
|
export {
|
|
454
458
|
getRectPoint,
|
|
455
459
|
isPointInMatrix,
|
|
@@ -467,4 +471,5 @@ export {
|
|
|
467
471
|
getAngle,
|
|
468
472
|
getDistance,
|
|
469
473
|
calculatePolygonArea,
|
|
474
|
+
getRandomId,
|
|
470
475
|
};
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import * as EVENTS from '../const/event';
|
|
2
|
+
import mitt from 'mitt';
|
|
3
|
+
import {getRandomId} from './calculate';
|
|
4
|
+
|
|
5
|
+
const globalEvent = mitt();
|
|
6
|
+
|
|
1
7
|
/**
|
|
2
8
|
* 事件类
|
|
3
9
|
* @class
|
|
@@ -9,6 +15,7 @@ export class EventEmitter {
|
|
|
9
15
|
*/
|
|
10
16
|
constructor() {
|
|
11
17
|
this.eventList = [];
|
|
18
|
+
this.key = getRandomId();
|
|
12
19
|
}
|
|
13
20
|
|
|
14
21
|
/**
|
|
@@ -18,11 +25,15 @@ export class EventEmitter {
|
|
|
18
25
|
* @param {Document|Element} [target = document]
|
|
19
26
|
*/
|
|
20
27
|
$emit(eventName, data, target = document) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
if (Object.values(EVENTS).includes(eventName)) {
|
|
29
|
+
globalEvent.emit(`${this.key}_${eventName}`, data);
|
|
30
|
+
} else {
|
|
31
|
+
const customEvent = new CustomEvent(eventName, {
|
|
32
|
+
bubbles: true,
|
|
33
|
+
detail: data,
|
|
34
|
+
});
|
|
35
|
+
target.dispatchEvent(customEvent);
|
|
36
|
+
}
|
|
26
37
|
}
|
|
27
38
|
|
|
28
39
|
/**
|
|
@@ -33,8 +44,12 @@ export class EventEmitter {
|
|
|
33
44
|
* @param {Document|Element} [target = document]
|
|
34
45
|
*/
|
|
35
46
|
$on(eventName, callback, options = true, target = document) {
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
if (Object.values(EVENTS).includes(eventName)) {
|
|
48
|
+
globalEvent.on(`${this.key}_${eventName}`, callback);
|
|
49
|
+
} else {
|
|
50
|
+
target.addEventListener(eventName, callback, options);
|
|
51
|
+
this.eventList.push({target, eventName, callback, options});
|
|
52
|
+
}
|
|
38
53
|
}
|
|
39
54
|
|
|
40
55
|
/**
|
|
@@ -60,16 +75,20 @@ export class EventEmitter {
|
|
|
60
75
|
* @param {Document|Element} [target = document]
|
|
61
76
|
*/
|
|
62
77
|
$off(eventName, callback, options, target = document) {
|
|
63
|
-
|
|
64
|
-
(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
78
|
+
if (Object.values(EVENTS).includes(eventName)) {
|
|
79
|
+
globalEvent.off(`${this.key}_${eventName}`, callback);
|
|
80
|
+
} else {
|
|
81
|
+
let eventList = this.eventList.filter((ev) =>
|
|
82
|
+
(ev.target === target || !target || target === document) &&
|
|
83
|
+
(ev.eventName === eventName || !eventName) &&
|
|
84
|
+
(ev.options === options || options == null) &&
|
|
85
|
+
(ev.callback === callback || !callback));
|
|
86
|
+
eventList.forEach((ev) => {
|
|
87
|
+
ev.target.removeEventListener(ev.eventName, ev.callback, ev.options);
|
|
88
|
+
const index = this.eventList.findIndex((e) => e === ev);
|
|
89
|
+
if (~index) this.eventList.splice(index, 1);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
73
92
|
}
|
|
74
93
|
|
|
75
94
|
/**
|
|
@@ -77,5 +96,6 @@ export class EventEmitter {
|
|
|
77
96
|
*/
|
|
78
97
|
destroy() {
|
|
79
98
|
this.$off();
|
|
99
|
+
globalEvent.all.clear();
|
|
80
100
|
}
|
|
81
101
|
}
|
package/src/util/index.js
CHANGED
|
@@ -64,9 +64,23 @@ function delayedTrigger(callback, time = 1000) {
|
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
function getUnitNumber(number, units, binary, index = 0) {
|
|
68
|
+
let i = number;
|
|
69
|
+
while (i >= binary) {
|
|
70
|
+
i = i / binary;
|
|
71
|
+
index++;
|
|
72
|
+
}
|
|
73
|
+
if (!units[index]) {
|
|
74
|
+
index = units.length - 1;
|
|
75
|
+
}
|
|
76
|
+
return (number / Math.pow(binary, index)).toFixed(2) / 1 + units[index];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
67
80
|
export {
|
|
68
81
|
$,
|
|
69
82
|
dataType,
|
|
70
83
|
deepClone,
|
|
71
84
|
delayedTrigger,
|
|
85
|
+
getUnitNumber,
|
|
72
86
|
};
|
package/src/view.js
CHANGED
|
@@ -35,7 +35,9 @@ export default class KfbView extends EventEmitter {
|
|
|
35
35
|
* @param {number[]=} config.navigator.vestige.zooms 浏览痕迹触发倍率
|
|
36
36
|
* @param {Object} config.pxConversion 像素转换参数
|
|
37
37
|
* @param {number} config.pxConversion.imageCapRes 像素转换倍率
|
|
38
|
+
* @param {string[]=} config.pxConversion.units 单位组
|
|
38
39
|
* @param {string} config.pxConversion.unit 单位
|
|
40
|
+
* @param {number} config.pxConversion.binary 几进制, 2, 16, 24, 1000
|
|
39
41
|
* @param {Object} config.area 交互区域,触发点击、拖动等事件
|
|
40
42
|
* @param {boolean=} config.area.disabled 是否禁用area
|
|
41
43
|
* @param {boolean=} config.area.drag 是否允许拖动
|
|
@@ -63,7 +65,9 @@ export default class KfbView extends EventEmitter {
|
|
|
63
65
|
* @param {boolean=} config.graduation.disabled 是否禁用刻度
|
|
64
66
|
* @param {boolean=} config.graduation.show 是否显刻度
|
|
65
67
|
* @param {boolean=} config.graduation.custom 是否自定义刻度,抛出graduation-change事件
|
|
66
|
-
* @param {
|
|
68
|
+
* @param {Object} config.graduation.tick 刻度线参数
|
|
69
|
+
* @param {number=} config.graduation.tick.height 刻度线高度
|
|
70
|
+
* @param {number=} config.graduation.tick.number 刻度线段落
|
|
67
71
|
* @param {array=} config.graduation.microns 刻度长度数组,在对应倍率范围内显示的刻度长度
|
|
68
72
|
* @param {boolean=} config.grid.disabled 是否禁用网格线
|
|
69
73
|
* @param {boolean=} config.grid.show 是否显示网格线
|
|
@@ -107,6 +111,14 @@ export default class KfbView extends EventEmitter {
|
|
|
107
111
|
width,
|
|
108
112
|
height,
|
|
109
113
|
};
|
|
114
|
+
this.mitt = {
|
|
115
|
+
$on: this.$on,
|
|
116
|
+
$emit: this.$emit,
|
|
117
|
+
$off: this.$off,
|
|
118
|
+
$once: this.$once,
|
|
119
|
+
key: this.key,
|
|
120
|
+
eventList: this.eventList,
|
|
121
|
+
};
|
|
110
122
|
initOpenDragon(this);
|
|
111
123
|
initComponents(this);
|
|
112
124
|
initEvent(this);
|
|
@@ -257,6 +269,7 @@ function initNavigator(kv) {
|
|
|
257
269
|
containerWidth: config.width,
|
|
258
270
|
element: navigator,
|
|
259
271
|
scale: config.scale,
|
|
272
|
+
mitt: kv.mitt,
|
|
260
273
|
...config.navigator,
|
|
261
274
|
});
|
|
262
275
|
}
|
|
@@ -276,13 +289,14 @@ function createCanvas(kv) {
|
|
|
276
289
|
|
|
277
290
|
function initComponentsOptions(kv, type) {
|
|
278
291
|
const config = kv.$options;
|
|
279
|
-
const pxConversion = config.pxConversion || {imageCapRes: 1,
|
|
292
|
+
const pxConversion = config.pxConversion || {imageCapRes: 1, units: []};
|
|
280
293
|
return {
|
|
281
294
|
kv,
|
|
282
295
|
viewer: kv.viewer,
|
|
283
296
|
cache: kv.cache,
|
|
284
297
|
canvas: createCanvas(kv),
|
|
285
298
|
options: {
|
|
299
|
+
mitt: kv.mitt,
|
|
286
300
|
scale: config.scale,
|
|
287
301
|
labelDrawing: config.labelDrawing,
|
|
288
302
|
label: config.label || {},
|
|
@@ -296,6 +310,7 @@ function initComponentsOptions(kv, type) {
|
|
|
296
310
|
},
|
|
297
311
|
...config[type],
|
|
298
312
|
...pxConversion,
|
|
313
|
+
units: pxConversion.units ?? [pxConversion.unit ?? ''], // 兼容之前只显示一个的单位
|
|
299
314
|
thumb: config.thumb ? {
|
|
300
315
|
radius: 5,
|
|
301
316
|
activeRadius: 7,
|