viewerjs 1.10.5 → 1.11.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.
@@ -1,26 +1,23 @@
1
1
  /*!
2
- * Viewer.js v1.10.5
2
+ * Viewer.js v1.11.1
3
3
  * https://fengyuanchen.github.io/viewerjs
4
4
  *
5
5
  * Copyright 2015-present Chen Fengyuan
6
6
  * Released under the MIT license
7
7
  *
8
- * Date: 2022-04-05T08:21:02.491Z
8
+ * Date: 2022-11-06T05:18:19.939Z
9
9
  */
10
10
 
11
11
  function ownKeys(object, enumerableOnly) {
12
12
  var keys = Object.keys(object);
13
-
14
13
  if (Object.getOwnPropertySymbols) {
15
14
  var symbols = Object.getOwnPropertySymbols(object);
16
15
  enumerableOnly && (symbols = symbols.filter(function (sym) {
17
16
  return Object.getOwnPropertyDescriptor(object, sym).enumerable;
18
17
  })), keys.push.apply(keys, symbols);
19
18
  }
20
-
21
19
  return keys;
22
20
  }
23
-
24
21
  function _objectSpread2(target) {
25
22
  for (var i = 1; i < arguments.length; i++) {
26
23
  var source = null != arguments[i] ? arguments[i] : {};
@@ -30,10 +27,8 @@ function _objectSpread2(target) {
30
27
  Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
31
28
  });
32
29
  }
33
-
34
30
  return target;
35
31
  }
36
-
37
32
  function _typeof(obj) {
38
33
  "@babel/helpers - typeof";
39
34
 
@@ -43,13 +38,11 @@ function _typeof(obj) {
43
38
  return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
44
39
  }, _typeof(obj);
45
40
  }
46
-
47
41
  function _classCallCheck(instance, Constructor) {
48
42
  if (!(instance instanceof Constructor)) {
49
43
  throw new TypeError("Cannot call a class as a function");
50
44
  }
51
45
  }
52
-
53
46
  function _defineProperties(target, props) {
54
47
  for (var i = 0; i < props.length; i++) {
55
48
  var descriptor = props[i];
@@ -59,7 +52,6 @@ function _defineProperties(target, props) {
59
52
  Object.defineProperty(target, descriptor.key, descriptor);
60
53
  }
61
54
  }
62
-
63
55
  function _createClass(Constructor, protoProps, staticProps) {
64
56
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
65
57
  if (staticProps) _defineProperties(Constructor, staticProps);
@@ -68,7 +60,6 @@ function _createClass(Constructor, protoProps, staticProps) {
68
60
  });
69
61
  return Constructor;
70
62
  }
