viewerjs 1.12.0 → 1.13.0
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/README.md +204 -32
- package/dist/viewer.common.js +477 -110
- package/dist/viewer.css +111 -2
- package/dist/viewer.esm.js +477 -110
- package/dist/viewer.js +477 -110
- package/dist/viewer.min.css +3 -3
- package/dist/viewer.min.js +3 -3
- package/package.json +6 -7
- package/src/css/viewer.css +107 -1
- package/src/css/viewer.scss +107 -1
- package/src/js/constants.js +5 -0
- package/src/js/defaults.js +46 -4
- package/src/js/events.js +29 -2
- package/src/js/handlers.js +194 -6
- package/src/js/methods.js +86 -61
- package/src/js/others.js +42 -3
- package/src/js/render.js +83 -15
- package/src/js/template.js +7 -0
- package/src/js/utilities.js +68 -12
- package/src/js/viewer.js +69 -10
- package/types/index.d.ts +54 -7
package/src/js/utilities.js
CHANGED
|
@@ -106,6 +106,34 @@ export function forEach(data, callback) {
|
|
|
106
106
|
return data;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Inherit attributes from the original image.
|
|
111
|
+
* @param {Element} image - The target image.
|
|
112
|
+
* @param {Element} originalImage - The original image.
|
|
113
|
+
* @param {Array} inheritedAttributes - The attributes to inherit.
|
|
114
|
+
*/
|
|
115
|
+
export function inheritAttributes(image, originalImage, inheritedAttributes) {
|
|
116
|
+
forEach(inheritedAttributes, (name) => {
|
|
117
|
+
const value = originalImage.getAttribute(name);
|
|
118
|
+
|
|
119
|
+
if (value !== null) {
|
|
120
|
+
image.setAttribute(name, value);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Check if transition is enabled for the given action.
|
|
127
|
+
* @param {Object} options - The viewer options.
|
|
128
|
+
* @param {string} action - The transition action.
|
|
129
|
+
* @returns {boolean} Returns `true` if transition is enabled.
|
|
130
|
+
*/
|
|
131
|
+
export function isTransitionEnabled(options, action) {
|
|
132
|
+
const { transition } = options;
|
|
133
|
+
|
|
134
|
+
return transition && transition[action] !== false;
|
|
135
|
+
}
|
|
136
|
+
|
|
109
137
|
/**
|
|
110
138
|
* Extend the given object.
|
|
111
139
|
* @param {*} obj - The object to be extended.
|
|
@@ -495,11 +523,8 @@ export function getTransforms({
|
|
|
495
523
|
values.push(`rotate(${rotate}deg)`);
|
|
496
524
|
}
|
|
497
525
|
|
|
498
|
-
if (isNumber(scaleX) && scaleX !== 1) {
|
|
526
|
+
if (isNumber(scaleX) && isNumber(scaleY) && (scaleX !== 1 || scaleY !== 1)) {
|
|
499
527
|
values.push(`scaleX(${scaleX})`);
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
if (isNumber(scaleY) && scaleY !== 1) {
|
|
503
528
|
values.push(`scaleY(${scaleY})`);
|
|
504
529
|
}
|
|
505
530
|
|
|
@@ -552,14 +577,7 @@ export function getImageNaturalSizes(image, options, callback) {
|
|
|
552
577
|
}
|
|
553
578
|
};
|
|
554
579
|
|
|
555
|
-
|
|
556
|
-
const value = image.getAttribute(name);
|
|
557
|
-
|
|
558
|
-
if (value !== null) {
|
|
559
|
-
newImage.setAttribute(name, value);
|
|
560
|
-
}
|
|
561
|
-
});
|
|
562
|
-
|
|
580
|
+
inheritAttributes(newImage, image, options.inheritedAttributes);
|
|
563
581
|
newImage.src = image.src;
|
|
564
582
|
|
|
565
583
|
// iOS Safari will convert the image automatically
|
|
@@ -633,6 +651,44 @@ export function getMaxZoomRatio(pointers) {
|
|
|
633
651
|
return ratios[0];
|
|
634
652
|
}
|
|
635
653
|
|
|
654
|
+
/**
|
|
655
|
+
* Get the max rotation degree of a group of pointers.
|
|
656
|
+
* @param {Object} pointers - The target pointers.
|
|
657
|
+
* @returns {number} The result degree.
|
|
658
|
+
*/
|
|
659
|
+
export function getMaxRotateDegree(pointers) {
|
|
660
|
+
const pointers2 = { ...pointers };
|
|
661
|
+
const degrees = [];
|
|
662
|
+
|
|
663
|
+
forEach(pointers, (pointer, pointerId) => {
|
|
664
|
+
delete pointers2[pointerId];
|
|
665
|
+
|
|
666
|
+
forEach(pointers2, (pointer2) => {
|
|
667
|
+
const start = Math.atan2(
|
|
668
|
+
pointer2.startY - pointer.startY,
|
|
669
|
+
pointer2.startX - pointer.startX,
|
|
670
|
+
);
|
|
671
|
+
const end = Math.atan2(
|
|
672
|
+
pointer2.endY - pointer.endY,
|
|
673
|
+
pointer2.endX - pointer.endX,
|
|
674
|
+
);
|
|
675
|
+
let radians = end - start;
|
|
676
|
+
|
|
677
|
+
if (radians > Math.PI) {
|
|
678
|
+
radians -= Math.PI * 2;
|
|
679
|
+
} else if (radians < -Math.PI) {
|
|
680
|
+
radians += Math.PI * 2;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
degrees.push((radians * 180) / Math.PI);
|
|
684
|
+
});
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
degrees.sort((a, b) => Math.abs(b) - Math.abs(a));
|
|
688
|
+
|
|
689
|
+
return degrees[0] || 0;
|
|
690
|
+
}
|
|
691
|
+
|
|
636
692
|
/**
|
|
637
693
|
* Get a pointer from an event object.
|
|
638
694
|
* @param {Object} event - The target event object.
|
package/src/js/viewer.js
CHANGED
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
assign,
|
|
30
30
|
dispatchEvent,
|
|
31
31
|
forEach,
|
|
32
|
+
getData,
|
|
32
33
|
getResponsiveClass,
|
|
33
34
|
hyphenate,
|
|
34
35
|
isFunction,
|
|
@@ -51,15 +52,16 @@ const getUniqueID = ((id) => (() => {
|
|
|
51
52
|
class Viewer {
|
|
52
53
|
/**
|
|
53
54
|
* Create a new Viewer.
|
|
54
|
-
* @param {Element} element - The target
|
|
55
|
+
* @param {Element} element - The target image, or a container of images, to view.
|
|
55
56
|
* @param {Object} [options={}] - The configuration options.
|
|
56
57
|
*/
|
|
57
58
|
constructor(element, options = {}) {
|
|
58
|
-
if (!element || element.nodeType !== 1) {
|
|
59
|
+
if (!element || (element.nodeType !== 1 && element.nodeType !== 11)) {
|
|
59
60
|
throw new Error('The first argument is required and must be an element.');
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
this.element = element;
|
|
64
|
+
this.ownerDocument = element.ownerDocument || element.host.ownerDocument;
|
|
63
65
|
this.options = assign({}, DEFAULTS, isPlainObject(options) && options);
|
|
64
66
|
this.action = false;
|
|
65
67
|
this.fading = false;
|
|
@@ -123,7 +125,7 @@ class Viewer {
|
|
|
123
125
|
this.initBody();
|
|
124
126
|
|
|
125
127
|
// Override `transition` option if it is not supported
|
|
126
|
-
if (isUndefined(
|
|
128
|
+
if (isUndefined(this.ownerDocument.createElement(NAMESPACE).style.transition)) {
|
|
127
129
|
options.transition = false;
|
|
128
130
|
}
|
|
129
131
|
|
|
@@ -217,6 +219,7 @@ class Viewer {
|
|
|
217
219
|
const title = viewer.querySelector(`.${NAMESPACE}-title`);
|
|
218
220
|
const toolbar = viewer.querySelector(`.${NAMESPACE}-toolbar`);
|
|
219
221
|
const navbar = viewer.querySelector(`.${NAMESPACE}-navbar`);
|
|
222
|
+
const navigation = viewer.querySelector(`.${NAMESPACE}-navigation`);
|
|
220
223
|
const button = viewer.querySelector(`.${NAMESPACE}-button`);
|
|
221
224
|
const canvas = viewer.querySelector(`.${NAMESPACE}-canvas`);
|
|
222
225
|
|
|
@@ -225,9 +228,12 @@ class Viewer {
|
|
|
225
228
|
this.title = title;
|
|
226
229
|
this.toolbar = toolbar;
|
|
227
230
|
this.navbar = navbar;
|
|
231
|
+
this.navigation = navigation;
|
|
228
232
|
this.button = button;
|
|
229
233
|
this.canvas = canvas;
|
|
230
234
|
this.footer = viewer.querySelector(`.${NAMESPACE}-footer`);
|
|
235
|
+
this.magnifier = viewer.querySelector(`.${NAMESPACE}-magnifier`);
|
|
236
|
+
this.magnifierImage = viewer.querySelector(`.${NAMESPACE}-magnifier-image`);
|
|
231
237
|
this.tooltipBox = viewer.querySelector(`.${NAMESPACE}-tooltip`);
|
|
232
238
|
this.player = viewer.querySelector(`.${NAMESPACE}-player`);
|
|
233
239
|
this.list = viewer.querySelector(`.${NAMESPACE}-list`);
|
|
@@ -237,11 +243,54 @@ class Viewer {
|
|
|
237
243
|
addClass(title, !options.title ? CLASS_HIDE : getResponsiveClass(Array.isArray(options.title)
|
|
238
244
|
? options.title[0]
|
|
239
245
|
: options.title));
|
|
240
|
-
|
|
246
|
+
const navbarOptions = isPlainObject(options.navbar) ? options.navbar : {};
|
|
247
|
+
let navbarShow = options.navbar;
|
|
248
|
+
const navbarSize = !isUndefined(navbarOptions.size) ? navbarOptions.size : options.navbar;
|
|
249
|
+
|
|
250
|
+
if (isPlainObject(options.navbar)) {
|
|
251
|
+
navbarShow = !isUndefined(navbarOptions.show) ? navbarOptions.show : true;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
addClass(navbar, !navbarShow ? CLASS_HIDE : getResponsiveClass(navbarShow));
|
|
255
|
+
|
|
256
|
+
if (['small', 'medium', 'large'].indexOf(navbarSize) !== -1) {
|
|
257
|
+
addClass(navbar, `${NAMESPACE}-${navbarSize}`);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (isPlainObject(options.navigation)) {
|
|
261
|
+
forEach(navigation.querySelectorAll('[role="button"]'), (item) => {
|
|
262
|
+
const name = getData(item, DATA_ACTION);
|
|
263
|
+
const value = options.navigation[name];
|
|
264
|
+
const deep = isPlainObject(value);
|
|
265
|
+
const show = deep && !isUndefined(value.show) ? value.show : value;
|
|
266
|
+
const size = deep && !isUndefined(value.size)
|
|
267
|
+
? value.size
|
|
268
|
+
: value;
|
|
269
|
+
|
|
270
|
+
toggleClass(item, CLASS_HIDE, !show);
|
|
271
|
+
|
|
272
|
+
if (isNumber(show)) {
|
|
273
|
+
addClass(item, getResponsiveClass(show));
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (['small', 'large'].indexOf(size) !== -1) {
|
|
277
|
+
addClass(item, `${NAMESPACE}-${size}`);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
} else {
|
|
281
|
+
addClass(
|
|
282
|
+
navigation,
|
|
283
|
+
!options.navigation ? CLASS_HIDE : getResponsiveClass(options.navigation),
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
241
287
|
toggleClass(button, CLASS_HIDE, !options.button);
|
|
242
288
|
|
|
243
289
|
if (options.keyboard) {
|
|
244
290
|
button.setAttribute('tabindex', 0);
|
|
291
|
+
forEach(navigation.querySelectorAll('[role="button"]'), (item) => {
|
|
292
|
+
item.setAttribute('tabindex', 0);
|
|
293
|
+
});
|
|
245
294
|
}
|
|
246
295
|
|
|
247
296
|
if (options.backdrop) {
|
|
@@ -356,7 +405,7 @@ class Viewer {
|
|
|
356
405
|
let { container } = options;
|
|
357
406
|
|
|
358
407
|
if (isString(container)) {
|
|
359
|
-
container =
|
|
408
|
+
container = this.ownerDocument.querySelector(container);
|
|
360
409
|
}
|
|
361
410
|
|
|
362
411
|
if (!container) {
|
|
@@ -391,12 +440,13 @@ class Viewer {
|
|
|
391
440
|
}
|
|
392
441
|
|
|
393
442
|
/**
|
|
394
|
-
*
|
|
395
|
-
* @
|
|
443
|
+
* Create a new Viewer instance.
|
|
444
|
+
* @param {Element} element - The target image, or a container of images, to view.
|
|
445
|
+
* @param {Object} [options={}] - The configuration options.
|
|
446
|
+
* @returns {Viewer} A new Viewer instance.
|
|
396
447
|
*/
|
|
397
|
-
static
|
|
398
|
-
|
|
399
|
-
return Viewer;
|
|
448
|
+
static create(element, options) {
|
|
449
|
+
return new Viewer(element, options);
|
|
400
450
|
}
|
|
401
451
|
|
|
402
452
|
/**
|
|
@@ -406,6 +456,15 @@ class Viewer {
|
|
|
406
456
|
static setDefaults(options) {
|
|
407
457
|
assign(DEFAULTS, isPlainObject(options) && options);
|
|
408
458
|
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Get the no conflict viewer class.
|
|
462
|
+
* @returns {Viewer} The viewer class.
|
|
463
|
+
*/
|
|
464
|
+
static noConflict() {
|
|
465
|
+
window.Viewer = AnotherViewer;
|
|
466
|
+
return Viewer;
|
|
467
|
+
}
|
|
409
468
|
}
|
|
410
469
|
|
|
411
470
|
assign(Viewer.prototype, render, events, handlers, methods, others);
|
package/types/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ declare namespace Viewer {
|
|
|
5
5
|
export type Filter = (this: Viewer, image: HTMLImageElement) => boolean;
|
|
6
6
|
export type TitleRenderer = (this: Viewer, image: HTMLImageElement, imageData: Record<string, any>) => string;
|
|
7
7
|
export type ImageURLResolver = (this: Viewer, image: HTMLImageElement) => string;
|
|
8
|
+
export type ZoomRatio = number | ((this: Viewer, image: HTMLImageElement, imageData: Record<string, any>) => number);
|
|
8
9
|
export type ToolbarButtonClick = (this: Viewer, event: Event) => void;
|
|
9
10
|
export type ToolbarOption = boolean | Visibility | ToolbarButtonSize | ToolbarButtonOptions | undefined;
|
|
10
11
|
|
|
@@ -29,6 +30,44 @@ declare namespace Viewer {
|
|
|
29
30
|
[x: string]: ToolbarOption;
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
export interface NavigationButtonOptions {
|
|
34
|
+
show?: boolean | Visibility;
|
|
35
|
+
size?: ToolbarButtonSize;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type NavigationOption = boolean | Visibility | NavigationButtonOptions | undefined;
|
|
39
|
+
|
|
40
|
+
export interface NavbarOptions {
|
|
41
|
+
visibleItemCount?: number;
|
|
42
|
+
show?: boolean | Visibility;
|
|
43
|
+
size?: ToolbarButtonSize;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type NavbarOption = boolean | Visibility | ToolbarButtonSize | NavbarOptions | undefined;
|
|
47
|
+
|
|
48
|
+
export interface NavigationOptions {
|
|
49
|
+
next?: NavigationOption;
|
|
50
|
+
prev?: NavigationOption;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface TransitionOptions {
|
|
54
|
+
hide?: boolean;
|
|
55
|
+
move?: boolean;
|
|
56
|
+
play?: boolean;
|
|
57
|
+
rotate?: boolean;
|
|
58
|
+
scale?: boolean;
|
|
59
|
+
show?: boolean;
|
|
60
|
+
tooltip?: boolean;
|
|
61
|
+
view?: boolean;
|
|
62
|
+
zoom?: boolean;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface MagnifierOptions {
|
|
66
|
+
size?: number;
|
|
67
|
+
zoomRatio?: number;
|
|
68
|
+
opacity?: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
32
71
|
export interface Pivot {
|
|
33
72
|
x: number;
|
|
34
73
|
y: number;
|
|
@@ -90,21 +129,27 @@ declare namespace Viewer {
|
|
|
90
129
|
initialCoverage?: number;
|
|
91
130
|
initialViewIndex?: number;
|
|
92
131
|
inline?: boolean;
|
|
132
|
+
autoplay?: boolean;
|
|
93
133
|
interval?: number;
|
|
94
134
|
keyboard?: boolean;
|
|
95
135
|
loading?: boolean;
|
|
96
136
|
loop?: boolean;
|
|
97
|
-
|
|
137
|
+
magnifier?: boolean | MagnifierOptions;
|
|
138
|
+
maxZoomRatio?: ZoomRatio;
|
|
98
139
|
minHeight?: number;
|
|
99
140
|
minWidth?: number;
|
|
100
|
-
minZoomRatio?:
|
|
141
|
+
minZoomRatio?: ZoomRatio;
|
|
101
142
|
movable?: boolean;
|
|
102
143
|
move?: EventHandler<MoveEvent>;
|
|
103
144
|
moved?: EventHandler<MovedEvent>;
|
|
104
|
-
navbar?:
|
|
145
|
+
navbar?: NavbarOption;
|
|
146
|
+
navigation?: boolean | Visibility | NavigationOptions;
|
|
105
147
|
play?: EventHandler;
|
|
148
|
+
preload?: boolean;
|
|
106
149
|
ready?: EventHandler;
|
|
107
150
|
rotatable?: boolean;
|
|
151
|
+
rotateOnGesture?: boolean;
|
|
152
|
+
rotateOnTouch?: boolean;
|
|
108
153
|
rotate?: EventHandler<RotateEvent>;
|
|
109
154
|
rotated?: EventHandler<RotatedEvent>;
|
|
110
155
|
scalable?: boolean;
|
|
@@ -118,13 +163,14 @@ declare namespace Viewer {
|
|
|
118
163
|
toggleOnDblclick?: boolean;
|
|
119
164
|
toolbar?: boolean | Visibility | ToolbarOptions;
|
|
120
165
|
tooltip?: boolean;
|
|
121
|
-
transition?: boolean;
|
|
166
|
+
transition?: boolean | TransitionOptions;
|
|
122
167
|
url?: string | ImageURLResolver;
|
|
123
168
|
view?: EventHandler;
|
|
124
169
|
viewed?: EventHandler;
|
|
125
170
|
zIndex?: number;
|
|
126
171
|
zIndexInline?: number;
|
|
127
172
|
zoom?: EventHandler<ZoomEvent>;
|
|
173
|
+
zoomOnGesture?: boolean;
|
|
128
174
|
zoomOnTouch?: boolean;
|
|
129
175
|
zoomOnWheel?: boolean;
|
|
130
176
|
zoomRatio?: number;
|
|
@@ -134,7 +180,7 @@ declare namespace Viewer {
|
|
|
134
180
|
}
|
|
135
181
|
|
|
136
182
|
declare class Viewer {
|
|
137
|
-
constructor(element: HTMLElement, options?: Viewer.Options);
|
|
183
|
+
constructor(element: HTMLElement | ShadowRoot, options?: Viewer.Options);
|
|
138
184
|
destroy(): Viewer;
|
|
139
185
|
exit(): Viewer;
|
|
140
186
|
full(): Viewer;
|
|
@@ -154,12 +200,13 @@ declare class Viewer {
|
|
|
154
200
|
stop(): Viewer;
|
|
155
201
|
toggle(): Viewer;
|
|
156
202
|
tooltip(): Viewer;
|
|
157
|
-
update(): Viewer;
|
|
203
|
+
update(options?: Viewer.Options): Viewer;
|
|
158
204
|
view(index?: number): Viewer;
|
|
159
205
|
zoom(ratio: number, hasTooltip?: boolean, pivot?: Viewer.Pivot): Viewer;
|
|
160
206
|
zoomTo(ratio: number, hasTooltip?: boolean, pivot?: Viewer.Pivot): Viewer;
|
|
161
|
-
static
|
|
207
|
+
static create(element: HTMLElement | ShadowRoot, options?: Viewer.Options): Viewer;
|
|
162
208
|
static setDefaults(options: Viewer.Options): void;
|
|
209
|
+
static noConflict(): Viewer;
|
|
163
210
|
}
|
|
164
211
|
|
|
165
212
|
declare module 'viewerjs' {
|