71
-
72
63
  function _defineProperty(obj, key, value) {
73
64
  if (key in obj) {
74
65
  Object.defineProperty(obj, key, {
@@ -80,7 +71,6 @@ function _defineProperty(obj, key, value) {
80
71
  } else {
81
72
  obj[key] = value;
82
73
  }
83
-
84
74
  return obj;
85
75
  }
86
76
 
@@ -91,213 +81,183 @@ var DEFAULTS = {
91
81
  * @type {boolean}
92
82
  */
93
83
  backdrop: true,
94
-
95
84
  /**
96
85
  * Show the button on the top-right of the viewer.
97
86
  * @type {boolean}
98
87
  */
99
88
  button: true,
100
-
101
89
  /**
102
90
  * Show the navbar.
103
91
  * @type {boolean | number}
104
92
  */
105
93
  navbar: true,
106
-
107
94
  /**
108
95
  * Specify the visibility and the content of the title.
109
96
  * @type {boolean | number | Function | Array}
110
97
  */
111
98
  title: true,
112
-
113
99
  /**
114
100
  * Show the toolbar.
115
101
  * @type {boolean | number | Object}
116
102
  */
117
103
  toolbar: true,
118
-
119
104
  /**
120
105
  * Custom class name(s) to add to the viewer's root element.
121
106
  * @type {string}
122
107
  */
123
108
  className: '',
124
-
125
109
  /**
126
110
  * Define where to put the viewer in modal mode.
127
111
  * @type {string | Element}
128
112
  */
129
113
  container: 'body',
130
-
131
114
  /**
132
115
  * Filter the images for viewing. Return true if the image is viewable.
133
116
  * @type {Function}
134
117
  */
135
118
  filter: null,
136
-
137
119
  /**
138
120
  * Enable to request fullscreen when play.
139
121
  * {@link https://developer.mozilla.org/en-US/docs/Web/API/FullscreenOptions}
140
122
  * @type {boolean|FullscreenOptions}
141
123
  */
142
124
  fullscreen: true,
143
-
144
125
  /**
145
126
  * Define the extra attributes to inherit from the original image.
146
127
  * @type {Array}
147
128
  */
148
129
  inheritedAttributes: ['crossOrigin', 'decoding', 'isMap', 'loading', 'referrerPolicy', 'sizes', 'srcset', 'useMap'],
149
-
150
130
  /**
151
- * Define the initial index of image for viewing.
131
+ * Define the initial coverage of the viewing image.
132
+ * @type {number}
133
+ */
134
+ initialCoverage: 0.9,
135
+ /**
136
+ * Define the initial index of the image for viewing.
152
137
  * @type {number}
153
138
  */
154
139
  initialViewIndex: 0,
155
-
156
140
  /**
157
141
  * Enable inline mode.
158
142
  * @type {boolean}
159
143
  */
160
144
  inline: false,
161
-
162
145
  /**
163
146
  * The amount of time to delay between automatically cycling an image when playing.
164
147
  * @type {number}
165
148
  */
166
149
  interval: 5000,
167
-
168
150
  /**
169
151
  * Enable keyboard support.
170
152
  * @type {boolean}
171
153
  */
172
154
  keyboard: true,
173
-
174
155
  /**
175
156
  * Focus the viewer when initialized.
176
157
  * @type {boolean}
177
158
  */
178
159
  focus: true,
179
-
180
160
  /**
181
161
  * Indicate if show a loading spinner when load image or not.
182
162
  * @type {boolean}
183
163
  */
184
164
  loading: true,
185
-
186
165
  /**
187
166
  * Indicate if enable loop viewing or not.
188
167
  * @type {boolean}
189
168
  */
190
169
  loop: true,
191
-
192
170
  /**
193
171
  * Min width of the viewer in inline mode.
194
172
  * @type {number}
195
173
  */
196
174
  minWidth: 200,
197
-
198
175
  /**
199
176
  * Min height of the viewer in inline mode.
200
177
  * @type {number}
201
178
  */
202
179
  minHeight: 100,
203
-
204
180
  /**
205
181
  * Enable to move the image.
206
182
  * @type {boolean}
207
183
  */
208
184
  movable: true,
209
-
210
185
  /**
211
186
  * Enable to rotate the image.
212
187
  * @type {boolean}
213
188
  */
214
189
  rotatable: true,
215
-
216
190
  /**
217
191
  * Enable to scale the image.
218
192
  * @type {boolean}
219
193
  */
220
194
  scalable: true,
221
-
222
195
  /**
223
196
  * Enable to zoom the image.
224
197
  * @type {boolean}
225
198
  */
226
199
  zoomable: true,
227
-
228
200
  /**
229
201
  * Enable to zoom the current image by dragging on the touch screen.
230
202
  * @type {boolean}
231
203
  */
232
204
  zoomOnTouch: true,
233
-
234
205
  /**
235
206
  * Enable to zoom the image by wheeling mouse.
236
207
  * @type {boolean}
237
208
  */
238
209
  zoomOnWheel: true,
239
-
240
210
  /**
241
211
  * Enable to slide to the next or previous image by swiping on the touch screen.
242
212
  * @type {boolean}
243
213
  */
244
214
  slideOnTouch: true,
245
-
246
215
  /**
247
216
  * Indicate if toggle the image size between its natural size
248
217
  * and initial size when double click on the image or not.
249
218
  * @type {boolean}
250
219
  */
251
220
  toggleOnDblclick: true,
252
-
253
221
  /**
254
222
  * Show the tooltip with image ratio (percentage) when zoom in or zoom out.
255
223
  * @type {boolean}
256
224
  */
257
225
  tooltip: true,
258
-
259
226
  /**
260
227
  * Enable CSS3 Transition for some special elements.
261
228
  * @type {boolean}
262
229
  */
263
230
  transition: true,
264
-
265
231
  /**
266
232
  * Define the CSS `z-index` value of viewer in modal mode.
267
233
  * @type {number}
268
234
  */
269
235
  zIndex: 2015,
270
-
271
236
  /**
272
237
  * Define the CSS `z-index` value of viewer in inline mode.
273
238
  * @type {number}
274
239
  */
275
240
  zIndexInline: 0,
276
-
277
241
  /**
278
242
  * Define the ratio when zoom the image by wheeling mouse.
279
243
  * @type {number}
280
244
  */
281
245
  zoomRatio: 0.1,
282
-
283
246
  /**
284
247
  * Define the min ratio of the image when zoom out.
285
248
  * @type {number}
286
249
  */
287
250
  minZoomRatio: 0.01,
288
-
289
251
  /**
290
252
  * Define the max ratio of the image when zoom in.
291
253
  * @type {number}
292
254
  */
293
255
  maxZoomRatio: 100,
294
-
295
256
  /**
296
257
  * Define where to get the original image URL for viewing.
297
258
  * @type {string | Function}
298
259
  */
299
260
  url: 'src',
300
-
301
261
  /**
302
262
  * Event shortcuts.
303
263
  * @type {Function}
@@ -327,12 +287,14 @@ var IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'un
327
287
  var WINDOW = IS_BROWSER ? window : {};
328
288
  var IS_TOUCH_DEVICE = IS_BROWSER && WINDOW.document.documentElement ? 'ontouchstart' in WINDOW.document.documentElement : false;
329
289
  var HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in WINDOW : false;
330
- var NAMESPACE = 'viewer'; // Actions
290
+ var NAMESPACE = 'viewer';
331
291
 
292
+ // Actions
332
293
  var ACTION_MOVE = 'move';
333
294
  var ACTION_SWITCH = 'switch';
334
- var ACTION_ZOOM = 'zoom'; // Classes
295
+ var ACTION_ZOOM = 'zoom';
335
296
 
297
+ // Classes
336
298
  var CLASS_ACTIVE = "".concat(NAMESPACE, "-active");
337
299
  var CLASS_CLOSE = "".concat(NAMESPACE, "-close");
338
300
  var CLASS_FADE = "".concat(NAMESPACE, "-fade");
@@ -349,8 +311,9 @@ var CLASS_LOADING = "".concat(NAMESPACE, "-loading");
349
311
  var CLASS_MOVE = "".concat(NAMESPACE, "-move");
350
312
  var CLASS_OPEN = "".concat(NAMESPACE, "-open");
351
313
  var CLASS_SHOW = "".concat(NAMESPACE, "-show");
352
- var CLASS_TRANSITION = "".concat(NAMESPACE, "-transition"); // Native events
314
+ var CLASS_TRANSITION = "".concat(NAMESPACE, "-transition");
353
315
 
316
+ // Native events
354
317
  var EVENT_CLICK = 'click';
355
318
  var EVENT_DBLCLICK = 'dblclick';
356
319
  var EVENT_DRAG_START = 'dragstart';
@@ -366,8 +329,9 @@ var EVENT_POINTER_MOVE = HAS_POINTER_EVENT ? 'pointermove' : EVENT_TOUCH_MOVE;
366
329
  var EVENT_POINTER_UP = HAS_POINTER_EVENT ? 'pointerup pointercancel' : EVENT_TOUCH_END;
367
330
  var EVENT_RESIZE = 'resize';
368
331
  var EVENT_TRANSITION_END = 'transitionend';
369
- var EVENT_WHEEL = 'wheel'; // Custom events
332
+ var EVENT_WHEEL = 'wheel';
370
333
 
334
+ // Custom events
371
335
  var EVENT_READY = 'ready';
372
336
  var EVENT_SHOW = 'show';
373
337
  var EVENT_SHOWN = 'shown';
@@ -384,12 +348,15 @@ var EVENT_SCALED = 'scaled';
384
348
  var EVENT_ZOOM = 'zoom';
385
349
  var EVENT_ZOOMED = 'zoomed';
386
350
  var EVENT_PLAY = 'play';
387
- var EVENT_STOP = 'stop'; // Data keys
351
+ var EVENT_STOP = 'stop';
388
352
 
389
- var DATA_ACTION = "".concat(NAMESPACE, "Action"); // RegExps
353
+ // Data keys
354
+ var DATA_ACTION = "".concat(NAMESPACE, "Action");
390
355
 
391
- var REGEXP_SPACES = /\s\s*/; // Misc
356
+ // RegExps
357
+ var REGEXP_SPACES = /\s\s*/;
392
358
 
359
+ // Misc
393
360
  var BUTTONS = ['zoom-in', 'zoom-out', 'one-to-one', 'reset', 'prev', 'play', 'next', 'rotate-left', 'rotate-right', 'flip-horizontal', 'flip-vertical'];
394
361
 
395
362
  /**
@@ -397,54 +364,52 @@ var BUTTONS = ['zoom-in', 'zoom-out', 'one-to-one', 'reset', 'prev', 'play', 'ne
397
364
  * @param {*} value - The value to check.
398
365
  * @returns {boolean} Returns `true` if the given value is a string, else `false`.
399
366
  */
400
-
401
367
  function isString(value) {
402
368
  return typeof value === 'string';
403
369
  }
370
+
404
371
  /**
405
372
  * Check if the given value is not a number.
406
373
  */
407
-
408
374
  var isNaN = Number.isNaN || WINDOW.isNaN;
375
+
409
376
  /**
410
377
  * Check if the given value is a number.
411
378
  * @param {*} value - The value to check.
412
379
  * @returns {boolean} Returns `true` if the given value is a number, else `false`.
413
380
  */
414
-
415
381
  function isNumber(value) {
416
382
  return typeof value === 'number' && !isNaN(value);
417
383
  }
384
+
418
385
  /**
419
386
  * Check if the given value is undefined.
420
387
  * @param {*} value - The value to check.
421
388
  * @returns {boolean} Returns `true` if the given value is undefined, else `false`.
422
389
  */
423
-
424
390
  function isUndefined(value) {
425
391
  return typeof value === 'undefined';
426
392
  }
393
+
427
394
  /**
428
395
  * Check if the given value is an object.
429
396
  * @param {*} value - The value to check.
430
397
  * @returns {boolean} Returns `true` if the given value is an object, else `false`.
431
398
  */
432
-
433
399
  function isObject(value) {
434
400
  return _typeof(value) === 'object' && value !== null;
435
401
  }
436
402
  var hasOwnProperty = Object.prototype.hasOwnProperty;
403
+
437
404
  /**
438
405
  * Check if the given value is a plain object.
439
406
  * @param {*} value - The value to check.
440
407
  * @returns {boolean} Returns `true` if the given value is a plain object, else `false`.
441
408
  */
442
-
443
409
  function isPlainObject(value) {
444
410
  if (!isObject(value)) {
445
411
  return false;
446
412
  }
447
-
448
413
  try {
449
414
  var _constructor = value.constructor;
450
415
  var prototype = _constructor.prototype;
@@ -453,30 +418,27 @@ function isPlainObject(value) {
453
418
  return false;
454
419
  }
455
420
  }
421
+
456
422
  /**
457
423
  * Check if the given value is a function.
458
424
  * @param {*} value - The value to check.
459
425
  * @returns {boolean} Returns `true` if the given value is a function, else `false`.
460
426
  */
461
-
462
427
  function isFunction(value) {
463
428
  return typeof value === 'function';
464
429
  }
430
+
465
431
  /**
466
432
  * Iterate the given data.
467
433
  * @param {*} data - The data to iterate.
468
434
  * @param {Function} callback - The process function for each element.
469
435
  * @returns {*} The original data.
470
436
  */
471
-
472
437
  function forEach(data, callback) {
473
438
  if (data && isFunction(callback)) {
474
- if (Array.isArray(data) || isNumber(data.length)
475
- /* array-like */
476
- ) {
439
+ if (Array.isArray(data) || isNumber(data.length) /* array-like */) {
477
440
  var length = data.length;
478
441
  var i;
479
-
480
442
  for (i = 0; i < length; i += 1) {
481
443
  if (callback.call(data, data[i], i, data) === false) {
482
444
  break;
@@ -488,21 +450,19 @@ function forEach(data, callback) {
488
450
  });
489
451
  }
490
452
  }
491
-
492
453
  return data;
493
454
  }
455
+
494
456
  /**
495
457
  * Extend the given object.
496
458
  * @param {*} obj - The object to be extended.
497
459
  * @param {*} args - The rest objects which will be merged to the first object.
498
460
  * @returns {Object} The extended object.
499
461
  */
500
-
501
462
  var assign = Object.assign || function assign(obj) {
502
463
  for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
503
464
  args[_key - 1] = arguments[_key];
504
465
  }
505
-
506
466
  if (isObject(obj) && args.length > 0) {
507
467
  args.forEach(function (arg) {
508
468
  if (isObject(arg)) {
@@ -512,127 +472,116 @@ var assign = Object.assign || function assign(obj) {
512
472
  }
513
473
  });
514
474
  }
515
-
516
475
  return obj;
517
476
  };
518
477
  var REGEXP_SUFFIX = /^(?:width|height|left|top|marginLeft|marginTop)$/;
478
+
519
479
  /**
520
480
  * Apply styles to the given element.
521
481
  * @param {Element} element - The target element.
522
482
  * @param {Object} styles - The styles for applying.
523
483
  */
524
-
525
484
  function setStyle(element, styles) {
526
485
  var style = element.style;
527
486
  forEach(styles, function (value, property) {
528
487
  if (REGEXP_SUFFIX.test(property) && isNumber(value)) {
529
488
  value += 'px';
530
489
  }
531
-
532
490
  style[property] = value;
533
491
  });
534
492
  }
493
+
535
494
  /**
536
495
  * Escape a string for using in HTML.
537
496
  * @param {String} value - The string to escape.
538
497
  * @returns {String} Returns the escaped string.
539
498
  */
540
-
541
499
  function escapeHTMLEntities(value) {
542
500
  return isString(value) ? value.replace(/&(?!amp;|quot;|#39;|lt;|gt;)/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;') : value;
543
501
  }
502
+
544
503
  /**
545
504
  * Check if the given element has a special class.
546
505
  * @param {Element} element - The element to check.
547
506
  * @param {string} value - The class to search.
548
507
  * @returns {boolean} Returns `true` if the special class was found.
549
508
  */
550
-
551
509
  function hasClass(element, value) {
552
510
  if (!element || !value) {
553
511
  return false;
554
512
  }
555
-
556
513
  return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1;
557
514
  }
515
+
558
516
  /**
559
517
  * Add classes to the given element.
560
518
  * @param {Element} element - The target element.
561
519
  * @param {string} value - The classes to be added.
562
520
  */
563
-
564
521
  function addClass(element, value) {
565
522
  if (!element || !value) {
566
523
  return;
567
524
  }
568
-
569
525
  if (isNumber(element.length)) {
570
526
  forEach(element, function (elem) {
571
527
  addClass(elem, value);
572
528
  });
573
529
  return;
574
530
  }
575
-
576
531
  if (element.classList) {
577
532
  element.classList.add(value);
578
533
  return;
579
534
  }
580
-
581
535
  var className = element.className.trim();
582
-
583
536
  if (!className) {
584
537
  element.className = value;
585
538
  } else if (className.indexOf(value) < 0) {
586
539
  element.className = "".concat(className, " ").concat(value);
587
540
  }
588
541
  }
542
+
589
543
  /**
590
544
  * Remove classes from the given element.
591
545
  * @param {Element} element - The target element.
592
546
  * @param {string} value - The classes to be removed.
593
547
  */
594
-
595
548
  function removeClass(element, value) {
596
549
  if (!element || !value) {
597
550
  return;
598
551
  }
599
-
600
552
  if (isNumber(element.length)) {
601
553
  forEach(element, function (elem) {
602
554
  removeClass(elem, value);
603
555
  });
604
556
  return;
605
557
  }
606
-
607
558
  if (element.classList) {
608
559
  element.classList.remove(value);
609
560
  return;
610
561
  }
611
-
612
562
  if (element.className.indexOf(value) >= 0) {
613
563
  element.className = element.className.replace(value, '');
614
564
  }
615
565
  }
566
+
616
567
  /**
617
568
  * Add or remove classes from the given element.
618
569
  * @param {Element} element - The target element.
619
570
  * @param {string} value - The classes to be toggled.
620
571
  * @param {boolean} added - Add only.
621
572
  */
622
-
623
573
  function toggleClass(element, value, added) {
624
574
  if (!value) {
625
575
  return;
626
576
  }
627
-
628
577
  if (isNumber(element.length)) {
629
578
  forEach(element, function (elem) {
630
579
  toggleClass(elem, value, added);
631
580
  });
632
581
  return;
633
- } // IE10-11 doesn't support the second parameter of `classList.toggle`
634
-
582
+ }
635
583
 
584
+ // IE10-11 doesn't support the second parameter of `classList.toggle`
636
585
  if (added) {
637
586
  addClass(element, value);
638
587
  } else {
@@ -640,40 +589,38 @@ function toggleClass(element, value, added) {
640
589
  }
641
590
  }
642
591
  var REGEXP_HYPHENATE = /([a-z\d])([A-Z])/g;
592
+
643
593
  /**
644
594
  * Transform the given string from camelCase to kebab-case
645
595
  * @param {string} value - The value to transform.
646
596
  * @returns {string} The transformed value.
647
597
  */
648
-
649
598
  function hyphenate(value) {
650
599
  return value.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase();
651
600
  }
601
+
652
602
  /**
653
603
  * Get data from the given element.
654
604
  * @param {Element} element - The target element.
655
605
  * @param {string} name - The data key to get.
656
606
  * @returns {string} The data value.
657
607
  */
658
-
659
608
  function getData(element, name) {
660
609
  if (isObject(element[name])) {
661
610
  return element[name];
662
611
  }
663
-
664
612
  if (element.dataset) {
665
613
  return element.dataset[name];
666
614
  }
667
-
668
615
  return element.getAttribute("data-".concat(hyphenate(name)));
669
616
  }
617
+
670
618
  /**
671
619
  * Set data to the given element.
672
620
  * @param {Element} element - The target element.
673
621
  * @param {string} name - The data key to set.
674
622
  * @param {string} data - The data value.
675
623
  */
676
-
677
624
  function setData(element, name, data) {
678
625
  if (isObject(data)) {
679
626
  element[name] = data;
@@ -683,21 +630,16 @@ function setData(element, name, data) {
683
630
  element.setAttribute("data-".concat(hyphenate(name)), data);
684
631
  }
685
632
  }
686
-
687
633
  var onceSupported = function () {
688
634
  var supported = false;
689
-
690
635
  if (IS_BROWSER) {
691
636
  var once = false;
692
-
693
637
  var listener = function listener() {};
694
-
695
638
  var options = Object.defineProperty({}, 'once', {
696
639
  get: function get() {
697
640
  supported = true;
698
641
  return once;
699
642
  },
700
-
701
643
  /**
702
644
  * This setter can fix a `TypeError` in strict mode
703
645
  * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}
@@ -710,9 +652,9 @@ var onceSupported = function () {
710
652
  WINDOW.addEventListener('test', listener, options);
711
653
  WINDOW.removeEventListener('test', listener, options);
712
654
  }
713
-
714
655
  return supported;
715
656
  }();
657
+
716
658
  /**
717
659
  * Remove event listener from the target element.
718
660
  * @param {Element} element - The event target.
@@ -720,32 +662,27 @@ var onceSupported = function () {
720
662
  * @param {Function} listener - The event listener.
721
663
  * @param {Object} options - The event options.
722
664
  */
723
-
724
-
725
665
  function removeListener(element, type, listener) {
726
666
  var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
727
667
  var handler = listener;
728
668
  type.trim().split(REGEXP_SPACES).forEach(function (event) {
729
669
  if (!onceSupported) {
730
670
  var listeners = element.listeners;
731
-
732
671
  if (listeners && listeners[event] && listeners[event][listener]) {
733
672
  handler = listeners[event][listener];
734
673
  delete listeners[event][listener];
735
-
736
674
  if (Object.keys(listeners[event]).length === 0) {
737
675
  delete listeners[event];
738
676
  }
739
-
740
677
  if (Object.keys(listeners).length === 0) {
741
678
  delete element.listeners;
742
679
  }
743
680
  }
744
681
  }
745
-
746
682
  element.removeEventListener(event, handler, options);
747
683
  });
748
684
  }
685
+
749
686
  /**
750
687
  * Add event listener to the target element.
751
688
  * @param {Element} element - The event target.
@@ -753,41 +690,34 @@ function removeListener(element, type, listener) {
753
690
  * @param {Function} listener - The event listener.
754
691
  * @param {Object} options - The event options.
755
692
  */
756
-
757
693
  function addListener(element, type, listener) {
758
694
  var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
759
695
  var _handler = listener;
760
696
  type.trim().split(REGEXP_SPACES).forEach(function (event) {
761
697
  if (options.once && !onceSupported) {
762
698
  var _element$listeners = element.listeners,
763
- listeners = _element$listeners === void 0 ? {} : _element$listeners;
764
-
699
+ listeners = _element$listeners === void 0 ? {} : _element$listeners;
765
700
  _handler = function handler() {
766
701
  delete listeners[event][listener];
767
702
  element.removeEventListener(event, _handler, options);
768
-
769
703
  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
770
704
  args[_key2] = arguments[_key2];
771
705
  }
772
-
773
706
  listener.apply(element, args);
774
707
  };
775
-
776
708
  if (!listeners[event]) {
777
709
  listeners[event] = {};
778
710
  }
779
-
780
711
  if (listeners[event][listener]) {
781
712
  element.removeEventListener(event, listeners[event][listener], options);
782
713
  }
783
-
784
714
  listeners[event][listener] = _handler;
785
715
  element.listeners = listeners;
786
716
  }
787
-
788
717
  element.addEventListener(event, _handler, options);
789
718
  });
790
719
  }
720
+
791
721
  /**
792
722
  * Dispatch event on the target element.
793
723
  * @param {Element} element - The event target.
@@ -796,10 +726,10 @@ function addListener(element, type, listener) {
796
726
  * @param {Object} options - The additional event options.
797
727
  * @returns {boolean} Indicate if the event is default prevented or not.
798
728
  */
799
-
800
729
  function dispatchEvent(element, type, data, options) {
801
- var event; // Event and CustomEvent on IE9-11 are global objects, not constructors
730
+ var event;
802
731
 
732
+ // Event and CustomEvent on IE9-11 are global objects, not constructors
803
733
  if (isFunction(Event) && isFunction(CustomEvent)) {
804
734
  event = new CustomEvent(type, _objectSpread2({
805
735
  bubbles: true,
@@ -810,15 +740,14 @@ function dispatchEvent(element, type, data, options) {
810
740
  event = document.createEvent('CustomEvent');
811
741
  event.initCustomEvent(type, true, true, data);
812
742
  }
813
-
814
743
  return element.dispatchEvent(event);
815
744
  }
745
+
816
746
  /**
817
747
  * Get the offset base on the document.
818
748
  * @param {Element} element - The target element.
819
749
  * @returns {Object} The offset data.
820
750
  */
821
-
822
751
  function getOffset(element) {
823
752
  var box = element.getBoundingClientRect();
824
753
  return {
@@ -826,41 +755,36 @@ function getOffset(element) {
826
755
  top: box.top + (window.pageYOffset - document.documentElement.clientTop)
827
756
  };
828
757
  }
758
+
829
759
  /**
830
760
  * Get transforms base on the given object.
831
761
  * @param {Object} obj - The target object.
832
762
  * @returns {string} A string contains transform values.
833
763
  */
834
-
835
764
  function getTransforms(_ref) {
836
765
  var rotate = _ref.rotate,
837
- scaleX = _ref.scaleX,
838
- scaleY = _ref.scaleY,
839
- translateX = _ref.translateX,
840
- translateY = _ref.translateY;
766
+ scaleX = _ref.scaleX,
767
+ scaleY = _ref.scaleY,
768
+ translateX = _ref.translateX,
769
+ translateY = _ref.translateY;
841
770
  var values = [];
842
-
843
771
  if (isNumber(translateX) && translateX !== 0) {
844
772
  values.push("translateX(".concat(translateX, "px)"));
845
773
  }
846
-
847
774
  if (isNumber(translateY) && translateY !== 0) {
848
775
  values.push("translateY(".concat(translateY, "px)"));
849
- } // Rotate should come first before scale to match orientation transform
850
-
776
+ }
851
777
 
778
+ // Rotate should come first before scale to match orientation transform
852
779
  if (isNumber(rotate) && rotate !== 0) {
853
780
  values.push("rotate(".concat(rotate, "deg)"));
854
781
  }
855
-
856
782
  if (isNumber(scaleX) && scaleX !== 1) {
857
783
  values.push("scaleX(".concat(scaleX, ")"));
858
784
  }
859
-
860
785
  if (isNumber(scaleY) && scaleY !== 1) {
861
786
  values.push("scaleY(".concat(scaleY, ")"));
862
787
  }
863
-
864
788
  var transform = values.length ? values.join(' ') : 'none';
865
789
  return {
866
790
  WebkitTransform: transform,
@@ -868,6 +792,7 @@ function getTransforms(_ref) {
868
792
  transform: transform
869
793
  };
870
794
  }
795
+
871
796
  /**
872
797
  * Get an image name from an image url.
873
798
  * @param {string} url - The target url.
@@ -876,11 +801,11 @@ function getTransforms(_ref) {
876
801
  * getImageNameFromURL('https://domain.com/path/to/picture.jpg?size=1280×960')
877
802
  * @returns {string} A string contains the image name.
878
803
  */
879
-
880
804
  function getImageNameFromURL(url) {
881
805
  return isString(url) ? decodeURIComponent(url.replace(/^.*\//, '').replace(/[?&#].*$/, '')) : '';
882
806
  }
883
807
  var IS_SAFARI = WINDOW.navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(WINDOW.navigator.userAgent);
808
+
884
809
  /**
885
810
  * Get an image's natural sizes.
886
811
  * @param {string} image - The target image.
@@ -888,72 +813,63 @@ var IS_SAFARI = WINDOW.navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i
888
813
  * @param {Function} callback - The callback function.
889
814
  * @returns {HTMLImageElement} The new image.
890
815
  */
891
-
892
816
  function getImageNaturalSizes(image, options, callback) {
893
- var newImage = document.createElement('img'); // Modern browsers (except Safari)
817
+ var newImage = document.createElement('img');
894
818
 
819
+ // Modern browsers (except Safari)
895
820
  if (image.naturalWidth && !IS_SAFARI) {
896
821
  callback(image.naturalWidth, image.naturalHeight);
897
822
  return newImage;
898
823
  }
899
-
900
824
  var body = document.body || document.documentElement;
901
-
902
825
  newImage.onload = function () {
903
826
  callback(newImage.width, newImage.height);
904
-
905
827
  if (!IS_SAFARI) {
906
828
  body.removeChild(newImage);
907
829
  }
908
830
  };
909
-
910
831
  forEach(options.inheritedAttributes, function (name) {
911
832
  var value = image.getAttribute(name);
912
-
913
833
  if (value !== null) {
914
834
  newImage.setAttribute(name, value);
915
835
  }
916
836
  });
917
- newImage.src = image.src; // iOS Safari will convert the image automatically
918
- // with its orientation once append it into DOM
837
+ newImage.src = image.src;
919
838
 
839
+ // iOS Safari will convert the image automatically
840
+ // with its orientation once append it into DOM
920
841
  if (!IS_SAFARI) {
921
842
  newImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;';
922
843
  body.appendChild(newImage);
923
844
  }
924
-
925
845
  return newImage;
926
846
  }
847
+
927
848
  /**
928
849
  * Get the related class name of a responsive type number.
929
850
  * @param {string} type - The responsive type.
930
851
  * @returns {string} The related class name.
931
852
  */
932
-
933
853
  function getResponsiveClass(type) {
934
854
  switch (type) {
935
855
  case 2:
936
856
  return CLASS_HIDE_XS_DOWN;
937
-
938
857
  case 3:
939
858
  return CLASS_HIDE_SM_DOWN;
940
-
941
859
  case 4:
942
860
  return CLASS_HIDE_MD_DOWN;
943
-
944
861
  default:
945
862
  return '';
946
863
  }
947
864
  }
865
+
948
866
  /**
949
867
  * Get the max ratio of a group of pointers.
950
868
  * @param {string} pointers - The target pointers.
951
869
  * @returns {number} The result ratio.
952
870
  */
953
-
954
871
  function getMaxZoomRatio(pointers) {
955
872
  var pointers2 = _objectSpread2({}, pointers);
956
-
957
873
  var ratios = [];
958
874
  forEach(pointers, function (pointer, pointerId) {
959
875
  delete pointers2[pointerId];
@@ -973,16 +889,16 @@ function getMaxZoomRatio(pointers) {
973
889
  });
974
890
  return ratios[0];
975
891
  }
892
+
976
893
  /**
977
894
  * Get a pointer from an event object.
978
895
  * @param {Object} event - The target event object.
979
896
  * @param {boolean} endOnly - Indicates if only returns the end point coordinate or not.
980
897
  * @returns {Object} The result pointer contains start and/or end point coordinates.
981
898
  */
982
-
983
899
  function getPointer(_ref2, endOnly) {
984
900
  var pageX = _ref2.pageX,
985
- pageY = _ref2.pageY;
901
+ pageY = _ref2.pageY;
986
902
  var end = {
987
903
  endX: pageX,
988
904
  endY: pageY
@@ -993,19 +909,19 @@ function getPointer(_ref2, endOnly) {
993
909
  startY: pageY
994
910
  }, end);
995
911
  }
912
+
996
913
  /**
997
914
  * Get the center point coordinate of a group of pointers.
998
915
  * @param {Object} pointers - The target pointers.
999
916
  * @returns {Object} The center point coordinate.
1000
917
  */
1001
-
1002
918
  function getPointersCenter(pointers) {
1003
919
  var pageX = 0;
1004
920
  var pageY = 0;
1005
921
  var count = 0;
1006
922
  forEach(pointers, function (_ref3) {
1007
923
  var startX = _ref3.startX,
1008
- startY = _ref3.startY;
924
+ startY = _ref3.startY;
1009
925
  pageX += startX;
1010
926
  pageY += startY;
1011
927
  count += 1;
@@ -1041,9 +957,8 @@ var render = {
1041
957
  },
1042
958
  initViewer: function initViewer() {
1043
959
  var options = this.options,
1044
- parent = this.parent;
960
+ parent = this.parent;
1045
961
  var viewerData;
1046
-
1047
962
  if (options.inline) {
1048
963
  viewerData = {
1049
964
  width: Math.max(parent.offsetWidth, options.minWidth),
@@ -1051,11 +966,9 @@ var render = {
1051
966
  };
1052
967
  this.parentData = viewerData;
1053
968
  }
1054
-
1055
969
  if (this.fulled || !viewerData) {
1056
970
  viewerData = this.containerData;
1057
971
  }
1058
-
1059
972
  this.viewerData = assign({}, viewerData);
1060
973
  },
1061
974
  renderViewer: function renderViewer() {
@@ -1065,40 +978,37 @@ var render = {
1065
978
  },
1066
979
  initList: function initList() {
1067
980
  var _this = this;
1068
-
1069
981
  var element = this.element,
1070
- options = this.options,
1071
- list = this.list;
1072
- var items = []; // initList may be called in this.update, so should keep idempotent
982
+ options = this.options,
983
+ list = this.list;
984
+ var items = [];
1073
985
 
986
+ // initList may be called in this.update, so should keep idempotent
1074
987
  list.innerHTML = '';
1075
988
  forEach(this.images, function (image, index) {
1076
989
  var src = image.src;
1077
990
  var alt = image.alt || getImageNameFromURL(src);
1078
-
1079
991
  var url = _this.getImageURL(image);
1080
-
1081
992
  if (src || url) {
1082
993
  var item = document.createElement('li');
1083
994
  var img = document.createElement('img');
1084
995
  forEach(options.inheritedAttributes, function (name) {
1085
996
  var value = image.getAttribute(name);
1086
-
1087
997
  if (value !== null) {
1088
998
  img.setAttribute(name, value);
1089
999
  }
1090
1000
  });
1091
- img.src = src || url;
1001
+ if (options.navbar) {
1002
+ img.src = src || url;
1003
+ }
1092
1004
  img.alt = alt;
1093
1005
  img.setAttribute('data-original-url', url || src);
1094
1006
  item.setAttribute('data-index', index);
1095
1007
  item.setAttribute('data-viewer-action', 'view');
1096
1008
  item.setAttribute('role', 'button');
1097
-
1098
1009
  if (options.keyboard) {
1099
1010
  item.setAttribute('tabindex', 0);
1100
1011
  }
1101
-
1102
1012
  item.appendChild(img);
1103
1013
  list.appendChild(item);
1104
1014
  items.push(item);
@@ -1110,25 +1020,20 @@ var render = {
1110
1020
  var onLoad;
1111
1021
  var onError;
1112
1022
  setData(image, 'filled', true);
1113
-
1114
1023
  if (options.loading) {
1115
1024
  addClass(item, CLASS_LOADING);
1116
1025
  }
1117
-
1118
1026
  addListener(image, EVENT_LOAD, onLoad = function onLoad(event) {
1119
1027
  removeListener(image, EVENT_ERROR, onError);
1120
-
1121
1028
  if (options.loading) {
1122
1029
  removeClass(item, CLASS_LOADING);
1123
1030
  }
1124
-
1125
1031
  _this.loadImage(event);
1126
1032
  }, {
1127
1033
  once: true
1128
1034
  });
1129
1035
  addListener(image, EVENT_ERROR, onError = function onError() {
1130
1036
  removeListener(image, EVENT_LOAD, onLoad);
1131
-
1132
1037
  if (options.loading) {
1133
1038
  removeClass(item, CLASS_LOADING);
1134
1039
  }
@@ -1136,7 +1041,6 @@ var render = {
1136
1041
  once: true
1137
1042
  });
1138
1043
  });
1139
-
1140
1044
  if (options.transition) {
1141
1045
  addListener(element, EVENT_VIEWED, function () {
1142
1046
  addClass(list, CLASS_TRANSITION);
@@ -1148,16 +1052,15 @@ var render = {
1148
1052
  renderList: function renderList() {
1149
1053
  var index = this.index;
1150
1054
  var item = this.items[index];
1151
-
1152
1055
  if (!item) {
1153
1056
  return;
1154
1057
  }
1155
-
1156
1058
  var next = item.nextElementSibling;
1157
1059
  var gutter = parseInt(window.getComputedStyle(next || item).marginLeft, 10);
1158
1060
  var offsetWidth = item.offsetWidth;
1159
- var outerWidth = offsetWidth + gutter; // Place the active item in the center of the screen
1061
+ var outerWidth = offsetWidth + gutter;
1160
1062
 
1063
+ // Place the active item in the center of the screen
1161
1064
  setStyle(this.list, assign({
1162
1065
  width: outerWidth * this.length - gutter
1163
1066
  }, getTransforms({
@@ -1174,10 +1077,9 @@ var render = {
1174
1077
  },
1175
1078
  initImage: function initImage(done) {
1176
1079
  var _this2 = this;
1177
-
1178
1080
  var options = this.options,
1179
- image = this.image,
1180
- viewerData = this.viewerData;
1081
+ image = this.image,
1082
+ viewerData = this.viewerData;
1181
1083
  var footerHeight = this.footer.offsetHeight;
1182
1084
  var viewerWidth = viewerData.width;
1183
1085
  var viewerHeight = Math.max(viewerData.height - footerHeight, footerHeight);
@@ -1190,18 +1092,18 @@ var render = {
1190
1092
  };
1191
1093
  sizingImage = getImageNaturalSizes(image, options, function (naturalWidth, naturalHeight) {
1192
1094
  var aspectRatio = naturalWidth / naturalHeight;
1095
+ var initialCoverage = Math.max(0, Math.min(1, options.initialCoverage));
1193
1096
  var width = viewerWidth;
1194
1097
  var height = viewerHeight;
1195
1098
  _this2.imageInitializing = false;
1196
-
1197
1099
  if (viewerHeight * aspectRatio > viewerWidth) {
1198
1100
  height = viewerWidth / aspectRatio;
1199
1101
  } else {
1200
1102
  width = viewerHeight * aspectRatio;
1201
1103
  }
1202
-
1203
- width = Math.min(width * 0.9, naturalWidth);
1204
- height = Math.min(height * 0.9, naturalHeight);
1104
+ initialCoverage = isNumber(initialCoverage) ? initialCoverage : 0.9;
1105
+ width = Math.min(width * initialCoverage, naturalWidth);
1106
+ height = Math.min(height * initialCoverage, naturalHeight);
1205
1107
  var left = (viewerWidth - width) / 2;
1206
1108
  var top = (viewerHeight - height) / 2;
1207
1109
  var imageData = {
@@ -1218,22 +1120,18 @@ var render = {
1218
1120
  naturalHeight: naturalHeight
1219
1121
  };
1220
1122
  var initialImageData = assign({}, imageData);
1221
-
1222
1123
  if (options.rotatable) {
1223
1124
  imageData.rotate = oldImageData.rotate || 0;
1224
1125
  initialImageData.rotate = 0;
1225
1126
  }
1226
-
1227
1127
  if (options.scalable) {
1228
1128
  imageData.scaleX = oldImageData.scaleX || 1;
1229
1129
  imageData.scaleY = oldImageData.scaleY || 1;
1230
1130
  initialImageData.scaleX = 1;
1231
1131
  initialImageData.scaleY = 1;
1232
1132
  }
1233
-
1234
1133
  _this2.imageData = imageData;
1235
1134
  _this2.initialImageData = initialImageData;
1236
-
1237
1135
  if (done) {
1238
1136
  done();
1239
1137
  }
@@ -1241,9 +1139,8 @@ var render = {
1241
1139
  },
1242
1140
  renderImage: function renderImage(done) {
1243
1141
  var _this3 = this;
1244
-
1245
1142
  var image = this.image,
1246
- imageData = this.imageData;
1143
+ imageData = this.imageData;
1247
1144
  setStyle(image, assign({
1248
1145
  width: imageData.width,
1249
1146
  height: imageData.height,
@@ -1251,14 +1148,12 @@ var render = {
1251
1148
  marginLeft: imageData.x,
1252
1149
  marginTop: imageData.y
1253
1150
  }, getTransforms(imageData)));
1254
-
1255
1151
  if (done) {
1256
1152
  if ((this.viewing || this.moving || this.rotating || this.scaling || this.zooming) && this.options.transition && hasClass(image, CLASS_TRANSITION)) {
1257
1153
  var onTransitionEnd = function onTransitionEnd() {
1258
1154
  _this3.imageRendering = false;
1259
1155
  done();
1260
1156
  };
1261
-
1262
1157
  this.imageRendering = {
1263
1158
  abort: function abort() {
1264
1159
  removeListener(image, EVENT_TRANSITION_END, onTransitionEnd);
@@ -1276,11 +1171,9 @@ var render = {
1276
1171
  // this.image only defined after viewed
1277
1172
  if (this.viewing || this.viewed) {
1278
1173
  var image = this.image;
1279
-
1280
1174
  if (this.viewing) {
1281
1175
  this.viewing.abort();
1282
1176
  }
1283
-
1284
1177
  image.parentNode.removeChild(image);
1285
1178
  this.image = null;
1286
1179
  }
@@ -1290,8 +1183,8 @@ var render = {
1290
1183
  var events = {
1291
1184
  bind: function bind() {
1292
1185
  var options = this.options,
1293
- viewer = this.viewer,
1294
- canvas = this.canvas;
1186
+ viewer = this.viewer,
1187
+ canvas = this.canvas;
1295
1188
  var document = this.element.ownerDocument;
1296
1189
  addListener(viewer, EVENT_CLICK, this.onClick = this.click.bind(this));
1297
1190
  addListener(viewer, EVENT_DRAG_START, this.onDragStart = this.dragstart.bind(this));
@@ -1300,22 +1193,20 @@ var events = {
1300
1193
  addListener(document, EVENT_POINTER_UP, this.onPointerUp = this.pointerup.bind(this));
1301
1194
  addListener(document, EVENT_KEY_DOWN, this.onKeyDown = this.keydown.bind(this));
1302
1195
  addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this));
1303
-
1304
1196
  if (options.zoomable && options.zoomOnWheel) {
1305
1197
  addListener(viewer, EVENT_WHEEL, this.onWheel = this.wheel.bind(this), {
1306
1198
  passive: false,
1307
1199
  capture: true
1308
1200
  });
1309
1201
  }
1310
-
1311
1202
  if (options.toggleOnDblclick) {
1312
1203
  addListener(canvas, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(this));
1313
1204
  }
1314
1205
  },
1315
1206
  unbind: function unbind() {
1316
1207
  var options = this.options,
1317
- viewer = this.viewer,
1318
- canvas = this.canvas;
1208
+ viewer = this.viewer,
1209
+ canvas = this.canvas;
1319
1210
  var document = this.element.ownerDocument;
1320
1211
  removeListener(viewer, EVENT_CLICK, this.onClick);
1321
1212
  removeListener(viewer, EVENT_DRAG_START, this.onDragStart);
@@ -1324,14 +1215,12 @@ var events = {
1324
1215
  removeListener(document, EVENT_POINTER_UP, this.onPointerUp);
1325
1216
  removeListener(document, EVENT_KEY_DOWN, this.onKeyDown);
1326
1217
  removeListener(window, EVENT_RESIZE, this.onResize);
1327
-
1328
1218
  if (options.zoomable && options.zoomOnWheel) {
1329
1219
  removeListener(viewer, EVENT_WHEEL, this.onWheel, {
1330
1220
  passive: false,
1331
1221
  capture: true
1332
1222
  });
1333
1223
  }
1334
-
1335
1224
  if (options.toggleOnDblclick) {
1336
1225
  removeListener(canvas, EVENT_DBLCLICK, this.onDblclick);
1337
1226
  }
@@ -1341,20 +1230,18 @@ var events = {
1341
1230
  var handlers = {
1342
1231
  click: function click(event) {
1343
1232
  var options = this.options,
1344
- imageData = this.imageData;
1233
+ imageData = this.imageData;
1345
1234
  var target = event.target;
1346
1235
  var action = getData(target, DATA_ACTION);
1347
-
1348
1236
  if (!action && target.localName === 'img' && target.parentElement.localName === 'li') {
1349
1237
  target = target.parentElement;
1350
1238
  action = getData(target, DATA_ACTION);
1351
- } // Cancel the emulated click when the native click event was triggered.
1352
-
1239
+ }
1353
1240
 
1241
+ // Cancel the emulated click when the native click event was triggered.
1354
1242
  if (IS_TOUCH_DEVICE && event.isTrusted && target === this.canvas) {
1355
1243
  clearTimeout(this.clickCanvasTimeout);
1356
1244
  }
1357
-
1358
1245
  switch (action) {
1359
1246
  case 'mix':
1360
1247
  if (this.played) {
@@ -1368,115 +1255,91 @@ var handlers = {
1368
1255
  } else {
1369
1256
  this.hide();
1370
1257
  }
1371
-
1372
1258
  break;
1373
-
1374
1259
  case 'hide':
1375
1260
  this.hide();
1376
1261
  break;
1377
-
1378
1262
  case 'view':
1379
1263
  this.view(getData(target, 'index'));
1380
1264
  break;
1381
-
1382
1265
  case 'zoom-in':
1383
1266
  this.zoom(0.1, true);
1384
1267
  break;
1385
-
1386
1268
  case 'zoom-out':
1387
1269
  this.zoom(-0.1, true);
1388
1270
  break;
1389
-
1390
1271
  case 'one-to-one':
1391
1272
  this.toggle();
1392
1273
  break;
1393
-
1394
1274
  case 'reset':
1395
1275
  this.reset();
1396
1276
  break;
1397
-
1398
1277
  case 'prev':
1399
1278
  this.prev(options.loop);
1400
1279
  break;
1401
-
1402
1280
  case 'play':
1403
1281
  this.play(options.fullscreen);
1404
1282
  break;
1405
-
1406
1283
  case 'next':
1407
1284
  this.next(options.loop);
1408
1285
  break;
1409
-
1410
1286
  case 'rotate-left':
1411
1287
  this.rotate(-90);
1412
1288
  break;
1413
-
1414
1289
  case 'rotate-right':
1415
1290
  this.rotate(90);
1416
1291
  break;
1417
-
1418
1292
  case 'flip-horizontal':
1419
1293
  this.scaleX(-imageData.scaleX || -1);
1420
1294
  break;
1421
-
1422
1295
  case 'flip-vertical':
1423
1296
  this.scaleY(-imageData.scaleY || -1);
1424
1297
  break;
1425
-
1426
1298
  default:
1427
1299
  if (this.played) {
1428
1300
  this.stop();
1429
1301
  }
1430
-
1431
1302
  }
1432
1303
  },
1433
1304
  dblclick: function dblclick(event) {
1434
1305
  event.preventDefault();
1435
-
1436
1306
  if (this.viewed && event.target === this.image) {
1437
1307
  // Cancel the emulated double click when the native dblclick event was triggered.
1438
1308
  if (IS_TOUCH_DEVICE && event.isTrusted) {
1439
1309
  clearTimeout(this.doubleClickImageTimeout);
1440
- } // XXX: No pageX/Y properties in custom event, fallback to the original event.
1441
-
1310
+ }
1442
1311
 
1312
+ // XXX: No pageX/Y properties in custom event, fallback to the original event.
1443
1313
  this.toggle(event.isTrusted ? event : event.detail && event.detail.originalEvent);
1444
1314
  }
1445
1315
  },
1446
1316
  load: function load() {
1447
1317
  var _this = this;
1448
-
1449
1318
  if (this.timeout) {
1450
1319
  clearTimeout(this.timeout);
1451
1320
  this.timeout = false;
1452
1321
  }
1453
-
1454
1322
  var element = this.element,
1455
- options = this.options,
1456
- image = this.image,
1457
- index = this.index,
1458
- viewerData = this.viewerData;
1323
+ options = this.options,
1324
+ image = this.image,
1325
+ index = this.index,
1326
+ viewerData = this.viewerData;
1459
1327
  removeClass(image, CLASS_INVISIBLE);
1460
-
1461
1328
  if (options.loading) {
1462
1329
  removeClass(this.canvas, CLASS_LOADING);
1463
1330
  }
1464
-
1465
1331
  image.style.cssText = 'height:0;' + "margin-left:".concat(viewerData.width / 2, "px;") + "margin-top:".concat(viewerData.height / 2, "px;") + 'max-width:none!important;' + 'position:relative;' + 'width:0;';
1466
1332
  this.initImage(function () {
1467
1333
  toggleClass(image, CLASS_MOVE, options.movable);
1468
1334
  toggleClass(image, CLASS_TRANSITION, options.transition);
1469
-
1470
1335
  _this.renderImage(function () {
1471
1336
  _this.viewed = true;
1472
1337
  _this.viewing = false;
1473
-
1474
1338
  if (isFunction(options.viewed)) {
1475
1339
  addListener(element, EVENT_VIEWED, options.viewed, {
1476
1340
  once: true
1477
1341
  });
1478
1342
  }
1479
-
1480
1343
  dispatchEvent(element, EVENT_VIEWED, {
1481
1344
  originalImage: _this.images[index],
1482
1345
  index: index,
@@ -1497,7 +1360,6 @@ var handlers = {
1497
1360
  var aspectRatio = naturalWidth / naturalHeight;
1498
1361
  var width = parentWidth;
1499
1362
  var height = parentHeight;
1500
-
1501
1363
  if (parentHeight * aspectRatio > parentWidth) {
1502
1364
  if (filled) {
1503
1365
  width = parentHeight * aspectRatio;
@@ -1509,7 +1371,6 @@ var handlers = {
1509
1371
  } else {
1510
1372
  width = parentHeight * aspectRatio;
1511
1373
  }
1512
-
1513
1374
  setStyle(image, assign({
1514
1375
  width: width,
1515
1376
  height: height
@@ -1521,27 +1382,21 @@ var handlers = {
1521
1382
  },
1522
1383
  keydown: function keydown(event) {
1523
1384
  var options = this.options;
1524
-
1525
1385
  if (!options.keyboard) {
1526
1386
  return;
1527
1387
  }
1528
-
1529
1388
  var keyCode = event.keyCode || event.which || event.charCode;
1530
-
1531
1389
  switch (keyCode) {
1532
1390
  // Enter
1533
1391
  case 13:
1534
1392
  if (this.viewer.contains(event.target)) {
1535
1393
  this.click(event);
1536
1394
  }
1537
-
1538
1395
  break;
1539
1396
  }
1540
-
1541
1397
  if (!this.fulled) {
1542
1398
  return;
1543
1399
  }
1544
-
1545
1400
  switch (keyCode) {
1546
1401
  // Escape
1547
1402
  case 27:
@@ -1554,54 +1409,62 @@ var handlers = {
1554
1409
  } else {
1555
1410
  this.hide();
1556
1411
  }
1557
-
1558
1412
  break;
1559
- // Space
1560
1413
 
1414
+ // Space
1561
1415
  case 32:
1562
1416
  if (this.played) {
1563
1417
  this.stop();
1564
1418
  }
1565
-
1566
1419
  break;
1567
- // ArrowLeft
1568
1420
 
1421
+ // ArrowLeft
1569
1422
  case 37:
1570
- this.prev(options.loop);
1423
+ if (this.played && this.playing) {
1424
+ this.playing.prev();
1425
+ } else {
1426
+ this.prev(options.loop);
1427
+ }
1571
1428
  break;
1572
- // ArrowUp
1573
1429
 
1430
+ // ArrowUp
1574
1431
  case 38:
1575
1432
  // Prevent scroll on Firefox
1576
- event.preventDefault(); // Zoom in
1433
+ event.preventDefault();
1577
1434
 
1435
+ // Zoom in
1578
1436
  this.zoom(options.zoomRatio, true);
1579
1437
  break;
1580
- // ArrowRight
1581
1438
 
1439
+ // ArrowRight
1582
1440
  case 39:
1583
- this.next(options.loop);
1441
+ if (this.played && this.playing) {
1442
+ this.playing.next();
1443
+ } else {
1444
+ this.next(options.loop);
1445
+ }
1584
1446
  break;
1585
- // ArrowDown
1586
1447
 
1448
+ // ArrowDown
1587
1449
  case 40:
1588
1450
  // Prevent scroll on Firefox
1589
- event.preventDefault(); // Zoom out
1451
+ event.preventDefault();
1590
1452
 
1453
+ // Zoom out
1591
1454
  this.zoom(-options.zoomRatio, true);
1592
1455
  break;
1456
+
1593
1457
  // Ctrl + 0
1458
+ case 48:
1459
+ // Fall through
1594
1460
 
1595
- case 48: // Fall through
1596
1461
  // Ctrl + 1
1597
1462
  // eslint-disable-next-line no-fallthrough
1598
-
1599
1463
  case 49:
1600
1464
  if (event.ctrlKey) {
1601
1465
  event.preventDefault();
1602
1466
  this.toggle();
1603
1467
  }
1604
-
1605
1468
  break;
1606
1469
  }
1607
1470
  },
@@ -1612,20 +1475,23 @@ var handlers = {
1612
1475
  },
1613
1476
  pointerdown: function pointerdown(event) {
1614
1477
  var options = this.options,
1615
- pointers = this.pointers;
1478
+ pointers = this.pointers;
1616
1479
  var buttons = event.buttons,
1617
- button = event.button;
1480
+ button = event.button;
1481
+ if (!this.viewed || this.showing || this.viewing || this.hiding
1482
+
1483
+ // Handle mouse event and pointer event and ignore touch event
1484
+ || (event.type === 'mousedown' || event.type === 'pointerdown' && event.pointerType === 'mouse') && (
1485
+ // No primary button (Usually the left button)
1486
+ isNumber(buttons) && buttons !== 1 || isNumber(button) && button !== 0
1618
1487
 
1619
- if (!this.viewed || this.showing || this.viewing || this.hiding // Handle mouse event and pointer event and ignore touch event
1620
- || (event.type === 'mousedown' || event.type === 'pointerdown' && event.pointerType === 'mouse') && ( // No primary button (Usually the left button)
1621
- isNumber(buttons) && buttons !== 1 || isNumber(button) && button !== 0 // Open context menu
1488
+ // Open context menu
1622
1489
  || event.ctrlKey)) {
1623
1490
  return;
1624
- } // Prevent default behaviours as page zooming in touch devices.
1625
-
1491
+ }
1626
1492
 
1493
+ // Prevent default behaviours as page zooming in touch devices.
1627
1494
  event.preventDefault();
1628
-
1629
1495
  if (event.changedTouches) {
1630
1496
  forEach(event.changedTouches, function (touch) {
1631
1497
  pointers[touch.identifier] = getPointer(touch);
@@ -1633,31 +1499,24 @@ var handlers = {
1633
1499
  } else {
1634
1500
  pointers[event.pointerId || 0] = getPointer(event);
1635
1501
  }
1636
-
1637
1502
  var action = options.movable ? ACTION_MOVE : false;
1638
-
1639
1503
  if (options.zoomOnTouch && options.zoomable && Object.keys(pointers).length > 1) {
1640
1504
  action = ACTION_ZOOM;
1641
1505
  } else if (options.slideOnTouch && (event.pointerType === 'touch' || event.type === 'touchstart') && this.isSwitchable()) {
1642
1506
  action = ACTION_SWITCH;
1643
1507
  }
1644
-
1645
1508
  if (options.transition && (action === ACTION_MOVE || action === ACTION_ZOOM)) {
1646
1509
  removeClass(this.image, CLASS_TRANSITION);
1647
1510
  }
1648
-
1649
1511
  this.action = action;
1650
1512
  },
1651
1513
  pointermove: function pointermove(event) {
1652
1514
  var pointers = this.pointers,
1653
- action = this.action;
1654
-
1515
+ action = this.action;
1655
1516
  if (!this.viewed || !action) {
1656
1517
  return;
1657
1518
  }
1658
-
1659
1519
  event.preventDefault();
1660
-
1661
1520
  if (event.changedTouches) {
1662
1521
  forEach(event.changedTouches, function (touch) {
1663
1522
  assign(pointers[touch.identifier] || {}, getPointer(touch, true));
@@ -1665,17 +1524,14 @@ var handlers = {
1665
1524
  } else {
1666
1525
  assign(pointers[event.pointerId || 0] || {}, getPointer(event, true));
1667
1526
  }
1668
-
1669
1527
  this.change(event);
1670
1528
  },
1671
1529
  pointerup: function pointerup(event) {
1672
1530
  var _this2 = this;
1673
-
1674
1531
  var options = this.options,
1675
- action = this.action,
1676
- pointers = this.pointers;
1532
+ action = this.action,
1533
+ pointers = this.pointers;
1677
1534
  var pointer;
1678
-
1679
1535
  if (event.changedTouches) {
1680
1536
  forEach(event.changedTouches, function (touch) {
1681
1537
  pointer = pointers[touch.identifier];
@@ -1685,42 +1541,39 @@ var handlers = {
1685
1541
  pointer = pointers[event.pointerId || 0];
1686
1542
  delete pointers[event.pointerId || 0];
1687
1543
  }
1688
-
1689
1544
  if (!action) {
1690
1545
  return;
1691
1546
  }
1692
-
1693
1547
  event.preventDefault();
1694
-
1695
1548
  if (options.transition && (action === ACTION_MOVE || action === ACTION_ZOOM)) {
1696
1549
  addClass(this.image, CLASS_TRANSITION);
1697
1550
  }
1551
+ this.action = false;
1698
1552
 
1699
- this.action = false; // Emulate click and double click in touch devices to support backdrop and image zooming (#210).
1700
-
1553
+ // Emulate click and double click in touch devices to support backdrop and image zooming (#210).
1701
1554
  if (IS_TOUCH_DEVICE && action !== ACTION_ZOOM && pointer && Date.now() - pointer.timeStamp < 500) {
1702
1555
  clearTimeout(this.clickCanvasTimeout);
1703
1556
  clearTimeout(this.doubleClickImageTimeout);
1704
-
1705
1557
  if (options.toggleOnDblclick && this.viewed && event.target === this.image) {
1706
1558
  if (this.imageClicked) {
1707
- this.imageClicked = false; // This timeout will be cleared later when a native dblclick event is triggering
1559
+ this.imageClicked = false;
1708
1560
 
1561
+ // This timeout will be cleared later when a native dblclick event is triggering
1709
1562
  this.doubleClickImageTimeout = setTimeout(function () {
1710
1563
  dispatchEvent(_this2.image, EVENT_DBLCLICK, {
1711
1564
  originalEvent: event
1712
1565
  });
1713
1566
  }, 50);
1714
1567
  } else {
1715
- this.imageClicked = true; // The default timing of a double click in Windows is 500 ms
1568
+ this.imageClicked = true;
1716
1569
 
1570
+ // The default timing of a double click in Windows is 500 ms
1717
1571
  this.doubleClickImageTimeout = setTimeout(function () {
1718
1572
  _this2.imageClicked = false;
1719
1573
  }, 500);
1720
1574
  }
1721
1575
  } else {
1722
1576
  this.imageClicked = false;
1723
-
1724
1577
  if (options.backdrop && options.backdrop !== 'static' && event.target === this.canvas) {
1725
1578
  // This timeout will be cleared later when a native click event is triggering
1726
1579
  this.clickCanvasTimeout = setTimeout(function () {
@@ -1734,34 +1587,28 @@ var handlers = {
1734
1587
  },
1735
1588
  resize: function resize() {
1736
1589
  var _this3 = this;
1737
-
1738
1590
  if (!this.isShown || this.hiding) {
1739
1591
  return;
1740
1592
  }
1741
-
1742
1593
  if (this.fulled) {
1743
1594
  this.close();
1744
1595
  this.initBody();
1745
1596
  this.open();
1746
1597
  }
1747
-
1748
1598
  this.initContainer();
1749
1599
  this.initViewer();
1750
1600
  this.renderViewer();
1751
1601
  this.renderList();
1752
-
1753
1602
  if (this.viewed) {
1754
1603
  this.initImage(function () {
1755
1604
  _this3.renderImage();
1756
1605
  });
1757
1606
  }
1758
-
1759
1607
  if (this.played) {
1760
1608
  if (this.options.fullscreen && this.fulled && !(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement)) {
1761
1609
  this.stop();
1762
1610
  return;
1763
1611
  }
1764
-
1765
1612
  forEach(this.player.getElementsByTagName('img'), function (image) {
1766
1613
  addListener(image, EVENT_LOAD, _this3.loadImage.bind(_this3), {
1767
1614
  once: true
@@ -1772,24 +1619,21 @@ var handlers = {
1772
1619
  },
1773
1620
  wheel: function wheel(event) {
1774
1621
  var _this4 = this;
1775
-
1776
1622
  if (!this.viewed) {
1777
1623
  return;
1778
1624
  }
1625
+ event.preventDefault();
1779
1626
 
1780
- event.preventDefault(); // Limit wheel speed to prevent zoom too fast
1781
-
1627
+ // Limit wheel speed to prevent zoom too fast
1782
1628
  if (this.wheeling) {
1783
1629
  return;
1784
1630
  }
1785
-
1786
1631
  this.wheeling = true;
1787
1632
  setTimeout(function () {
1788
1633
  _this4.wheeling = false;
1789
1634
  }, 50);
1790
1635
  var ratio = Number(this.options.zoomRatio) || 0.1;
1791
1636
  var delta = 1;
1792
-
1793
1637
  if (event.deltaY) {
1794
1638
  delta = event.deltaY > 0 ? 1 : -1;
1795
1639
  } else if (event.wheelDelta) {
@@ -1797,8 +1641,7 @@ var handlers = {
1797
1641
  } else if (event.detail) {
1798
1642
  delta = event.detail > 0 ? 1 : -1;
1799
1643
  }
1800
-
1801
- this.zoom(-delta * ratio, true, event);
1644
+ this.zoom(-delta * ratio, true, null, event);
1802
1645
  }
1803
1646
  };
1804
1647
 
@@ -1810,36 +1653,28 @@ var methods = {
1810
1653
  show: function show() {
1811
1654
  var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
1812
1655
  var element = this.element,
1813
- options = this.options;
1814
-
1656
+ options = this.options;
1815
1657
  if (options.inline || this.showing || this.isShown || this.showing) {
1816
1658
  return this;
1817
1659
  }
1818
-
1819
1660
  if (!this.ready) {
1820
1661
  this.build();
1821
-
1822
1662
  if (this.ready) {
1823
1663
  this.show(immediate);
1824
1664
  }
1825
-
1826
1665
  return this;
1827
1666
  }
1828
-
1829
1667
  if (isFunction(options.show)) {
1830
1668
  addListener(element, EVENT_SHOW, options.show, {
1831
1669
  once: true
1832
1670
  });
1833
1671
  }
1834
-
1835
1672
  if (dispatchEvent(element, EVENT_SHOW) === false || !this.ready) {
1836
1673
  return this;
1837
1674
  }
1838
-
1839
1675
  if (this.hiding) {
1840
1676
  this.transitioning.abort();
1841
1677
  }
1842
-
1843
1678
  this.showing = true;
1844
1679
  this.open();
1845
1680
  var viewer = this.viewer;
@@ -1848,7 +1683,6 @@ var methods = {
1848
1683
  viewer.setAttribute('aria-labelledby', this.title.id);
1849
1684
  viewer.setAttribute('aria-modal', true);
1850
1685
  viewer.removeAttribute('aria-hidden');
1851
-
1852
1686
  if (options.transition && !immediate) {
1853
1687
  var shown = this.shown.bind(this);
1854
1688
  this.transitioning = {
@@ -1857,8 +1691,9 @@ var methods = {
1857
1691
  removeClass(viewer, CLASS_IN);
1858
1692
  }
1859
1693
  };
1860
- addClass(viewer, CLASS_TRANSITION); // Force reflow to enable CSS3 transition
1694
+ addClass(viewer, CLASS_TRANSITION);
1861
1695
 
1696
+ // Force reflow to enable CSS3 transition
1862
1697
  viewer.initialOffsetWidth = viewer.offsetWidth;
1863
1698
  addListener(viewer, EVENT_TRANSITION_END, shown, {
1864
1699
  once: true
@@ -1868,10 +1703,8 @@ var methods = {
1868
1703
  addClass(viewer, CLASS_IN);
1869
1704
  this.shown();
1870
1705
  }
1871
-
1872
1706
  return this;
1873
1707
  },
1874
-
1875
1708
  /**
1876
1709
  * Hide the viewer (only available in modal mode)
1877
1710
  * @param {boolean} [immediate=false] - Indicates if hide the viewer immediately or not.
@@ -1879,56 +1712,43 @@ var methods = {
1879
1712
  */
1880
1713
  hide: function hide() {
1881
1714
  var _this = this;
1882
-
1883
1715
  var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
1884
1716
  var element = this.element,
1885
- options = this.options;
1886
-
1717
+ options = this.options;
1887
1718
  if (options.inline || this.hiding || !(this.isShown || this.showing)) {
1888
1719
  return this;
1889
1720
  }
1890
-
1891
1721
  if (isFunction(options.hide)) {
1892
1722
  addListener(element, EVENT_HIDE, options.hide, {
1893
1723
  once: true
1894
1724
  });
1895
1725
  }
1896
-
1897
1726
  if (dispatchEvent(element, EVENT_HIDE) === false) {
1898
1727
  return this;
1899
1728
  }
1900
-
1901
1729
  if (this.showing) {
1902
1730
  this.transitioning.abort();
1903
1731
  }
1904
-
1905
1732
  this.hiding = true;
1906
-
1907
1733
  if (this.played) {
1908
1734
  this.stop();
1909
1735
  } else if (this.viewing) {
1910
1736
  this.viewing.abort();
1911
1737
  }
1912
-
1913
1738
  var viewer = this.viewer,
1914
- image = this.image;
1915
-
1739
+ image = this.image;
1916
1740
  var hideImmediately = function hideImmediately() {
1917
1741
  removeClass(viewer, CLASS_IN);
1918
-
1919
1742
  _this.hidden();
1920
1743
  };
1921
-
1922
1744
  if (options.transition && !immediate) {
1923
1745
  var onViewerTransitionEnd = function onViewerTransitionEnd(event) {
1924
1746
  // Ignore all propagating `transitionend` events (#275).
1925
1747
  if (event && event.target === viewer) {
1926
1748
  removeListener(viewer, EVENT_TRANSITION_END, onViewerTransitionEnd);
1927
-
1928
1749
  _this.hidden();
1929
1750
  }
1930
1751
  };
1931
-
1932
1752
  var onImageTransitionEnd = function onImageTransitionEnd() {
1933
1753
  // In case of show the viewer by `viewer.show(true)` previously (#407).
1934
1754
  if (hasClass(viewer, CLASS_TRANSITION)) {
@@ -1938,7 +1758,6 @@ var methods = {
1938
1758
  hideImmediately();
1939
1759
  }
1940
1760
  };
1941
-
1942
1761
  this.transitioning = {
1943
1762
  abort: function abort() {
1944
1763
  if (_this.viewed && hasClass(image, CLASS_TRANSITION)) {
@@ -1947,24 +1766,23 @@ var methods = {
1947
1766
  removeListener(viewer, EVENT_TRANSITION_END, onViewerTransitionEnd);
1948
1767
  }
1949
1768
  }
1950
- }; // In case of hiding the viewer when holding on the image (#255),
1951
- // note that the `CLASS_TRANSITION` class will be removed on pointer down.
1769
+ };
1952
1770
 
1771
+ // In case of hiding the viewer when holding on the image (#255),
1772
+ // note that the `CLASS_TRANSITION` class will be removed on pointer down.
1953
1773
  if (this.viewed && hasClass(image, CLASS_TRANSITION)) {
1954
1774
  addListener(image, EVENT_TRANSITION_END, onImageTransitionEnd, {
1955
1775
  once: true
1956
1776
  });
1957
- this.zoomTo(0, false, null, true);
1777
+ this.zoomTo(0, false, null, null, true);
1958
1778
  } else {
1959
1779
  onImageTransitionEnd();
1960
1780
  }
1961
1781
  } else {
1962
1782
  hideImmediately();
1963
1783
  }
1964
-
1965
1784
  return this;
1966
1785
  },
1967
-
1968
1786
  /**
1969
1787
  * View one of the images with image's index
1970
1788
  * @param {number} index - The index of the image to view.
@@ -1972,27 +1790,22 @@ var methods = {
1972
1790
  */
1973
1791
  view: function view() {
1974
1792
  var _this2 = this;
1975
-
1976
1793
  var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.options.initialViewIndex;
1977
1794
  index = Number(index) || 0;
1978
-
1979
1795
  if (this.hiding || this.played || index < 0 || index >= this.length || this.viewed && index === this.index) {
1980
1796
  return this;
1981
1797
  }
1982
-
1983
1798
  if (!this.isShown) {
1984
1799
  this.index = index;
1985
1800
  return this.show();
1986
1801
  }
1987
-
1988
1802
  if (this.viewing) {
1989
1803
  this.viewing.abort();
1990
1804
  }
1991
-
1992
1805
  var element = this.element,
1993
- options = this.options,
1994
- title = this.title,
1995
- canvas = this.canvas;
1806
+ options = this.options,
1807
+ title = this.title,
1808
+ canvas = this.canvas;
1996
1809
  var item = this.items[index];
1997
1810
  var img = item.querySelector('img');
1998
1811
  var url = getData(img, 'originalUrl');
@@ -2000,20 +1813,17 @@ var methods = {
2000
1813
  var image = document.createElement('img');
2001
1814
  forEach(options.inheritedAttributes, function (name) {
2002
1815
  var value = img.getAttribute(name);
2003
-
2004
1816
  if (value !== null) {
2005
1817
  image.setAttribute(name, value);
2006
1818
  }
2007
1819
  });
2008
1820
  image.src = url;
2009
1821
  image.alt = alt;
2010
-
2011
1822
  if (isFunction(options.view)) {
2012
1823
  addListener(element, EVENT_VIEW, options.view, {
2013
1824
  once: true
2014
1825
  });
2015
1826
  }
2016
-
2017
1827
  if (dispatchEvent(element, EVENT_VIEW, {
2018
1828
  originalImage: this.images[index],
2019
1829
  index: index,
@@ -2021,44 +1831,39 @@ var methods = {
2021
1831
  }) === false || !this.isShown || this.hiding || this.played) {
2022
1832
  return this;
2023
1833
  }
2024
-
2025
1834
  var activeItem = this.items[this.index];
2026
-
2027
1835
  if (activeItem) {
2028
1836
  removeClass(activeItem, CLASS_ACTIVE);
2029
1837
  activeItem.removeAttribute('aria-selected');
2030
1838
  }
2031
-
2032
1839
  addClass(item, CLASS_ACTIVE);
2033
1840
  item.setAttribute('aria-selected', true);
2034
-
2035
1841
  if (options.focus) {
2036
1842
  item.focus();
2037
1843
  }
2038
-
2039
1844
  this.image = image;
2040
1845
  this.viewed = false;
2041
1846
  this.index = index;
2042
1847
  this.imageData = {};
2043
1848
  addClass(image, CLASS_INVISIBLE);
2044
-
2045
1849
  if (options.loading) {
2046
1850
  addClass(canvas, CLASS_LOADING);
2047
1851
  }
2048
-
2049
1852
  canvas.innerHTML = '';
2050
- canvas.appendChild(image); // Center current item
1853
+ canvas.appendChild(image);
2051
1854
 
2052
- this.renderList(); // Clear title
1855
+ // Center current item
1856
+ this.renderList();
2053
1857
 
2054
- title.innerHTML = ''; // Generate title after viewed
1858
+ // Clear title
1859
+ title.innerHTML = '';
2055
1860
 
1861
+ // Generate title after viewed
2056
1862
  var onViewed = function onViewed() {
2057
1863
  var imageData = _this2.imageData;
2058
1864
  var render = Array.isArray(options.title) ? options.title[1] : options.title;
2059
1865
  title.innerHTML = escapeHTMLEntities(isFunction(render) ? render.call(_this2, image, imageData) : "".concat(alt, " (").concat(imageData.naturalWidth, " \xD7 ").concat(imageData.naturalHeight, ")"));
2060
1866
  };
2061
-
2062
1867
  var onLoad;
2063
1868
  var onError;
2064
1869
  addListener(element, EVENT_VIEWED, onViewed, {
@@ -2067,7 +1872,6 @@ var methods = {
2067
1872
  this.viewing = {
2068
1873
  abort: function abort() {
2069
1874
  removeListener(element, EVENT_VIEWED, onViewed);
2070
-
2071
1875
  if (image.complete) {
2072
1876
  if (_this2.imageRendering) {
2073
1877
  _this2.imageRendering.abort();
@@ -2078,55 +1882,46 @@ var methods = {
2078
1882
  // Cancel download to save bandwidth.
2079
1883
  image.src = '';
2080
1884
  removeListener(image, EVENT_LOAD, onLoad);
2081
-
2082
1885
  if (_this2.timeout) {
2083
1886
  clearTimeout(_this2.timeout);
2084
1887
  }
2085
1888
  }
2086
1889
  }
2087
1890
  };
2088
-
2089
1891
  if (image.complete) {
2090
1892
  this.load();
2091
1893
  } else {
2092
1894
  addListener(image, EVENT_LOAD, onLoad = function onLoad() {
2093
1895
  removeListener(image, EVENT_ERROR, onError);
2094
-
2095
1896
  _this2.load();
2096
1897
  }, {
2097
1898
  once: true
2098
1899
  });
2099
1900
  addListener(image, EVENT_ERROR, onError = function onError() {
2100
1901
  removeListener(image, EVENT_LOAD, onLoad);
2101
-
2102
1902
  if (_this2.timeout) {
2103
1903
  clearTimeout(_this2.timeout);
2104
1904
  _this2.timeout = false;
2105
1905
  }
2106
-
2107
1906
  removeClass(image, CLASS_INVISIBLE);
2108
-
2109
1907
  if (options.loading) {
2110
1908
  removeClass(_this2.canvas, CLASS_LOADING);
2111
1909
  }
2112
1910
  }, {
2113
1911
  once: true
2114
1912
  });
2115
-
2116
1913
  if (this.timeout) {
2117
1914
  clearTimeout(this.timeout);
2118
- } // Make the image visible if it fails to load within 1s
2119
-
1915
+ }
2120
1916
 
1917
+ // Make the image visible if it fails to load within 1s
2121
1918
  this.timeout = setTimeout(function () {
2122
1919
  removeClass(image, CLASS_INVISIBLE);
2123
1920
  _this2.timeout = false;
2124
1921
  }, 1000);
2125
1922
  }
2126
-
2127
1923
  return this;
2128
1924
  },
2129
-
2130
1925
  /**
2131
1926
  * View the previous image
2132
1927
  * @param {boolean} [loop=false] - Indicate if view the last one
@@ -2136,15 +1931,12 @@ var methods = {
2136
1931
  prev: function prev() {
2137
1932
  var loop = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
2138
1933
  var index = this.index - 1;
2139
-
2140
1934
  if (index < 0) {
2141
1935
  index = loop ? this.length - 1 : 0;
2142
1936
  }
2143
-
2144
1937
  this.view(index);
2145
1938
  return this;
2146
1939
  },
2147
-
2148
1940
  /**
2149
1941
  * View the next image
2150
1942
  * @param {boolean} [loop=false] - Indicate if view the first one
@@ -2155,15 +1947,12 @@ var methods = {
2155
1947
  var loop = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
2156
1948
  var maxIndex = this.length - 1;
2157
1949
  var index = this.index + 1;
2158
-
2159
1950
  if (index > maxIndex) {
2160
1951
  index = loop ? 0 : maxIndex;
2161
1952
  }
2162
-
2163
1953
  this.view(index);
2164
1954
  return this;
2165
1955
  },
2166
-
2167
1956
  /**
2168
1957
  * Move the image with relative offsets.
2169
1958
  * @param {number} x - The moving distance in the horizontal direction.
@@ -2176,7 +1965,6 @@ var methods = {
2176
1965
  this.moveTo(isUndefined(x) ? x : imageData.x + Number(x), isUndefined(y) ? y : imageData.y + Number(y));
2177
1966
  return this;
2178
1967
  },
2179
-
2180
1968
  /**
2181
1969
  * Move the image to an absolute point.
2182
1970
  * @param {number} x - The new position in the horizontal direction.
@@ -2186,41 +1974,33 @@ var methods = {
2186
1974
  */
2187
1975
  moveTo: function moveTo(x) {
2188
1976
  var _this3 = this;
2189
-
2190
1977
  var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x;
2191
-
2192
1978
  var _originalEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
2193
-
2194
1979
  var element = this.element,
2195
- options = this.options,
2196
- imageData = this.imageData;
1980
+ options = this.options,
1981
+ imageData = this.imageData;
2197
1982
  x = Number(x);
2198
1983
  y = Number(y);
2199
-
2200
1984
  if (this.viewed && !this.played && options.movable) {
2201
1985
  var oldX = imageData.x;
2202
1986
  var oldY = imageData.y;
2203
1987
  var changed = false;
2204
-
2205
1988
  if (isNumber(x)) {
2206
1989
  changed = true;
2207
1990
  } else {
2208
1991
  x = oldX;
2209
1992
  }
2210
-
2211
1993
  if (isNumber(y)) {
2212
1994
  changed = true;
2213
1995
  } else {
2214
1996
  y = oldY;
2215
1997
  }
2216
-
2217
1998
  if (changed) {
2218
1999
  if (isFunction(options.move)) {
2219
2000
  addListener(element, EVENT_MOVE, options.move, {
2220
2001
  once: true
2221
2002
  });
2222
2003
  }
2223
-
2224
2004
  if (dispatchEvent(element, EVENT_MOVE, {
2225
2005
  x: x,
2226
2006
  y: y,
@@ -2230,7 +2010,6 @@ var methods = {
2230
2010
  }) === false) {
2231
2011
  return this;
2232
2012
  }
2233
-
2234
2013
  imageData.x = x;
2235
2014
  imageData.y = y;
2236
2015
  imageData.left = x;
@@ -2238,13 +2017,11 @@ var methods = {
2238
2017
  this.moving = true;
2239
2018
  this.renderImage(function () {
2240
2019
  _this3.moving = false;
2241
-
2242
2020
  if (isFunction(options.moved)) {
2243
2021
  addListener(element, EVENT_MOVED, options.moved, {
2244
2022
  once: true
2245
2023
  });
2246
2024
  }
2247
-
2248
2025
  dispatchEvent(element, EVENT_MOVED, {
2249
2026
  x: x,
2250
2027
  y: y,
@@ -2257,10 +2034,8 @@ var methods = {
2257
2034
  });
2258
2035
  }
2259
2036
  }
2260
-
2261
2037
  return this;
2262
2038
  },
2263
-
2264
2039
  /**
2265
2040
  * Rotate the image with a relative degree.
2266
2041
  * @param {number} degree - The rotate degree.
@@ -2270,7 +2045,6 @@ var methods = {
2270
2045
  this.rotateTo((this.imageData.rotate || 0) + Number(degree));
2271
2046
  return this;
2272
2047
  },
2273
-
2274
2048
  /**
2275
2049
  * Rotate the image to an absolute degree.
2276
2050
  * @param {number} degree - The rotate degree.
@@ -2278,39 +2052,32 @@ var methods = {
2278
2052
  */
2279
2053
  rotateTo: function rotateTo(degree) {
2280
2054
  var _this4 = this;
2281
-
2282
2055
  var element = this.element,
2283
- options = this.options,
2284
- imageData = this.imageData;
2056
+ options = this.options,
2057
+ imageData = this.imageData;
2285
2058
  degree = Number(degree);
2286
-
2287
2059
  if (isNumber(degree) && this.viewed && !this.played && options.rotatable) {
2288
2060
  var oldDegree = imageData.rotate;
2289
-
2290
2061
  if (isFunction(options.rotate)) {
2291
2062
  addListener(element, EVENT_ROTATE, options.rotate, {
2292
2063
  once: true
2293
2064
  });
2294
2065
  }
2295
-
2296
2066
  if (dispatchEvent(element, EVENT_ROTATE, {
2297
2067
  degree: degree,
2298
2068
  oldDegree: oldDegree
2299
2069
  }) === false) {
2300
2070
  return this;
2301
2071
  }
2302
-
2303
2072
  imageData.rotate = degree;
2304
2073
  this.rotating = true;
2305
2074
  this.renderImage(function () {
2306
2075
  _this4.rotating = false;
2307
-
2308
2076
  if (isFunction(options.rotated)) {
2309
2077
  addListener(element, EVENT_ROTATED, options.rotated, {
2310
2078
  once: true
2311
2079
  });
2312
2080
  }
2313
-
2314
2081
  dispatchEvent(element, EVENT_ROTATED, {
2315
2082
  degree: degree,
2316
2083
  oldDegree: oldDegree
@@ -2319,10 +2086,8 @@ var methods = {
2319
2086
  });
2320
2087
  });
2321
2088
  }
2322
-
2323
2089
  return this;
2324
2090
  },
2325
-
2326
2091
  /**
2327
2092
  * Scale the image on the x-axis.
2328
2093
  * @param {number} scaleX - The scale ratio on the x-axis.
@@ -2332,7 +2097,6 @@ var methods = {
2332
2097
  this.scale(_scaleX, this.imageData.scaleY);
2333
2098
  return this;
2334
2099
  },
2335
-
2336
2100
  /**
2337
2101
  * Scale the image on the y-axis.
2338
2102
  * @param {number} scaleY - The scale ratio on the y-axis.
@@ -2342,7 +2106,6 @@ var methods = {
2342
2106
  this.scale(this.imageData.scaleX, _scaleY);
2343
2107
  return this;
2344
2108
  },
2345
-
2346
2109
  /**
2347
2110
  * Scale the image.
2348
2111
  * @param {number} scaleX - The scale ratio on the x-axis.
@@ -2351,38 +2114,32 @@ var methods = {
2351
2114
  */
2352
2115
  scale: function scale(scaleX) {
2353
2116
  var _this5 = this;
2354
-
2355
2117
  var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX;
2356
2118
  var element = this.element,
2357
- options = this.options,
2358
- imageData = this.imageData;
2119
+ options = this.options,
2120
+ imageData = this.imageData;
2359
2121
  scaleX = Number(scaleX);
2360
2122
  scaleY = Number(scaleY);
2361
-
2362
2123
  if (this.viewed && !this.played && options.scalable) {
2363
2124
  var oldScaleX = imageData.scaleX;
2364
2125
  var oldScaleY = imageData.scaleY;
2365
2126
  var changed = false;
2366
-
2367
2127
  if (isNumber(scaleX)) {
2368
2128
  changed = true;
2369
2129
  } else {
2370
2130
  scaleX = oldScaleX;
2371
2131
  }
2372
-
2373
2132
  if (isNumber(scaleY)) {
2374
2133
  changed = true;
2375
2134
  } else {
2376
2135
  scaleY = oldScaleY;
2377
2136
  }
2378
-
2379
2137
  if (changed) {
2380
2138
  if (isFunction(options.scale)) {
2381
2139
  addListener(element, EVENT_SCALE, options.scale, {
2382
2140
  once: true
2383
2141
  });
2384
2142
  }
2385
-
2386
2143
  if (dispatchEvent(element, EVENT_SCALE, {
2387
2144
  scaleX: scaleX,
2388
2145
  scaleY: scaleY,
@@ -2391,19 +2148,16 @@ var methods = {
2391
2148
  }) === false) {
2392
2149
  return this;
2393
2150
  }
2394
-
2395
2151
  imageData.scaleX = scaleX;
2396
2152
  imageData.scaleY = scaleY;
2397
2153
  this.scaling = true;
2398
2154
  this.renderImage(function () {
2399
2155
  _this5.scaling = false;
2400
-
2401
2156
  if (isFunction(options.scaled)) {
2402
2157
  addListener(element, EVENT_SCALED, options.scaled, {
2403
2158
  once: true
2404
2159
  });
2405
2160
  }
2406
-
2407
2161
  dispatchEvent(element, EVENT_SCALED, {
2408
2162
  scaleX: scaleX,
2409
2163
  scaleY: scaleY,
@@ -2415,103 +2169,88 @@ var methods = {
2415
2169
  });
2416
2170
  }
2417
2171
  }
2418
-
2419
2172
  return this;
2420
2173
  },
2421
-
2422
2174
  /**
2423
2175
  * Zoom the image with a relative ratio.
2424
2176
  * @param {number} ratio - The target ratio.
2425
- * @param {boolean} [hasTooltip=false] - Indicates if it has a tooltip or not.
2177
+ * @param {boolean} [showTooltip=false] - Indicates whether to show the tooltip.
2178
+ * @param {Object} [pivot] - The pivot point coordinate for zooming.
2426
2179
  * @param {Event} [_originalEvent=null] - The original event if any.
2427
2180
  * @returns {Viewer} this
2428
2181
  */
2429
2182
  zoom: function zoom(ratio) {
2430
- var hasTooltip = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
2431
-
2432
- var _originalEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
2433
-
2183
+ var showTooltip = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
2184
+ var pivot = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
2185
+ var _originalEvent = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
2434
2186
  var imageData = this.imageData;
2435
2187
  ratio = Number(ratio);
2436
-
2437
2188
  if (ratio < 0) {
2438
2189
  ratio = 1 / (1 - ratio);
2439
2190
  } else {
2440
2191
  ratio = 1 + ratio;
2441
2192
  }
2442
-
2443
- this.zoomTo(imageData.width * ratio / imageData.naturalWidth, hasTooltip, _originalEvent);
2193
+ this.zoomTo(imageData.width * ratio / imageData.naturalWidth, showTooltip, pivot, _originalEvent);
2444
2194
  return this;
2445
2195
  },
2446
-
2447
2196
  /**
2448
2197
  * Zoom the image to an absolute ratio.
2449
2198
  * @param {number} ratio - The target ratio.
2450
- * @param {boolean} [hasTooltip=false] - Indicates if it has a tooltip or not.
2199
+ * @param {boolean} [showTooltip] - Indicates whether to show the tooltip.
2200
+ * @param {Object} [pivot] - The pivot point coordinate for zooming.
2451
2201
  * @param {Event} [_originalEvent=null] - The original event if any.
2452
2202
  * @param {Event} [_zoomable=false] - Indicates if the current zoom is available or not.
2453
2203
  * @returns {Viewer} this
2454
2204
  */
2455
2205
  zoomTo: function zoomTo(ratio) {
2456
2206
  var _this6 = this;
2457
-
2458
- var hasTooltip = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
2459
-
2460
- var _originalEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
2461
-
2462
- var _zoomable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
2463
-
2207
+ var showTooltip = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
2208
+ var pivot = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
2209
+ var _originalEvent = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
2210
+ var _zoomable = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
2464
2211
  var element = this.element,
2465
- options = this.options,
2466
- pointers = this.pointers,
2467
- imageData = this.imageData;
2212
+ options = this.options,
2213
+ pointers = this.pointers,
2214
+ imageData = this.imageData;
2468
2215
  var x = imageData.x,
2469
- y = imageData.y,
2470
- width = imageData.width,
2471
- height = imageData.height,
2472
- naturalWidth = imageData.naturalWidth,
2473
- naturalHeight = imageData.naturalHeight;
2216
+ y = imageData.y,
2217
+ width = imageData.width,
2218
+ height = imageData.height,
2219
+ naturalWidth = imageData.naturalWidth,
2220
+ naturalHeight = imageData.naturalHeight;
2474
2221
  ratio = Math.max(0, ratio);
2475
-
2476
2222
  if (isNumber(ratio) && this.viewed && !this.played && (_zoomable || options.zoomable)) {
2477
2223
  if (!_zoomable) {
2478
2224
  var minZoomRatio = Math.max(0.01, options.minZoomRatio);
2479
2225
  var maxZoomRatio = Math.min(100, options.maxZoomRatio);
2480
2226
  ratio = Math.min(Math.max(ratio, minZoomRatio), maxZoomRatio);
2481
2227
  }
2482
-
2483
2228
  if (_originalEvent) {
2484
2229
  switch (_originalEvent.type) {
2485
2230
  case 'wheel':
2486
2231
  if (options.zoomRatio >= 0.055 && ratio > 0.95 && ratio < 1.05) {
2487
2232
  ratio = 1;
2488
2233
  }
2489
-
2490
2234
  break;
2491
-
2492
2235
  case 'pointermove':
2493
2236
  case 'touchmove':
2494
2237
  case 'mousemove':
2495
2238
  if (ratio > 0.99 && ratio < 1.01) {
2496
2239
  ratio = 1;
2497
2240
  }
2498
-
2499
2241
  break;
2500
2242
  }
2501
2243
  }
2502
-
2503
2244
  var newWidth = naturalWidth * ratio;
2504
2245
  var newHeight = naturalHeight * ratio;
2505
2246
  var offsetWidth = newWidth - width;
2506
2247
  var offsetHeight = newHeight - height;
2507
2248
  var oldRatio = imageData.ratio;
2508
-
2509
2249
  if (isFunction(options.zoom)) {
2510
2250
  addListener(element, EVENT_ZOOM, options.zoom, {
2511
2251
  once: true
2512
2252
  });
2513
2253
  }
2514
-
2515
2254
  if (dispatchEvent(element, EVENT_ZOOM, {
2516
2255
  ratio: ratio,
2517
2256
  oldRatio: oldRatio,
@@ -2519,24 +2258,25 @@ var methods = {
2519
2258
  }) === false) {
2520
2259
  return this;
2521
2260
  }
2522
-
2523
2261
  this.zooming = true;
2524
-
2525
2262
  if (_originalEvent) {
2526
2263
  var offset = getOffset(this.viewer);
2527
2264
  var center = pointers && Object.keys(pointers).length > 0 ? getPointersCenter(pointers) : {
2528
2265
  pageX: _originalEvent.pageX,
2529
2266
  pageY: _originalEvent.pageY
2530
- }; // Zoom from the triggering point of the event
2267
+ };
2531
2268
 
2269
+ // Zoom from the triggering point of the event
2532
2270
  imageData.x -= offsetWidth * ((center.pageX - offset.left - x) / width);
2533
2271
  imageData.y -= offsetHeight * ((center.pageY - offset.top - y) / height);
2272
+ } else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) {
2273
+ imageData.x -= offsetWidth * ((pivot.x - x) / width);
2274
+ imageData.y -= offsetHeight * ((pivot.y - y) / height);
2534
2275
  } else {
2535
2276
  // Zoom from the center of the image
2536
2277
  imageData.x -= offsetWidth / 2;
2537
2278
  imageData.y -= offsetHeight / 2;
2538
2279
  }
2539
-
2540
2280
  imageData.left = imageData.x;
2541
2281
  imageData.top = imageData.y;
2542
2282
  imageData.width = newWidth;
@@ -2545,13 +2285,11 @@ var methods = {
2545
2285
  imageData.ratio = ratio;
2546
2286
  this.renderImage(function () {
2547
2287
  _this6.zooming = false;
2548
-
2549
2288
  if (isFunction(options.zoomed)) {
2550
2289
  addListener(element, EVENT_ZOOMED, options.zoomed, {
2551
2290
  once: true
2552
2291
  });
2553
2292
  }
2554
-
2555
2293
  dispatchEvent(element, EVENT_ZOOMED, {
2556
2294
  ratio: ratio,
2557
2295
  oldRatio: oldRatio,
@@ -2560,15 +2298,12 @@ var methods = {
2560
2298
  cancelable: false
2561
2299
  });
2562
2300
  });
2563
-
2564
- if (hasTooltip) {
2301
+ if (showTooltip) {
2565
2302
  this.tooltip();
2566
2303
  }
2567
2304
  }
2568
-
2569
2305
  return this;
2570
2306
  },
2571
-
2572
2307
  /**
2573
2308
  * Play the images
2574
2309
  * @param {boolean|FullscreenOptions} [fullscreen=false] - Indicate if request fullscreen or not.
@@ -2576,26 +2311,20 @@ var methods = {
2576
2311
  */
2577
2312
  play: function play() {
2578
2313
  var _this7 = this;
2579
-
2580
2314
  var fullscreen = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
2581
-
2582
2315
  if (!this.isShown || this.played) {
2583
2316
  return this;
2584
2317
  }
2585
-
2586
2318
  var element = this.element,
2587
- options = this.options;
2588
-
2319
+ options = this.options;
2589
2320
  if (isFunction(options.play)) {
2590
2321
  addListener(element, EVENT_PLAY, options.play, {
2591
2322
  once: true
2592
2323
  });
2593
2324
  }
2594
-
2595
2325
  if (dispatchEvent(element, EVENT_PLAY) === false) {
2596
2326
  return this;
2597
2327
  }
2598
-
2599
2328
  var player = this.player;
2600
2329
  var onLoad = this.loadImage.bind(this);
2601
2330
  var list = [];
@@ -2603,11 +2332,9 @@ var methods = {
2603
2332
  var index = 0;
2604
2333
  this.played = true;
2605
2334
  this.onLoadWhenPlay = onLoad;
2606
-
2607
2335
  if (fullscreen) {
2608
2336
  this.requestFullscreen(fullscreen);
2609
2337
  }
2610
-
2611
2338
  addClass(player, CLASS_SHOW);
2612
2339
  forEach(this.items, function (item, i) {
2613
2340
  var img = item.querySelector('img');
@@ -2618,61 +2345,63 @@ var methods = {
2618
2345
  total += 1;
2619
2346
  addClass(image, CLASS_FADE);
2620
2347
  toggleClass(image, CLASS_TRANSITION, options.transition);
2621
-
2622
2348
  if (hasClass(item, CLASS_ACTIVE)) {
2623
2349
  addClass(image, CLASS_IN);
2624
2350
  index = i;
2625
2351
  }
2626
-
2627
2352
  list.push(image);
2628
2353
  addListener(image, EVENT_LOAD, onLoad, {
2629
2354
  once: true
2630
2355
  });
2631
2356
  player.appendChild(image);
2632
2357
  });
2633
-
2634
2358
  if (isNumber(options.interval) && options.interval > 0) {
2635
- var play = function play() {
2636
- _this7.playing = setTimeout(function () {
2637
- removeClass(list[index], CLASS_IN);
2638
- index += 1;
2639
- index = index < total ? index : 0;
2640
- addClass(list[index], CLASS_IN);
2641
- play();
2642
- }, options.interval);
2359
+ var prev = function prev() {
2360
+ clearTimeout(_this7.playing.timeout);
2361
+ removeClass(list[index], CLASS_IN);
2362
+ index -= 1;
2363
+ index = index >= 0 ? index : total - 1;
2364
+ addClass(list[index], CLASS_IN);
2365
+ _this7.playing.timeout = setTimeout(prev, options.interval);
2366
+ };
2367
+ var next = function next() {
2368
+ clearTimeout(_this7.playing.timeout);
2369
+ removeClass(list[index], CLASS_IN);
2370
+ index += 1;
2371
+ index = index < total ? index : 0;
2372
+ addClass(list[index], CLASS_IN);
2373
+ _this7.playing.timeout = setTimeout(next, options.interval);
2643
2374
  };
2644
-
2645
2375
  if (total > 1) {
2646
- play();
2376
+ this.playing = {
2377
+ prev: prev,
2378
+ next: next,
2379
+ timeout: setTimeout(next, options.interval)
2380
+ };
2647
2381
  }
2648
2382
  }
2649
-
2650
2383
  return this;
2651
2384
  },
2652
2385
  // Stop play
2653
2386
  stop: function stop() {
2654
2387
  var _this8 = this;
2655
-
2656
2388
  if (!this.played) {
2657
2389
  return this;
2658
2390
  }
2659
-
2660
2391
  var element = this.element,
2661
- options = this.options;
2662
-
2392
+ options = this.options;
2663
2393
  if (isFunction(options.stop)) {
2664
2394
  addListener(element, EVENT_STOP, options.stop, {
2665
2395
  once: true
2666
2396
  });
2667
2397
  }
2668
-
2669
2398
  if (dispatchEvent(element, EVENT_STOP) === false) {
2670
2399
  return this;
2671
2400
  }
2672
-
2673
2401
  var player = this.player;
2402
+ clearTimeout(this.playing.timeout);
2403
+ this.playing = false;
2674
2404
  this.played = false;
2675
- clearTimeout(this.playing);
2676
2405
  forEach(player.getElementsByTagName('img'), function (image) {
2677
2406
  removeListener(image, EVENT_LOAD, _this8.onLoadWhenPlay);
2678
2407
  });
@@ -2684,28 +2413,22 @@ var methods = {
2684
2413
  // Enter modal mode (only available in inline mode)
2685
2414
  full: function full() {
2686
2415
  var _this9 = this;
2687
-
2688
2416
  var options = this.options,
2689
- viewer = this.viewer,
2690
- image = this.image,
2691
- list = this.list;
2692
-
2417
+ viewer = this.viewer,
2418
+ image = this.image,
2419
+ list = this.list;
2693
2420
  if (!this.isShown || this.played || this.fulled || !options.inline) {
2694
2421
  return this;
2695
2422
  }
2696
-
2697
2423
  this.fulled = true;
2698
2424
  this.open();
2699
2425
  addClass(this.button, CLASS_FULLSCREEN_EXIT);
2700
-
2701
2426
  if (options.transition) {
2702
2427
  removeClass(list, CLASS_TRANSITION);
2703
-
2704
2428
  if (this.viewed) {
2705
2429
  removeClass(image, CLASS_TRANSITION);
2706
2430
  }
2707
2431
  }
2708
-
2709
2432
  addClass(viewer, CLASS_FIXED);
2710
2433
  viewer.setAttribute('role', 'dialog');
2711
2434
  viewer.setAttribute('aria-labelledby', this.title.id);
@@ -2714,15 +2437,12 @@ var methods = {
2714
2437
  setStyle(viewer, {
2715
2438
  zIndex: options.zIndex
2716
2439
  });
2717
-
2718
2440
  if (options.focus) {
2719
2441
  this.enforceFocus();
2720
2442
  }
2721
-
2722
2443
  this.initContainer();
2723
2444
  this.viewerData = assign({}, this.containerData);
2724
2445
  this.renderList();
2725
-
2726
2446
  if (this.viewed) {
2727
2447
  this.initImage(function () {
2728
2448
  _this9.renderImage(function () {
@@ -2735,38 +2455,30 @@ var methods = {
2735
2455
  });
2736
2456
  });
2737
2457
  }
2738
-
2739
2458
  return this;
2740
2459
  },
2741
2460
  // Exit modal mode (only available in inline mode)
2742
2461
  exit: function exit() {
2743
2462
  var _this10 = this;
2744
-
2745
2463
  var options = this.options,
2746
- viewer = this.viewer,
2747
- image = this.image,
2748
- list = this.list;
2749
-
2464
+ viewer = this.viewer,
2465
+ image = this.image,
2466
+ list = this.list;
2750
2467
  if (!this.isShown || this.played || !this.fulled || !options.inline) {
2751
2468
  return this;
2752
2469
  }
2753
-
2754
2470
  this.fulled = false;
2755
2471
  this.close();
2756
2472
  removeClass(this.button, CLASS_FULLSCREEN_EXIT);
2757
-
2758
2473
  if (options.transition) {
2759
2474
  removeClass(list, CLASS_TRANSITION);
2760
-
2761
2475
  if (this.viewed) {
2762
2476
  removeClass(image, CLASS_TRANSITION);
2763
2477
  }
2764
2478
  }
2765
-
2766
2479
  if (options.focus) {
2767
2480
  this.clearEnforceFocus();
2768
2481
  }
2769
-
2770
2482
  viewer.removeAttribute('role');
2771
2483
  viewer.removeAttribute('aria-labelledby');
2772
2484
  viewer.removeAttribute('aria-modal');
@@ -2777,7 +2489,6 @@ var methods = {
2777
2489
  this.viewerData = assign({}, this.parentData);
2778
2490
  this.renderViewer();
2779
2491
  this.renderList();
2780
-
2781
2492
  if (this.viewed) {
2782
2493
  this.initImage(function () {
2783
2494
  _this10.renderImage(function () {
@@ -2790,34 +2501,29 @@ var methods = {
2790
2501
  });
2791
2502
  });
2792
2503
  }
2793
-
2794
2504
  return this;
2795
2505
  },
2796
2506
  // Show the current ratio of the image with percentage
2797
2507
  tooltip: function tooltip() {
2798
2508
  var _this11 = this;
2799
-
2800
2509
  var options = this.options,
2801
- tooltipBox = this.tooltipBox,
2802
- imageData = this.imageData;
2803
-
2510
+ tooltipBox = this.tooltipBox,
2511
+ imageData = this.imageData;
2804
2512
  if (!this.viewed || this.played || !options.tooltip) {
2805
2513
  return this;
2806
2514
  }
2807
-
2808
2515
  tooltipBox.textContent = "".concat(Math.round(imageData.ratio * 100), "%");
2809
-
2810
2516
  if (!this.tooltipping) {
2811
2517
  if (options.transition) {
2812
2518
  if (this.fading) {
2813
2519
  dispatchEvent(tooltipBox, EVENT_TRANSITION_END);
2814
2520
  }
2815
-
2816
2521
  addClass(tooltipBox, CLASS_SHOW);
2817
2522
  addClass(tooltipBox, CLASS_FADE);
2818
2523
  addClass(tooltipBox, CLASS_TRANSITION);
2819
- tooltipBox.removeAttribute('aria-hidden'); // Force reflow to enable CSS3 transition
2524
+ tooltipBox.removeAttribute('aria-hidden');
2820
2525
 
2526
+ // Force reflow to enable CSS3 transition
2821
2527
  tooltipBox.initialOffsetWidth = tooltipBox.offsetWidth;
2822
2528
  addClass(tooltipBox, CLASS_IN);
2823
2529
  } else {
@@ -2827,7 +2533,6 @@ var methods = {
2827
2533
  } else {
2828
2534
  clearTimeout(this.tooltipping);
2829
2535
  }
2830
-
2831
2536
  this.tooltipping = setTimeout(function () {
2832
2537
  if (options.transition) {
2833
2538
  addListener(tooltipBox, EVENT_TRANSITION_END, function () {
@@ -2845,12 +2550,10 @@ var methods = {
2845
2550
  removeClass(tooltipBox, CLASS_SHOW);
2846
2551
  tooltipBox.setAttribute('aria-hidden', true);
2847
2552
  }
2848
-
2849
2553
  _this11.tooltipping = false;
2850
2554
  }, 1000);
2851
2555
  return this;
2852
2556
  },
2853
-
2854
2557
  /**
2855
2558
  * Toggle the image size between its current size and natural size
2856
2559
  * @param {Event} [_originalEvent=null] - The original event if any.
@@ -2858,13 +2561,11 @@ var methods = {
2858
2561
  */
2859
2562
  toggle: function toggle() {
2860
2563
  var _originalEvent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
2861
-
2862
2564
  if (this.imageData.ratio === 1) {
2863
- this.zoomTo(this.imageData.oldRatio, true, _originalEvent);
2565
+ this.zoomTo(this.imageData.oldRatio, true, null, _originalEvent);
2864
2566
  } else {
2865
- this.zoomTo(1, true, _originalEvent);
2567
+ this.zoomTo(1, true, null, _originalEvent);
2866
2568
  }
2867
-
2868
2569
  return this;
2869
2570
  },
2870
2571
  // Reset the image to its initial state
@@ -2873,21 +2574,19 @@ var methods = {
2873
2574
  this.imageData = assign({}, this.initialImageData);
2874
2575
  this.renderImage();
2875
2576
  }
2876
-
2877
2577
  return this;
2878
2578
  },
2879
2579
  // Update viewer when images changed
2880
2580
  update: function update() {
2881
2581
  var _this12 = this;
2882
-
2883
2582
  var element = this.element,
2884
- options = this.options,
2885
- isImg = this.isImg; // Destroy viewer if the target image was deleted
2583
+ options = this.options,
2584
+ isImg = this.isImg;
2886
2585
 
2586
+ // Destroy viewer if the target image was deleted
2887
2587
  if (isImg && !element.parentNode) {
2888
2588
  return this.destroy();
2889
2589
  }
2890
-
2891
2590
  var images = [];
2892
2591
  forEach(isImg ? [element] : element.querySelectorAll('img'), function (image) {
2893
2592
  if (isFunction(options.filter)) {
@@ -2898,22 +2597,20 @@ var methods = {
2898
2597
  images.push(image);
2899
2598
  }
2900
2599
  });
2901
-
2902
2600
  if (!images.length) {
2903
2601
  return this;
2904
2602
  }
2905
-
2906
2603
  this.images = images;
2907
2604
  this.length = images.length;
2908
-
2909
2605
  if (this.ready) {
2910
2606
  var changedIndexes = [];
2911
2607
  forEach(this.items, function (item, i) {
2912
2608
  var img = item.querySelector('img');
2913
2609
  var image = images[i];
2914
-
2915
2610
  if (image && img) {
2916
- if (image.src !== img.src // Title changed (#408)
2611
+ if (image.src !== img.src
2612
+
2613
+ // Title changed (#408)
2917
2614
  || image.alt !== img.alt) {
2918
2615
  changedIndexes.push(i);
2919
2616
  }
@@ -2925,18 +2622,17 @@ var methods = {
2925
2622
  width: 'auto'
2926
2623
  });
2927
2624
  this.initList();
2928
-
2929
2625
  if (this.isShown) {
2930
2626
  if (this.length) {
2931
2627
  if (this.viewed) {
2932
2628
  var changedIndex = changedIndexes.indexOf(this.index);
2933
-
2934
2629
  if (changedIndex >= 0) {
2935
2630
  this.viewed = false;
2936
2631
  this.view(Math.max(Math.min(this.index - changedIndex, this.length - 1), 0));
2937
2632
  } else {
2938
- var activeItem = this.items[this.index]; // Reactivate the current viewing item after reset the list.
2633
+ var activeItem = this.items[this.index];
2939
2634
 
2635
+ // Reactivate the current viewing item after reset the list.
2940
2636
  addClass(activeItem, CLASS_ACTIVE);
2941
2637
  activeItem.setAttribute('aria-selected', true);
2942
2638
  }
@@ -2953,30 +2649,24 @@ var methods = {
2953
2649
  } else {
2954
2650
  this.build();
2955
2651
  }
2956
-
2957
2652
  return this;
2958
2653
  },
2959
2654
  // Destroy the viewer
2960
2655
  destroy: function destroy() {
2961
2656
  var element = this.element,
2962
- options = this.options;
2963
-
2657
+ options = this.options;
2964
2658
  if (!element[NAMESPACE]) {
2965
2659
  return this;
2966
2660
  }
2967
-
2968
2661
  this.destroyed = true;
2969
-
2970
2662
  if (this.ready) {
2971
2663
  if (this.played) {
2972
2664
  this.stop();
2973
2665
  }
2974
-
2975
2666
  if (options.inline) {
2976
2667
  if (this.fulled) {
2977
2668
  this.exit();
2978
2669
  }
2979
-
2980
2670
  this.unbind();
2981
2671
  } else if (this.isShown) {
2982
2672
  if (this.viewing) {
@@ -2986,17 +2676,14 @@ var methods = {
2986
2676
  this.imageInitializing.abort();
2987
2677
  }
2988
2678
  }
2989
-
2990
2679
  if (this.hiding) {
2991
2680
  this.transitioning.abort();
2992
2681
  }
2993
-
2994
2682
  this.hidden();
2995
2683
  } else if (this.showing) {
2996
2684
  this.transitioning.abort();
2997
2685
  this.hidden();
2998
2686
  }
2999
-
3000
2687
  this.ready = false;
3001
2688
  this.viewer.parentNode.removeChild(this.viewer);
3002
2689
  } else if (options.inline) {
@@ -3006,11 +2693,9 @@ var methods = {
3006
2693
  this.initializing.abort();
3007
2694
  }
3008
2695
  }
3009
-
3010
2696
  if (!options.inline) {
3011
2697
  removeListener(element, EVENT_CLICK, this.onStart);
3012
2698
  }
3013
-
3014
2699
  element[NAMESPACE] = undefined;
3015
2700
  return this;
3016
2701
  }
@@ -3019,7 +2704,6 @@ var methods = {
3019
2704
  var others = {
3020
2705
  getImageURL: function getImageURL(image) {
3021
2706
  var url = this.options.url;
3022
-
3023
2707
  if (isString(url)) {
3024
2708
  url = image.getAttribute(url);
3025
2709
  } else if (isFunction(url)) {
@@ -3027,30 +2711,24 @@ var others = {
3027
2711
  } else {
3028
2712
  url = '';
3029
2713
  }
3030
-
3031
2714
  return url;
3032
2715
  },
3033
2716
  enforceFocus: function enforceFocus() {
3034
2717
  var _this = this;
3035
-
3036
2718
  this.clearEnforceFocus();
3037
2719
  addListener(document, EVENT_FOCUSIN, this.onFocusin = function (event) {
3038
2720
  var viewer = _this.viewer;
3039
2721
  var target = event.target;
3040
-
3041
2722
  if (target === document || target === viewer || viewer.contains(target)) {
3042
2723
  return;
3043
2724
  }
3044
-
3045
2725
  while (target) {
3046
2726
  // Avoid conflicts with other modals (#474, #540)
3047
2727
  if (target.getAttribute('tabindex') !== null || target.getAttribute('aria-modal') === 'true') {
3048
2728
  return;
3049
2729
  }
3050
-
3051
2730
  target = target.parentElement;
3052
2731
  }
3053
-
3054
2732
  viewer.focus();
3055
2733
  });
3056
2734
  },
@@ -3063,51 +2741,49 @@ var others = {
3063
2741
  open: function open() {
3064
2742
  var body = this.body;
3065
2743
  addClass(body, CLASS_OPEN);
3066
- body.style.paddingRight = "".concat(this.scrollbarWidth + (parseFloat(this.initialBodyComputedPaddingRight) || 0), "px");
2744
+ if (this.scrollbarWidth > 0) {
2745
+ body.style.paddingRight = "".concat(this.scrollbarWidth + (parseFloat(this.initialBodyComputedPaddingRight) || 0), "px");
2746
+ }
3067
2747
  },
3068
2748
  close: function close() {
3069
2749
  var body = this.body;
3070
2750
  removeClass(body, CLASS_OPEN);
3071
- body.style.paddingRight = this.initialBodyPaddingRight;
2751
+ if (this.scrollbarWidth > 0) {
2752
+ body.style.paddingRight = this.initialBodyPaddingRight;
2753
+ }
3072
2754
  },
3073
2755
  shown: function shown() {
3074
2756
  var element = this.element,
3075
- options = this.options,
3076
- viewer = this.viewer;
2757
+ options = this.options,
2758
+ viewer = this.viewer;
3077
2759
  this.fulled = true;
3078
2760
  this.isShown = true;
3079
2761
  this.render();
3080
2762
  this.bind();
3081
2763
  this.showing = false;
3082
-
3083
2764
  if (options.focus) {
3084
2765
  viewer.focus();
3085
2766
  this.enforceFocus();
3086
2767
  }
3087
-
3088
2768
  if (isFunction(options.shown)) {
3089
2769
  addListener(element, EVENT_SHOWN, options.shown, {
3090
2770
  once: true
3091
2771
  });
3092
2772
  }
3093
-
3094
2773
  if (dispatchEvent(element, EVENT_SHOWN) === false) {
3095
2774
  return;
3096
2775
  }
3097
-
3098
2776
  if (this.ready && this.isShown && !this.hiding) {
3099
2777
  this.view(this.index);
3100
2778
  }
3101
2779
  },
3102
2780
  hidden: function hidden() {
3103
2781
  var element = this.element,
3104
- options = this.options,
3105
- viewer = this.viewer;
3106
-
2782
+ options = this.options,
2783
+ viewer = this.viewer;
3107
2784
  if (options.fucus) {
3108
2785
  this.clearEnforceFocus();
3109
2786
  }
3110
-
3111
2787
  this.fulled = false;
3112
2788
  this.viewed = false;
3113
2789
  this.isShown = false;
@@ -3121,14 +2797,12 @@ var others = {
3121
2797
  this.resetList();
3122
2798
  this.resetImage();
3123
2799
  this.hiding = false;
3124
-
3125
2800
  if (!this.destroyed) {
3126
2801
  if (isFunction(options.hidden)) {
3127
2802
  addListener(element, EVENT_HIDDEN, options.hidden, {
3128
2803
  once: true
3129
2804
  });
3130
2805
  }
3131
-
3132
2806
  dispatchEvent(element, EVENT_HIDDEN, null, {
3133
2807
  cancelable: false
3134
2808
  });
@@ -3136,10 +2810,10 @@ var others = {
3136
2810
  },
3137
2811
  requestFullscreen: function requestFullscreen(options) {
3138
2812
  var document = this.element.ownerDocument;
3139
-
3140
2813
  if (this.fulled && !(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement)) {
3141
- var documentElement = document.documentElement; // Element.requestFullscreen()
2814
+ var documentElement = document.documentElement;
3142
2815
 
2816
+ // Element.requestFullscreen()
3143
2817
  if (documentElement.requestFullscreen) {
3144
2818
  // Avoid TypeError when convert `options` to dictionary
3145
2819
  if (isPlainObject(options)) {
@@ -3158,7 +2832,6 @@ var others = {
3158
2832
  },
3159
2833
  exitFullscreen: function exitFullscreen() {
3160
2834
  var document = this.element.ownerDocument;
3161
-
3162
2835
  if (this.fulled && (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement)) {
3163
2836
  // Document.exitFullscreen()
3164
2837
  if (document.exitFullscreen) {
@@ -3174,48 +2847,43 @@ var others = {
3174
2847
  },
3175
2848
  change: function change(event) {
3176
2849
  var options = this.options,
3177
- pointers = this.pointers;
3178
- var pointer = pointers[Object.keys(pointers)[0]]; // In the case of the `pointers` object is empty (#421)
2850
+ pointers = this.pointers;
2851
+ var pointer = pointers[Object.keys(pointers)[0]];
3179
2852
 
2853
+ // In the case of the `pointers` object is empty (#421)
3180
2854
  if (!pointer) {
3181
2855
  return;
3182
2856
  }
3183
-
3184
2857
  var offsetX = pointer.endX - pointer.startX;
3185
2858
  var offsetY = pointer.endY - pointer.startY;
3186
-
3187
2859
  switch (this.action) {
3188
2860
  // Move the current image
3189
2861
  case ACTION_MOVE:
3190
2862
  this.move(offsetX, offsetY, event);
3191
2863
  break;
3192
- // Zoom the current image
3193
2864
 
2865
+ // Zoom the current image
3194
2866
  case ACTION_ZOOM:
3195
- this.zoom(getMaxZoomRatio(pointers), false, event);
2867
+ this.zoom(getMaxZoomRatio(pointers), false, null, event);
3196
2868
  break;
3197
-
3198
2869
  case ACTION_SWITCH:
3199
2870
  {
3200
2871
  this.action = 'switched';
3201
2872
  var absoluteOffsetX = Math.abs(offsetX);
3202
-
3203
2873
  if (absoluteOffsetX > 1 && absoluteOffsetX > Math.abs(offsetY)) {
3204
2874
  // Empty `pointers` as `touchend` event will not be fired after swiped in iOS browsers.
3205
2875
  this.pointers = {};
3206
-
3207
2876
  if (offsetX > 1) {
3208
2877
  this.prev(options.loop);
3209
2878
  } else if (offsetX < -1) {
3210
2879
  this.next(options.loop);
3211
2880
  }
3212
2881
  }
3213
-
3214
2882
  break;
3215
2883
  }
3216
- } // Override
3217
-
2884
+ }
3218
2885
 
2886
+ // Override
3219
2887
  forEach(pointers, function (p) {
3220
2888
  p.startX = p.endX;
3221
2889
  p.startY = p.endY;
@@ -3223,20 +2891,18 @@ var others = {
3223
2891
  },
3224
2892
  isSwitchable: function isSwitchable() {
3225
2893
  var imageData = this.imageData,
3226
- viewerData = this.viewerData;
2894
+ viewerData = this.viewerData;
3227
2895
  return this.length > 1 && imageData.x >= 0 && imageData.y >= 0 && imageData.width <= viewerData.width && imageData.height <= viewerData.height;
3228
2896
  }
3229
2897
  };
3230
2898
 
3231
2899
  var AnotherViewer = WINDOW.Viewer;
3232
-
3233
2900
  var getUniqueID = function (id) {
3234
2901
  return function () {
3235
2902
  id += 1;
3236
2903
  return id;
3237
2904
  };
3238
2905
  }(-1);
3239
-
3240
2906
  var Viewer = /*#__PURE__*/function () {
3241
2907
  /**
3242
2908
  * Create a new Viewer.
@@ -3245,13 +2911,10 @@ var Viewer = /*#__PURE__*/function () {
3245
2911
  */
3246
2912
  function Viewer(element) {
3247
2913
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
3248
-
3249
2914
  _classCallCheck(this, Viewer);
3250
-
3251
2915
  if (!element || element.nodeType !== 1) {
3252
2916
  throw new Error('The first argument is required and must be an element.');
3253
2917
  }
3254
-
3255
2918
  this.element = element;
3256
2919
  this.options = assign({}, DEFAULTS, isPlainObject(options) && options);
3257
2920
  this.action = false;
@@ -3281,25 +2944,21 @@ var Viewer = /*#__PURE__*/function () {
3281
2944
  this.id = getUniqueID();
3282
2945
  this.init();
3283
2946
  }
3284
-
3285
2947
  _createClass(Viewer, [{
3286
2948
  key: "init",
3287
2949
  value: function init() {
3288
2950
  var _this = this;
3289
-
3290
2951
  var element = this.element,
3291
- options = this.options;
3292
-
2952
+ options = this.options;
3293
2953
  if (element[NAMESPACE]) {
3294
2954
  return;
3295
2955
  }
2956
+ element[NAMESPACE] = this;
3296
2957
 
3297
- element[NAMESPACE] = this; // The `focus` option requires the `keyboard` option set to `true`.
3298
-
2958
+ // The `focus` option requires the `keyboard` option set to `true`.
3299
2959
  if (options.focus && !options.keyboard) {
3300
2960
  options.focus = false;
3301
2961
  }
3302
-
3303
2962
  var isImg = element.localName === 'img';
3304
2963
  var images = [];
3305
2964
  forEach(isImg ? [element] : element.querySelectorAll('img'), function (image) {
@@ -3314,18 +2973,16 @@ var Viewer = /*#__PURE__*/function () {
3314
2973
  this.isImg = isImg;
3315
2974
  this.length = images.length;
3316
2975
  this.images = images;
3317
- this.initBody(); // Override `transition` option if it is not supported
2976
+ this.initBody();
3318
2977
 
2978
+ // Override `transition` option if it is not supported
3319
2979
  if (isUndefined(document.createElement(NAMESPACE).style.transition)) {
3320
2980
  options.transition = false;
3321
2981
  }
3322
-
3323
2982
  if (options.inline) {
3324
2983
  var count = 0;
3325
-
3326
2984
  var progress = function progress() {
3327
2985
  count += 1;
3328
-
3329
2986
  if (count === _this.length) {
3330
2987
  var timeout;
3331
2988
  _this.initializing = false;
@@ -3333,16 +2990,15 @@ var Viewer = /*#__PURE__*/function () {
3333
2990
  abort: function abort() {
3334
2991
  clearTimeout(timeout);
3335
2992
  }
3336
- }; // build asynchronously to keep `this.viewer` is accessible in `ready` event handler.
2993
+ };
3337
2994
 
2995
+ // build asynchronously to keep `this.viewer` is accessible in `ready` event handler.
3338
2996
  timeout = setTimeout(function () {
3339
2997
  _this.delaying = false;
3340
-
3341
2998
  _this.build();
3342
2999
  }, 0);
3343
3000
  }
3344
3001
  };
3345
-
3346
3002
  this.initializing = {
3347
3003
  abort: function abort() {
3348
3004
  forEach(images, function (image) {
@@ -3376,7 +3032,6 @@ var Viewer = /*#__PURE__*/function () {
3376
3032
  } else {
3377
3033
  addListener(element, EVENT_CLICK, this.onStart = function (_ref) {
3378
3034
  var target = _ref.target;
3379
-
3380
3035
  if (target.localName === 'img' && (!isFunction(options.filter) || options.filter.call(_this, target))) {
3381
3036
  _this.view(_this.images.indexOf(target));
3382
3037
  }
@@ -3389,9 +3044,8 @@ var Viewer = /*#__PURE__*/function () {
3389
3044
  if (this.ready) {
3390
3045
  return;
3391
3046
  }
3392
-
3393
3047
  var element = this.element,
3394
- options = this.options;
3048
+ options = this.options;
3395
3049
  var parent = element.parentNode;
3396
3050
  var template = document.createElement('div');
3397
3051
  template.innerHTML = TEMPLATE;
@@ -3417,82 +3071,65 @@ var Viewer = /*#__PURE__*/function () {
3417
3071
  addClass(title, !options.title ? CLASS_HIDE : getResponsiveClass(Array.isArray(options.title) ? options.title[0] : options.title));
3418
3072
  addClass(navbar, !options.navbar ? CLASS_HIDE : getResponsiveClass(options.navbar));
3419
3073
  toggleClass(button, CLASS_HIDE, !options.button);
3420
-
3421
3074
  if (options.keyboard) {
3422
3075
  button.setAttribute('tabindex', 0);
3423
3076
  }
3424
-
3425
3077
  if (options.backdrop) {
3426
3078
  addClass(viewer, "".concat(NAMESPACE, "-backdrop"));
3427
-
3428
3079
  if (!options.inline && options.backdrop !== 'static') {
3429
3080
  setData(canvas, DATA_ACTION, 'hide');
3430
3081
  }
3431
3082
  }
3432
-
3433
3083
  if (isString(options.className) && options.className) {
3434
3084
  // In case there are multiple class names
3435
3085
  options.className.split(REGEXP_SPACES).forEach(function (className) {
3436
3086
  addClass(viewer, className);
3437
3087
  });
3438
3088
  }
3439
-
3440
3089
  if (options.toolbar) {
3441
3090
  var list = document.createElement('ul');
3442
3091
  var custom = isPlainObject(options.toolbar);
3443
3092
  var zoomButtons = BUTTONS.slice(0, 3);
3444
3093
  var rotateButtons = BUTTONS.slice(7, 9);
3445
3094
  var scaleButtons = BUTTONS.slice(9);
3446
-
3447
3095
  if (!custom) {
3448
3096
  addClass(toolbar, getResponsiveClass(options.toolbar));
3449
3097
  }
3450
-
3451
3098
  forEach(custom ? options.toolbar : BUTTONS, function (value, index) {
3452
3099
  var deep = custom && isPlainObject(value);
3453
3100
  var name = custom ? hyphenate(index) : value;
3454
3101
  var show = deep && !isUndefined(value.show) ? value.show : value;
3455
-
3456
3102
  if (!show || !options.zoomable && zoomButtons.indexOf(name) !== -1 || !options.rotatable && rotateButtons.indexOf(name) !== -1 || !options.scalable && scaleButtons.indexOf(name) !== -1) {
3457
3103
  return;
3458
3104
  }
3459
-
3460
3105
  var size = deep && !isUndefined(value.size) ? value.size : value;
3461
3106
  var click = deep && !isUndefined(value.click) ? value.click : value;
3462
3107
  var item = document.createElement('li');
3463
-
3464
3108
  if (options.keyboard) {
3465
3109
  item.setAttribute('tabindex', 0);
3466
3110
  }
3467
-
3468
3111
  item.setAttribute('role', 'button');
3469
3112
  addClass(item, "".concat(NAMESPACE, "-").concat(name));
3470
-
3471
3113
  if (!isFunction(click)) {
3472
3114
  setData(item, DATA_ACTION, name);
3473
3115
  }
3474
-
3475
3116
  if (isNumber(show)) {
3476
3117
  addClass(item, getResponsiveClass(show));
3477
3118
  }
3478
-
3479
3119
  if (['small', 'large'].indexOf(size) !== -1) {
3480
3120
  addClass(item, "".concat(NAMESPACE, "-").concat(size));
3481
3121
  } else if (name === 'play') {
3482
3122
  addClass(item, "".concat(NAMESPACE, "-large"));
3483
3123
  }
3484
-
3485
3124
  if (isFunction(click)) {
3486
3125
  addListener(item, EVENT_CLICK, click);
3487
3126
  }
3488
-
3489
3127
  list.appendChild(item);
3490
3128
  });
3491
3129
  toolbar.appendChild(list);
3492
3130
  } else {
3493
3131
  addClass(toolbar, CLASS_HIDE);
3494
3132
  }
3495
-
3496
3133
  if (!options.rotatable) {
3497
3134
  var rotates = toolbar.querySelectorAll('li[class*="rotate"]');
3498
3135
  addClass(rotates, CLASS_INVISIBLE);
@@ -3500,19 +3137,16 @@ var Viewer = /*#__PURE__*/function () {
3500
3137
  toolbar.appendChild(rotate);
3501
3138
  });
3502
3139
  }
3503
-
3504
3140
  if (options.inline) {
3505
3141
  addClass(button, CLASS_FULLSCREEN);
3506
3142
  setStyle(viewer, {
3507
3143
  zIndex: options.zIndexInline
3508
3144
  });
3509
-
3510
3145
  if (window.getComputedStyle(parent).position === 'static') {
3511
3146
  setStyle(parent, {
3512
3147
  position: 'relative'
3513
3148
  });
3514
3149
  }
3515
-
3516
3150
  parent.insertBefore(viewer, element.nextSibling);
3517
3151
  } else {
3518
3152
  addClass(button, CLASS_CLOSE);
@@ -3523,67 +3157,57 @@ var Viewer = /*#__PURE__*/function () {
3523
3157
  zIndex: options.zIndex
3524
3158
  });
3525
3159
  var container = options.container;
3526
-
3527
3160
  if (isString(container)) {
3528
3161
  container = element.ownerDocument.querySelector(container);
3529
3162
  }
3530
-
3531
3163
  if (!container) {
3532
3164
  container = this.body;
3533
3165
  }
3534
-
3535
3166
  container.appendChild(viewer);
3536
3167
  }
3537
-
3538
3168
  if (options.inline) {
3539
3169
  this.render();
3540
3170
  this.bind();
3541
3171
  this.isShown = true;
3542
3172
  }
3543
-
3544
3173
  this.ready = true;
3545
-
3546
3174
  if (isFunction(options.ready)) {
3547
3175
  addListener(element, EVENT_READY, options.ready, {
3548
3176
  once: true
3549
3177
  });
3550
3178
  }
3551
-
3552
3179
  if (dispatchEvent(element, EVENT_READY) === false) {
3553
3180
  this.ready = false;
3554
3181
  return;
3555
3182
  }
3556
-
3557
3183
  if (this.ready && options.inline) {
3558
3184
  this.view(this.index);
3559
3185
  }
3560
3186
  }
3187
+
3561
3188
  /**
3562
3189
  * Get the no conflict viewer class.
3563
3190
  * @returns {Viewer} The viewer class.
3564
3191
  */
3565
-
3566
3192
  }], [{
3567
3193
  key: "noConflict",
3568
3194
  value: function noConflict() {
3569
3195
  window.Viewer = AnotherViewer;
3570
3196
  return Viewer;
3571
3197
  }
3198
+
3572
3199
  /**
3573
3200
  * Change the default options.
3574
3201
  * @param {Object} options - The new default options.
3575
3202
  */
3576
-
3577
3203
  }, {
3578
3204
  key: "setDefaults",
3579
3205
  value: function setDefaults(options) {
3580
3206
  assign(DEFAULTS, isPlainObject(options) && options);
3581
3207
  }
3582
3208
  }]);
3583
-
3584
3209
  return Viewer;
3585
3210
  }();
3586
-
3587
3211
  assign(Viewer.prototype, render, events, handlers, methods, others);
3588
3212
 
3589
3213
  export { Viewer as default };