@hyper-proto/iv-viewer 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1442 @@
1
+ /**
2
+ * @hyper-proto/iv-viewer - 2.3.0
3
+ * Author : HyperProto
4
+ * Copyright (c) 2019, 2026 to HyperProto, released under the MIT license.
5
+ * git+https://github.com/hyperproto-gh/iv-viewer.git
6
+ */
7
+
8
+ (function (global, factory) {
9
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
10
+ typeof define === 'function' && define.amd ? define(factory) :
11
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.ImageViewer = factory());
12
+ })(this, (function () { 'use strict';
13
+
14
+ function _arrayLikeToArray(r, a) {
15
+ (null == a || a > r.length) && (a = r.length);
16
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
17
+ return n;
18
+ }
19
+ function _arrayWithHoles(r) {
20
+ if (Array.isArray(r)) return r;
21
+ }
22
+ function _assertThisInitialized(e) {
23
+ if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
24
+ return e;
25
+ }
26
+ function _callSuper(t, o, e) {
27
+ return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
28
+ }
29
+ function _classCallCheck(a, n) {
30
+ if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
31
+ }
32
+ function _defineProperties(e, r) {
33
+ for (var t = 0; t < r.length; t++) {
34
+ var o = r[t];
35
+ o.enumerable = o.enumerable || false, o.configurable = true, "value" in o && (o.writable = true), Object.defineProperty(e, _toPropertyKey(o.key), o);
36
+ }
37
+ }
38
+ function _createClass(e, r, t) {
39
+ return r && _defineProperties(e.prototype, r), Object.defineProperty(e, "prototype", {
40
+ writable: false
41
+ }), e;
42
+ }
43
+ function _defineProperty(e, r, t) {
44
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
45
+ value: t,
46
+ enumerable: true,
47
+ configurable: true,
48
+ writable: true
49
+ }) : e[r] = t, e;
50
+ }
51
+ function _get() {
52
+ return _get = "undefined" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function (e, t, r) {
53
+ var p = _superPropBase(e, t);
54
+ if (p) {
55
+ var n = Object.getOwnPropertyDescriptor(p, t);
56
+ return n.get ? n.get.call(arguments.length < 3 ? e : r) : n.value;
57
+ }
58
+ }, _get.apply(null, arguments);
59
+ }
60
+ function _getPrototypeOf(t) {
61
+ return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
62
+ return t.__proto__ || Object.getPrototypeOf(t);
63
+ }, _getPrototypeOf(t);
64
+ }
65
+ function _inherits(t, e) {
66
+ if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
67
+ t.prototype = Object.create(e && e.prototype, {
68
+ constructor: {
69
+ value: t,
70
+ writable: true,
71
+ configurable: true
72
+ }
73
+ }), Object.defineProperty(t, "prototype", {
74
+ writable: false
75
+ }), e && _setPrototypeOf(t, e);
76
+ }
77
+ function _isNativeReflectConstruct() {
78
+ try {
79
+ var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
80
+ } catch (t) {}
81
+ return (_isNativeReflectConstruct = function () {
82
+ return !!t;
83
+ })();
84
+ }
85
+ function _iterableToArrayLimit(r, l) {
86
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
87
+ if (null != t) {
88
+ var e,
89
+ n,
90
+ i,
91
+ u,
92
+ a = [],
93
+ f = true,
94
+ o = false;
95
+ try {
96
+ if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
97
+ } catch (r) {
98
+ o = true, n = r;
99
+ } finally {
100
+ try {
101
+ if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
102
+ } finally {
103
+ if (o) throw n;
104
+ }
105
+ }
106
+ return a;
107
+ }
108
+ }
109
+ function _nonIterableRest() {
110
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
111
+ }
112
+ function ownKeys(e, r) {
113
+ var t = Object.keys(e);
114
+ if (Object.getOwnPropertySymbols) {
115
+ var o = Object.getOwnPropertySymbols(e);
116
+ r && (o = o.filter(function (r) {
117
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
118
+ })), t.push.apply(t, o);
119
+ }
120
+ return t;
121
+ }
122
+ function _objectSpread2(e) {
123
+ for (var r = 1; r < arguments.length; r++) {
124
+ var t = null != arguments[r] ? arguments[r] : {};
125
+ r % 2 ? ownKeys(Object(t), true).forEach(function (r) {
126
+ _defineProperty(e, r, t[r]);
127
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
128
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
129
+ });
130
+ }
131
+ return e;
132
+ }
133
+ function _possibleConstructorReturn(t, e) {
134
+ if (e && ("object" == typeof e || "function" == typeof e)) return e;
135
+ if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined");
136
+ return _assertThisInitialized(t);
137
+ }
138
+ function _setPrototypeOf(t, e) {
139
+ return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
140
+ return t.__proto__ = e, t;
141
+ }, _setPrototypeOf(t, e);
142
+ }
143
+ function _slicedToArray(r, e) {
144
+ return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
145
+ }
146
+ function _superPropBase(t, o) {
147
+ for (; !{}.hasOwnProperty.call(t, o) && null !== (t = _getPrototypeOf(t)););
148
+ return t;
149
+ }
150
+ function _superPropGet(t, o, e, r) {
151
+ var p = _get(_getPrototypeOf(t.prototype ), o, e);
152
+ return "function" == typeof p ? function (t) {
153
+ return p.apply(e, t);
154
+ } : p;
155
+ }
156
+ function _toPrimitive(t, r) {
157
+ if ("object" != typeof t || !t) return t;
158
+ var e = t[Symbol.toPrimitive];
159
+ if (void 0 !== e) {
160
+ var i = e.call(t, r);
161
+ if ("object" != typeof i) return i;
162
+ throw new TypeError("@@toPrimitive must return a primitive value.");
163
+ }
164
+ return (String )(t);
165
+ }
166
+ function _toPropertyKey(t) {
167
+ var i = _toPrimitive(t, "string");
168
+ return "symbol" == typeof i ? i : i + "";
169
+ }
170
+ function _unsupportedIterableToArray(r, a) {
171
+ if (r) {
172
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
173
+ var t = {}.toString.call(r).slice(8, -1);
174
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
175
+ }
176
+ }
177
+
178
+ // constants
179
+ var ZOOM_CONSTANT = 15; // increase or decrease value for zoom on mouse wheel
180
+ var MOUSE_WHEEL_COUNT = 5; // A mouse delta after which it should stop preventing default behaviour of mouse wheel
181
+
182
+ function noop() {}
183
+ function preventDefault(e) {
184
+ e.preventDefault();
185
+ }
186
+
187
+ // ease out method
188
+ /*
189
+ t : current time,
190
+ b : initial value,
191
+ c : changed value,
192
+ d : duration
193
+ */
194
+ function easeOutQuart(t, b, c, d) {
195
+ t /= d;
196
+ t -= 1;
197
+ return -c * (t * t * t * t - 1) + b;
198
+ }
199
+ function createElement(options) {
200
+ var elem = document.createElement(options.tagName);
201
+ if (options.id) elem.id = options.id;
202
+ if (options.html) elem.innerHTML = options.html;
203
+ if (options.className) elem.className = options.className;
204
+ if (options.src) elem.src = options.src;
205
+ if (options.style) elem.style.cssText = options.style;
206
+ if (options.child) elem.appendChild(options.child);
207
+
208
+ // Insert before
209
+ if (options.insertBefore) {
210
+ options.parent.insertBefore(elem, options.insertBefore);
211
+
212
+ // Standard append
213
+ } else {
214
+ options.parent.appendChild(elem);
215
+ }
216
+ return elem;
217
+ }
218
+
219
+ // method to add class
220
+ function addClass(el, className) {
221
+ var classNameAry = className.split(' ');
222
+ if (classNameAry.length > 1) {
223
+ classNameAry.forEach(function (classItem) {
224
+ return addClass(el, classItem);
225
+ });
226
+ } else if (el.classList) {
227
+ el.classList.add(className);
228
+ } else {
229
+ el.className += " ".concat(className);
230
+ }
231
+ }
232
+
233
+ // method to remove class
234
+ function removeClass(el, className) {
235
+ var classNameAry = className.split(' ');
236
+ if (classNameAry.length > 1) {
237
+ classNameAry.forEach(function (classItem) {
238
+ return removeClass(el, classItem);
239
+ });
240
+ } else if (el.classList) {
241
+ el.classList.remove(className);
242
+ } else {
243
+ el.className = el.className.replace(new RegExp("(^|\\b)".concat(className.split(' ').join('|'), "(\\b|$)"), 'gi'), ' ');
244
+ }
245
+ }
246
+
247
+ // function to check if image is loaded
248
+ function imageLoaded(img) {
249
+ return img.complete && (typeof img.naturalWidth === 'undefined' || img.naturalWidth !== 0);
250
+ }
251
+ function toArray(list) {
252
+ if (!(list instanceof NodeList || list instanceof HTMLCollection)) return [list];
253
+ return Array.prototype.slice.call(list);
254
+ }
255
+ function css(elements, properties) {
256
+ var elmArray = toArray(elements);
257
+ if (typeof properties === 'string') {
258
+ return window.getComputedStyle(elmArray[0])[properties];
259
+ }
260
+ elmArray.forEach(function (element) {
261
+ Object.keys(properties).forEach(function (key) {
262
+ var value = properties[key];
263
+ element.style[key] = value;
264
+ });
265
+ });
266
+ return undefined;
267
+ }
268
+ function removeCss(element, property) {
269
+ element.style.removeProperty(property);
270
+ }
271
+ function wrap(element, _ref) {
272
+ var _ref$tag = _ref.tag,
273
+ tag = _ref$tag === void 0 ? 'div' : _ref$tag,
274
+ className = _ref.className,
275
+ id = _ref.id,
276
+ style = _ref.style;
277
+ var wrapper = document.createElement(tag);
278
+ if (className) wrapper.className = className;
279
+ if (id) wrapper.id = id;
280
+ if (style) wrapper.style = style;
281
+ element.parentNode.insertBefore(wrapper, element);
282
+ element.parentNode.removeChild(element);
283
+ wrapper.appendChild(element);
284
+ return wrapper;
285
+ }
286
+ function unwrap(element) {
287
+ var parent = element.parentNode;
288
+ if (parent !== document.body) {
289
+ parent.parentNode.insertBefore(element, parent);
290
+ parent.parentNode.removeChild(parent);
291
+ }
292
+ }
293
+ function remove(elements) {
294
+ var elmArray = toArray(elements);
295
+ elmArray.forEach(function (element) {
296
+ element.parentNode.removeChild(element);
297
+ });
298
+ }
299
+ function clamp(num, min, max) {
300
+ return Math.min(Math.max(num, min), max);
301
+ }
302
+ function assignEvent(element, events, handler) {
303
+ if (typeof events === 'string') events = [events];
304
+ events.forEach(function (event) {
305
+ element.addEventListener(event, handler);
306
+ });
307
+ return function () {
308
+ events.forEach(function (event) {
309
+ element.removeEventListener(event, handler);
310
+ });
311
+ };
312
+ }
313
+ function getTouchPointsDistance(touches) {
314
+ var touch0 = touches[0];
315
+ var touch1 = touches[1];
316
+ return Math.sqrt(Math.pow(touch1.pageX - touch0.pageX, 2) + Math.pow(touch1.pageY - touch0.pageY, 2));
317
+ }
318
+
319
+ var Slider = /*#__PURE__*/function () {
320
+ function Slider(container, _ref) {
321
+ var _this = this;
322
+ var _onStart = _ref.onStart,
323
+ _onMove = _ref.onMove,
324
+ onEnd = _ref.onEnd,
325
+ isSliderEnabled = _ref.isSliderEnabled;
326
+ _classCallCheck(this, Slider);
327
+ _defineProperty(this, "startHandler", function (eStart) {
328
+ if (!_this.isSliderEnabled()) return;
329
+ _this.removeListeners();
330
+ eStart.preventDefault();
331
+ var moveHandler = _this.moveHandler,
332
+ endHandler = _this.endHandler,
333
+ onStart = _this.onStart;
334
+ var isTouchEvent = eStart.type === 'touchstart' || eStart.type === 'touchend';
335
+ _this.touchMoveEvent = isTouchEvent ? 'touchmove' : 'mousemove';
336
+ _this.touchEndEvent = isTouchEvent ? 'touchend' : 'mouseup';
337
+ _this.sx = isTouchEvent ? eStart.touches[0].clientX : eStart.clientX;
338
+ _this.sy = isTouchEvent ? eStart.touches[0].clientY : eStart.clientY;
339
+ onStart(eStart, {
340
+ x: _this.sx,
341
+ y: _this.sy
342
+ });
343
+
344
+ // add listeners
345
+ document.addEventListener(_this.touchMoveEvent, moveHandler);
346
+ document.addEventListener(_this.touchEndEvent, endHandler);
347
+ /*
348
+ add end handler in context menu as well.
349
+ As mouseup event is not trigger on context menu open
350
+ https://bugs.chromium.org/p/chromium/issues/detail?id=506801
351
+ */
352
+ document.addEventListener('contextmenu', endHandler);
353
+ });
354
+ _defineProperty(this, "moveHandler", function (eMove) {
355
+ if (!_this.isSliderEnabled()) return;
356
+ eMove.preventDefault();
357
+ var sx = _this.sx,
358
+ sy = _this.sy,
359
+ onMove = _this.onMove;
360
+ var isTouchEvent = _this.touchMoveEvent === 'touchmove';
361
+
362
+ // get the coordinates
363
+ var mx = isTouchEvent ? eMove.touches[0].clientX : eMove.clientX;
364
+ var my = isTouchEvent ? eMove.touches[0].clientY : eMove.clientY;
365
+ onMove(eMove, {
366
+ dx: mx - sx,
367
+ dy: my - sy,
368
+ mx: mx,
369
+ my: my
370
+ });
371
+ });
372
+ _defineProperty(this, "endHandler", function () {
373
+ if (!_this.isSliderEnabled()) return;
374
+ _this.removeListeners();
375
+ _this.onEnd();
376
+ });
377
+ this.container = container;
378
+ this.isSliderEnabled = isSliderEnabled;
379
+ this.onStart = _onStart || noop;
380
+ this.onMove = _onMove || noop;
381
+ this.onEnd = onEnd || noop;
382
+ }
383
+ return _createClass(Slider, [{
384
+ key: "removeListeners",
385
+ value:
386
+ // remove previous events if it's not removed
387
+ // - Case when while sliding mouse moved out of document and released there
388
+ function removeListeners() {
389
+ if (!this.touchMoveEvent) return;
390
+ document.removeEventListener(this.touchMoveEvent, this.moveHandler);
391
+ document.removeEventListener(this.touchEndEvent, this.endHandler);
392
+ document.removeEventListener('contextmenu', this.endHandler);
393
+ }
394
+ }, {
395
+ key: "init",
396
+ value: function init() {
397
+ var _this2 = this;
398
+ ['touchstart', 'mousedown'].forEach(function (evt) {
399
+ _this2.container.addEventListener(evt, _this2.startHandler);
400
+ });
401
+ }
402
+ }, {
403
+ key: "destroy",
404
+ value: function destroy() {
405
+ var _this3 = this;
406
+ ['touchstart', 'mousedown'].forEach(function (evt) {
407
+ _this3.container.removeEventListener(evt, _this3.startHandler);
408
+ });
409
+ this.removeListeners();
410
+ }
411
+ }]);
412
+ }();
413
+
414
+ var ImageViewer = /*#__PURE__*/function () {
415
+ function ImageViewer(element) {
416
+ var _this = this;
417
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
418
+ _classCallCheck(this, ImageViewer);
419
+ _defineProperty(this, "zoom", function (perc, point) {
420
+ var _options = _this._options,
421
+ _elements = _this._elements,
422
+ _state = _this._state;
423
+ var curPerc = _state.zoomValue,
424
+ imageDim = _state.imageDim,
425
+ containerDim = _state.containerDim,
426
+ zoomSliderLength = _state.zoomSliderLength;
427
+ var image = _elements.image,
428
+ zoomHandle = _elements.zoomHandle;
429
+ var maxZoom = _options.maxZoom;
430
+ perc = Math.round(Math.max(100, perc));
431
+ perc = Math.min(maxZoom, perc);
432
+ point = point || {
433
+ x: containerDim.w / 2,
434
+ y: containerDim.h / 2
435
+ };
436
+ var curLeft = parseFloat(css(image, 'left'));
437
+ var curTop = parseFloat(css(image, 'top'));
438
+
439
+ // clear any panning frames
440
+ _this._clearFrames();
441
+ var step = 0;
442
+ var baseLeft = (containerDim.w - imageDim.w) / 2;
443
+ var baseTop = (containerDim.h - imageDim.h) / 2;
444
+ var baseRight = containerDim.w - baseLeft;
445
+ var baseBottom = containerDim.h - baseTop;
446
+ var _zoom = function zoom() {
447
+ step++;
448
+ if (step < 16) {
449
+ _this._frames.zoomFrame = requestAnimationFrame(_zoom);
450
+ }
451
+ var tickZoom = easeOutQuart(step, curPerc, perc - curPerc, 16);
452
+ // snap in at the last percent to more often land at the exact value
453
+ // only do that at the target percent value to make the animation as smooth as possible
454
+ if (Math.abs(perc - tickZoom) < 1) {
455
+ tickZoom = perc;
456
+ }
457
+ var ratio = tickZoom / curPerc;
458
+ var imgWidth = imageDim.w * tickZoom / 100;
459
+ var imgHeight = imageDim.h * tickZoom / 100;
460
+ var newLeft = -((point.x - curLeft) * ratio - point.x);
461
+ var newTop = -((point.y - curTop) * ratio - point.y);
462
+
463
+ // fix for left and top
464
+ newLeft = Math.min(newLeft, baseLeft);
465
+ newTop = Math.min(newTop, baseTop);
466
+
467
+ // fix for right and bottom
468
+ if (newLeft + imgWidth < baseRight) {
469
+ newLeft = baseRight - imgWidth; // newLeft - (newLeft + imgWidth - baseRight)
470
+ }
471
+ if (newTop + imgHeight < baseBottom) {
472
+ newTop = baseBottom - imgHeight; // newTop + (newTop + imgHeight - baseBottom)
473
+ }
474
+ css(image, {
475
+ height: "".concat(imgHeight, "px"),
476
+ width: "".concat(imgWidth, "px"),
477
+ left: "".concat(newLeft, "px"),
478
+ top: "".concat(newTop, "px")
479
+ });
480
+ _this._state.zoomValue = tickZoom;
481
+ _this._resizeSnapHandle(imgWidth, imgHeight, newLeft, newTop);
482
+
483
+ // update zoom handle position
484
+ css(zoomHandle, {
485
+ left: "".concat((tickZoom - 100) * zoomSliderLength / (maxZoom - 100), "px")
486
+ });
487
+
488
+ // dispatch zoom changed event
489
+ if (_this._listeners.onZoomChange) {
490
+ _this._listeners.onZoomChange(_this._callbackData);
491
+ }
492
+ };
493
+ _zoom();
494
+ });
495
+ _defineProperty(this, "_clearFrames", function () {
496
+ var _this$_frames = _this._frames,
497
+ slideMomentumCheck = _this$_frames.slideMomentumCheck,
498
+ sliderMomentumFrame = _this$_frames.sliderMomentumFrame,
499
+ zoomFrame = _this$_frames.zoomFrame;
500
+ clearInterval(slideMomentumCheck);
501
+ cancelAnimationFrame(sliderMomentumFrame);
502
+ cancelAnimationFrame(zoomFrame);
503
+ });
504
+ _defineProperty(this, "_resizeSnapHandle", function (imgWidth, imgHeight, imgLeft, imgTop) {
505
+ var _elements = _this._elements,
506
+ _state = _this._state;
507
+ var snapHandle = _elements.snapHandle,
508
+ image = _elements.image;
509
+ var imageDim = _state.imageDim,
510
+ containerDim = _state.containerDim,
511
+ zoomValue = _state.zoomValue,
512
+ snapImageDim = _state.snapImageDim;
513
+ var imageWidth = imgWidth || imageDim.w * zoomValue / 100;
514
+ var imageHeight = imgHeight || imageDim.h * zoomValue / 100;
515
+ var imageLeft = imgLeft || parseFloat(css(image, 'left'));
516
+ var imageTop = imgTop || parseFloat(css(image, 'top'));
517
+ var left = -imageLeft * snapImageDim.w / imageWidth;
518
+ var top = -imageTop * snapImageDim.h / imageHeight;
519
+ var handleWidth = containerDim.w * snapImageDim.w / imageWidth;
520
+ var handleHeight = containerDim.h * snapImageDim.h / imageHeight;
521
+ css(snapHandle, {
522
+ top: "".concat(top, "px"),
523
+ left: "".concat(left, "px"),
524
+ width: "".concat(handleWidth, "px"),
525
+ height: "".concat(handleHeight, "px")
526
+ });
527
+ _this._state.snapHandleDim = {
528
+ w: handleWidth,
529
+ h: handleHeight
530
+ };
531
+ });
532
+ _defineProperty(this, "showSnapView", function (noTimeout) {
533
+ var _this$_state = _this._state,
534
+ snapViewVisible = _this$_state.snapViewVisible,
535
+ zoomValue = _this$_state.zoomValue,
536
+ loaded = _this$_state.loaded;
537
+ var snapView = _this._elements.snapView;
538
+ if (!_this._options.snapView) return;
539
+ if (snapViewVisible || zoomValue <= 100 || !loaded) return;
540
+ clearTimeout(_this._frames.snapViewTimeout);
541
+ _this._state.snapViewVisible = true;
542
+ css(snapView, {
543
+ opacity: 1,
544
+ pointerEvents: 'inherit'
545
+ });
546
+ if (!noTimeout) {
547
+ _this._frames.snapViewTimeout = setTimeout(_this.hideSnapView, 1500);
548
+ }
549
+ });
550
+ _defineProperty(this, "hideSnapView", function () {
551
+ var snapView = _this._elements.snapView;
552
+ css(snapView, {
553
+ opacity: 0,
554
+ pointerEvents: 'none'
555
+ });
556
+ _this._state.snapViewVisible = false;
557
+ });
558
+ _defineProperty(this, "refresh", function () {
559
+ var animate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
560
+ _this._calculateDimensions();
561
+ _this.resetZoom(animate);
562
+ });
563
+ var _this$_findContainerA = this._findContainerAndImageSrc(element, options),
564
+ container = _this$_findContainerA.container,
565
+ domElement = _this$_findContainerA.domElement,
566
+ imageSrc = _this$_findContainerA.imageSrc,
567
+ hiResImageSrc = _this$_findContainerA.hiResImageSrc;
568
+
569
+ // containers for elements
570
+ this._elements = {
571
+ container: container,
572
+ domElement: domElement
573
+ };
574
+ this._options = _objectSpread2(_objectSpread2({}, ImageViewer.defaults), options);
575
+
576
+ // container for all events
577
+ this._events = {};
578
+ this._listeners = this._options.listeners || {};
579
+
580
+ // container for all timeout and frames
581
+ this._frames = {};
582
+
583
+ // container for all sliders
584
+ this._sliders = {};
585
+
586
+ // maintain current state
587
+ this._state = {
588
+ zoomValue: this._options.zoomValue
589
+ };
590
+ this._images = {
591
+ imageSrc: imageSrc,
592
+ hiResImageSrc: hiResImageSrc
593
+ };
594
+ this._init();
595
+ if (imageSrc) {
596
+ this._loadImages();
597
+ }
598
+
599
+ // store reference of imageViewer in domElement
600
+ domElement._imageViewer = this;
601
+ }
602
+ return _createClass(ImageViewer, [{
603
+ key: "zoomInButton",
604
+ get: function get() {
605
+ return this._options.hasZoomButtons ? '<div class="iv-button-zoom--in" role="button"></div>' : '';
606
+ }
607
+ }, {
608
+ key: "zoomOutButton",
609
+ get: function get() {
610
+ return this._options.hasZoomButtons ? '<div class="iv-button-zoom--out" role="button"></div>' : '';
611
+ }
612
+ }, {
613
+ key: "imageViewHtml",
614
+ get: function get() {
615
+ return "\n <div class=\"iv-loader\"></div>\n <div class=\"iv-snap-view\">\n <div class=\"iv-snap-image-wrap\">\n <div class=\"iv-snap-handle\"></div>\n </div>\n <div class=\"iv-zoom-actions ".concat(this._options.hasZoomButtons ? 'iv-zoom-actions--has-buttons' : '', "\">\n ").concat(this.zoomInButton, "\n <div class=\"iv-zoom-slider\">\n <div class=\"iv-zoom-handle\"></div>\n </div>\n ").concat(this.zoomOutButton, "\n </div>\n </div>\n <div class=\"iv-image-view\" >\n <div class=\"iv-image-wrap\" ></div>\n </div>\n ");
616
+ }
617
+ }, {
618
+ key: "_findContainerAndImageSrc",
619
+ value: function _findContainerAndImageSrc(element) {
620
+ var domElement = element;
621
+ var imageSrc, hiResImageSrc;
622
+ if (typeof element === 'string') {
623
+ domElement = document.querySelector(element);
624
+ }
625
+
626
+ // throw error if imageViewer is already assigned
627
+ if (domElement._imageViewer) {
628
+ throw new Error('An image viewer is already being initiated on the element.');
629
+ }
630
+ var container = element;
631
+ if (domElement.tagName === 'IMG') {
632
+ imageSrc = domElement.src;
633
+ hiResImageSrc = domElement.getAttribute('high-res-src') || domElement.getAttribute('data-high-res-src');
634
+
635
+ // wrap the image with iv-container div
636
+ container = wrap(domElement, {
637
+ className: 'iv-container iv-image-mode',
638
+ style: {
639
+ display: 'inline-block',
640
+ overflow: 'hidden'
641
+ }
642
+ });
643
+
644
+ // hide the image and add iv-original-img class
645
+ css(domElement, {
646
+ opacity: 0,
647
+ position: 'relative',
648
+ zIndex: -1
649
+ });
650
+ } else {
651
+ imageSrc = domElement.getAttribute('src') || domElement.getAttribute('data-src');
652
+ hiResImageSrc = domElement.getAttribute('high-res-src') || domElement.getAttribute('data-high-res-src');
653
+ }
654
+ return {
655
+ container: container,
656
+ domElement: domElement,
657
+ imageSrc: imageSrc,
658
+ hiResImageSrc: hiResImageSrc
659
+ };
660
+ }
661
+ }, {
662
+ key: "_init",
663
+ value: function _init() {
664
+ // initialize the dom elements
665
+ this._initDom();
666
+
667
+ // initialize slider
668
+ this._initImageSlider();
669
+ this._initSnapSlider();
670
+ this._initZoomSlider();
671
+
672
+ // enable pinch and zoom feature for touch screens
673
+ this._pinchAndZoom();
674
+
675
+ // enable scroll zoom interaction
676
+ this._scrollZoom();
677
+
678
+ // enable double tap to zoom interaction
679
+ this._doubleTapToZoom();
680
+
681
+ // initialize events
682
+ this._initEvents();
683
+ }
684
+ }, {
685
+ key: "_initDom",
686
+ value: function _initDom() {
687
+ var container = this._elements.container;
688
+
689
+ // add image-viewer layout elements
690
+ createElement({
691
+ tagName: 'div',
692
+ className: 'iv-wrap',
693
+ html: this.imageViewHtml,
694
+ parent: container
695
+ });
696
+
697
+ // add container class on the container
698
+ addClass(container, 'iv-container');
699
+
700
+ // if the element is static position, position it relatively
701
+ if (css(container, 'position') === 'static') {
702
+ css(container, {
703
+ position: 'relative'
704
+ });
705
+ }
706
+
707
+ // save references for later use
708
+ this._elements = _objectSpread2(_objectSpread2({}, this._elements), {}, {
709
+ snapView: container.querySelector('.iv-snap-view'),
710
+ snapImageWrap: container.querySelector('.iv-snap-image-wrap'),
711
+ imageWrap: container.querySelector('.iv-image-wrap'),
712
+ snapHandle: container.querySelector('.iv-snap-handle'),
713
+ zoomHandle: container.querySelector('.iv-zoom-handle'),
714
+ zoomIn: container.querySelector('.iv-button-zoom--in'),
715
+ zoomOut: container.querySelector('.iv-button-zoom--out')
716
+ });
717
+ if (this._listeners.onInit) {
718
+ this._listeners.onInit(this._callbackData);
719
+ }
720
+ }
721
+ }, {
722
+ key: "_initImageSlider",
723
+ value: function _initImageSlider() {
724
+ var _this2 = this;
725
+ var _elements = this._elements;
726
+ var imageWrap = _elements.imageWrap;
727
+ var positions, currentPos;
728
+
729
+ /* Add slide interaction to image */
730
+ var imageSlider = new Slider(imageWrap, {
731
+ isSliderEnabled: function isSliderEnabled() {
732
+ var _this2$_state = _this2._state,
733
+ loaded = _this2$_state.loaded,
734
+ zooming = _this2$_state.zooming,
735
+ zoomValue = _this2$_state.zoomValue;
736
+ return loaded && !zooming && zoomValue > 100;
737
+ },
738
+ onStart: function onStart(e, position) {
739
+ var snapSlider = _this2._sliders.snapSlider;
740
+
741
+ // clear all animation frame and interval
742
+ _this2._clearFrames();
743
+ snapSlider.onStart();
744
+
745
+ // reset positions
746
+ positions = [position, position];
747
+ currentPos = undefined;
748
+ _this2._frames.slideMomentumCheck = setInterval(function () {
749
+ if (!currentPos) return;
750
+ positions.shift();
751
+ positions.push({
752
+ x: currentPos.mx,
753
+ y: currentPos.my
754
+ });
755
+ }, 50);
756
+ },
757
+ onMove: function onMove(e, position) {
758
+ var snapImageDim = _this2._state.snapImageDim;
759
+ var snapSlider = _this2._sliders.snapSlider;
760
+ var imageCurrentDim = _this2._getImageCurrentDim();
761
+ currentPos = position;
762
+ snapSlider.onMove(e, {
763
+ dx: -position.dx * snapImageDim.w / imageCurrentDim.w,
764
+ dy: -position.dy * snapImageDim.h / imageCurrentDim.h
765
+ });
766
+ },
767
+ onEnd: function onEnd() {
768
+ var snapImageDim = _this2._state.snapImageDim;
769
+ var snapSlider = _this2._sliders.snapSlider;
770
+ var imageCurrentDim = _this2._getImageCurrentDim();
771
+
772
+ // clear all animation frame and interval
773
+ _this2._clearFrames();
774
+ var step, positionX, positionY;
775
+ var xDiff = positions[1].x - positions[0].x;
776
+ var yDiff = positions[1].y - positions[0].y;
777
+ var _momentum = function momentum() {
778
+ if (step <= 60) {
779
+ _this2._frames.sliderMomentumFrame = requestAnimationFrame(_momentum);
780
+ }
781
+ positionX += easeOutQuart(step, xDiff / 3, -xDiff / 3, 60);
782
+ positionY += easeOutQuart(step, yDiff / 3, -yDiff / 3, 60);
783
+ snapSlider.onMove(null, {
784
+ dx: -(positionX * snapImageDim.w / imageCurrentDim.w),
785
+ dy: -(positionY * snapImageDim.h / imageCurrentDim.h)
786
+ });
787
+ step++;
788
+ };
789
+ if (Math.abs(xDiff) > 30 || Math.abs(yDiff) > 30) {
790
+ step = 1;
791
+ positionX = currentPos.dx;
792
+ positionY = currentPos.dy;
793
+ _momentum();
794
+ }
795
+ }
796
+ });
797
+ imageSlider.init();
798
+ this._sliders.imageSlider = imageSlider;
799
+ }
800
+ }, {
801
+ key: "_initSnapSlider",
802
+ value: function _initSnapSlider() {
803
+ var _this3 = this;
804
+ var snapHandle = this._elements.snapHandle;
805
+ var startHandleTop, startHandleLeft;
806
+ var snapSlider = new Slider(snapHandle, {
807
+ isSliderEnabled: function isSliderEnabled() {
808
+ return _this3._state.loaded;
809
+ },
810
+ onStart: function onStart() {
811
+ var _this3$_frames = _this3._frames,
812
+ slideMomentumCheck = _this3$_frames.slideMomentumCheck,
813
+ sliderMomentumFrame = _this3$_frames.sliderMomentumFrame;
814
+ startHandleTop = parseFloat(css(snapHandle, 'top'));
815
+ startHandleLeft = parseFloat(css(snapHandle, 'left'));
816
+
817
+ // stop momentum on image
818
+ clearInterval(slideMomentumCheck);
819
+ cancelAnimationFrame(sliderMomentumFrame);
820
+ },
821
+ onMove: function onMove(e, position) {
822
+ var _this3$_state = _this3._state,
823
+ snapHandleDim = _this3$_state.snapHandleDim,
824
+ snapImageDim = _this3$_state.snapImageDim;
825
+ var image = _this3._elements.image;
826
+ var imageCurrentDim = _this3._getImageCurrentDim();
827
+
828
+ // find handle left and top and make sure they lay between the snap image
829
+ var maxLeft = Math.max(snapImageDim.w - snapHandleDim.w, startHandleLeft);
830
+ var maxTop = Math.max(snapImageDim.h - snapHandleDim.h, startHandleTop);
831
+ var minLeft = Math.min(0, startHandleLeft);
832
+ var minTop = Math.min(0, startHandleTop);
833
+ var left = clamp(startHandleLeft + position.dx, minLeft, maxLeft);
834
+ var top = clamp(startHandleTop + position.dy, minTop, maxTop);
835
+ var imgLeft = -left * imageCurrentDim.w / snapImageDim.w;
836
+ var imgTop = -top * imageCurrentDim.h / snapImageDim.h;
837
+ css(snapHandle, {
838
+ left: "".concat(left, "px"),
839
+ top: "".concat(top, "px")
840
+ });
841
+ css(image, {
842
+ left: "".concat(imgLeft, "px"),
843
+ top: "".concat(imgTop, "px")
844
+ });
845
+ }
846
+ });
847
+ snapSlider.init();
848
+ this._sliders.snapSlider = snapSlider;
849
+ }
850
+ }, {
851
+ key: "_initZoomSlider",
852
+ value: function _initZoomSlider() {
853
+ var _this4 = this;
854
+ var _this$_elements = this._elements,
855
+ snapView = _this$_elements.snapView,
856
+ zoomHandle = _this$_elements.zoomHandle;
857
+
858
+ // zoom in zoom out using zoom handle
859
+ var sliderElm = snapView.querySelector('.iv-zoom-slider');
860
+ var leftOffset, handleWidth;
861
+
862
+ // on zoom slider we have to follow the mouse and set the handle to its position.
863
+ var zoomSlider = new Slider(sliderElm, {
864
+ isSliderEnabled: function isSliderEnabled() {
865
+ return _this4._state.loaded;
866
+ },
867
+ onStart: function onStart(eStart) {
868
+ var slider = _this4._sliders.zoomSlider;
869
+ leftOffset = sliderElm.getBoundingClientRect().left;
870
+ handleWidth = parseInt(css(zoomHandle, 'width'), 10);
871
+
872
+ // move the handle to current mouse position
873
+ slider.onMove(eStart);
874
+ },
875
+ onMove: function onMove(e) {
876
+ var maxZoom = _this4._options.maxZoom;
877
+ var zoomSliderLength = _this4._state.zoomSliderLength;
878
+ var clientX = e.clientX !== undefined ? e.clientX : e.touches[0].clientX;
879
+ var newLeft = clamp(clientX - leftOffset - handleWidth / 2, 0, zoomSliderLength);
880
+ var zoomValue = 100 + (maxZoom - 100) * newLeft / zoomSliderLength;
881
+ _this4.zoom(zoomValue);
882
+ }
883
+ });
884
+ zoomSlider.init();
885
+ this._sliders.zoomSlider = zoomSlider;
886
+ }
887
+ }, {
888
+ key: "_initEvents",
889
+ value: function _initEvents() {
890
+ this._snapViewEvents();
891
+
892
+ // handle window resize
893
+ if (this._options.refreshOnResize) {
894
+ this._events.onWindowResize = assignEvent(window, 'resize', this.refresh);
895
+ }
896
+ this._events.onDragStart = assignEvent(this._elements.container, 'dragstart', preventDefault);
897
+ }
898
+ }, {
899
+ key: "_snapViewEvents",
900
+ value: function _snapViewEvents() {
901
+ var _this5 = this;
902
+ var _this$_elements2 = this._elements,
903
+ imageWrap = _this$_elements2.imageWrap,
904
+ snapView = _this$_elements2.snapView;
905
+
906
+ // show snapView on mouse move
907
+ this._events.snapViewOnMouseMove = assignEvent(imageWrap, ['touchmove', 'mousemove'], function () {
908
+ _this5.showSnapView();
909
+ });
910
+
911
+ // keep showing snapView if on hover over it without any timeout
912
+ this._events.mouseEnterSnapView = assignEvent(snapView, ['mouseenter', 'touchstart'], function () {
913
+ _this5._state.snapViewVisible = false;
914
+ _this5.showSnapView(true);
915
+ });
916
+
917
+ // on mouse leave set timeout to hide snapView
918
+ this._events.mouseLeaveSnapView = assignEvent(snapView, ['mouseleave', 'touchend'], function () {
919
+ _this5._state.snapViewVisible = false;
920
+ _this5.showSnapView();
921
+ });
922
+ if (!this._options.hasZoomButtons) {
923
+ return;
924
+ }
925
+ var _this$_elements3 = this._elements,
926
+ zoomOut = _this$_elements3.zoomOut,
927
+ zoomIn = _this$_elements3.zoomIn;
928
+ this._events.zoomInClick = assignEvent(zoomIn, ['click'], function () {
929
+ _this5.zoom(_this5._state.zoomValue + _this5._options.zoomStep || 50);
930
+ });
931
+ this._events.zoomOutClick = assignEvent(zoomOut, ['click'], function () {
932
+ _this5.zoom(_this5._state.zoomValue - _this5._options.zoomStep || 50);
933
+ });
934
+ }
935
+ }, {
936
+ key: "_pinchAndZoom",
937
+ value: function _pinchAndZoom() {
938
+ var _this6 = this;
939
+ var _this$_elements4 = this._elements,
940
+ imageWrap = _this$_elements4.imageWrap,
941
+ container = _this$_elements4.container;
942
+
943
+ // apply pinch and zoom feature
944
+ var onPinchStart = function onPinchStart(eStart) {
945
+ var _this6$_state = _this6._state,
946
+ loaded = _this6$_state.loaded,
947
+ startZoomValue = _this6$_state.zoomValue;
948
+ var events = _this6._events;
949
+ if (!loaded) return;
950
+ var touch0 = eStart.touches[0];
951
+ var touch1 = eStart.touches[1];
952
+ if (!(touch0 && touch1)) {
953
+ return;
954
+ }
955
+ _this6._state.zooming = true;
956
+ var contOffset = container.getBoundingClientRect();
957
+
958
+ // find distance between two touch points
959
+ var startDist = getTouchPointsDistance(eStart.touches);
960
+
961
+ // find the center for the zoom
962
+ var center = {
963
+ x: (touch1.clientX + touch0.clientX) / 2 - contOffset.left,
964
+ y: (touch1.clientY + touch0.clientY) / 2 - contOffset.top
965
+ };
966
+ var moveListener = function moveListener(eMove) {
967
+ // eMove.preventDefault();
968
+
969
+ var newDist = getTouchPointsDistance(eMove.touches);
970
+ var zoomValue = startZoomValue + (newDist - startDist) / 2;
971
+ _this6.zoom(zoomValue, center);
972
+ };
973
+ var endListener = function endListener(eEnd) {
974
+ // unbind events
975
+ events.pinchMove();
976
+ events.pinchEnd();
977
+ _this6._state.zooming = false;
978
+ // properly resume move event if one finger remains
979
+ if (eEnd.touches.length === 1) {
980
+ _this6._sliders.imageSlider.startHandler(eEnd);
981
+ }
982
+ };
983
+
984
+ // remove events if already assigned
985
+ if (events.pinchMove) events.pinchMove();
986
+ if (events.pinchEnd) events.pinchEnd();
987
+
988
+ // assign events
989
+ events.pinchMove = assignEvent(document, 'touchmove', moveListener);
990
+ events.pinchEnd = assignEvent(document, 'touchend', endListener);
991
+ };
992
+ this._events.pinchStart = assignEvent(imageWrap, 'touchstart', onPinchStart);
993
+ }
994
+ }, {
995
+ key: "_scrollZoom",
996
+ value: function _scrollZoom() {
997
+ var _this7 = this;
998
+ /* Add zoom interaction in mouse wheel */
999
+ var _options = this._options;
1000
+ var _this$_elements5 = this._elements,
1001
+ container = _this$_elements5.container,
1002
+ imageWrap = _this$_elements5.imageWrap;
1003
+ var changedDelta = 0;
1004
+ var onMouseWheel = function onMouseWheel(e) {
1005
+ var _this7$_state = _this7._state,
1006
+ loaded = _this7$_state.loaded,
1007
+ zoomValue = _this7$_state.zoomValue;
1008
+ if (!_options.zoomOnMouseWheel || !loaded) return;
1009
+
1010
+ // clear all animation frame and interval
1011
+ _this7._clearFrames();
1012
+
1013
+ // cross-browser wheel delta
1014
+ var delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail || -e.deltaY));
1015
+ var newZoomValue = zoomValue * (100 + delta * ZOOM_CONSTANT) / 100;
1016
+ if (!(newZoomValue >= 100 && newZoomValue <= _options.maxZoom)) {
1017
+ changedDelta += Math.abs(delta);
1018
+ } else {
1019
+ changedDelta = 0;
1020
+ }
1021
+ e.preventDefault();
1022
+ if (changedDelta > MOUSE_WHEEL_COUNT) return;
1023
+ var contOffset = container.getBoundingClientRect();
1024
+ var x = e.clientX - contOffset.left;
1025
+ var y = e.clientY - contOffset.top;
1026
+ _this7.zoom(newZoomValue, {
1027
+ x: x,
1028
+ y: y
1029
+ });
1030
+
1031
+ // show the snap viewer
1032
+ _this7.showSnapView();
1033
+ };
1034
+ this._events.scrollZoom = assignEvent(imageWrap, 'wheel', onMouseWheel);
1035
+ }
1036
+ }, {
1037
+ key: "_doubleTapToZoom",
1038
+ value: function _doubleTapToZoom() {
1039
+ var _this8 = this;
1040
+ var imageWrap = this._elements.imageWrap;
1041
+ // handle double tap for zoom in and zoom out
1042
+
1043
+ var touchTime = 0;
1044
+ var point;
1045
+ var onDoubleTap = function onDoubleTap(e) {
1046
+ if (touchTime === 0) {
1047
+ touchTime = Date.now();
1048
+ point = {
1049
+ x: e.clientX,
1050
+ y: e.clientY
1051
+ };
1052
+ } else if (Date.now() - touchTime < 500 && Math.abs(e.clientX - point.x) < 50 && Math.abs(e.clientY - point.y) < 50) {
1053
+ if (_this8._state.zoomValue === _this8._options.zoomValue) {
1054
+ _this8.zoom(200);
1055
+ } else {
1056
+ _this8.resetZoom();
1057
+ }
1058
+ touchTime = 0;
1059
+ } else {
1060
+ touchTime = 0;
1061
+ }
1062
+ };
1063
+ this._events.doubleTapToZoom = assignEvent(imageWrap, 'click', onDoubleTap);
1064
+ }
1065
+ }, {
1066
+ key: "_getImageCurrentDim",
1067
+ value: function _getImageCurrentDim() {
1068
+ var _this$_state2 = this._state,
1069
+ zoomValue = _this$_state2.zoomValue,
1070
+ imageDim = _this$_state2.imageDim;
1071
+ return {
1072
+ w: imageDim.w * (zoomValue / 100),
1073
+ h: imageDim.h * (zoomValue / 100)
1074
+ };
1075
+ }
1076
+ }, {
1077
+ key: "_loadImages",
1078
+ value: function _loadImages() {
1079
+ var _this9 = this;
1080
+ var _images = this._images,
1081
+ _elements = this._elements;
1082
+ var imageSrc = _images.imageSrc,
1083
+ hiResImageSrc = _images.hiResImageSrc;
1084
+ var container = _elements.container,
1085
+ snapImageWrap = _elements.snapImageWrap,
1086
+ imageWrap = _elements.imageWrap;
1087
+ var ivLoader = container.querySelector('.iv-loader');
1088
+
1089
+ // remove old images
1090
+ remove(container.querySelectorAll('.iv-snap-image, .iv-image'));
1091
+
1092
+ // add snapView image
1093
+ var snapImage = createElement({
1094
+ tagName: 'img',
1095
+ className: 'iv-snap-image',
1096
+ src: imageSrc,
1097
+ insertBefore: snapImageWrap.firstChild,
1098
+ parent: snapImageWrap
1099
+ });
1100
+
1101
+ // add image
1102
+ var image = createElement({
1103
+ tagName: 'img',
1104
+ className: 'iv-image iv-small-image',
1105
+ src: imageSrc,
1106
+ parent: imageWrap
1107
+ });
1108
+ this._state.loaded = false;
1109
+
1110
+ // store image reference in _elements
1111
+ this._elements.image = image;
1112
+ this._elements.snapImage = snapImage;
1113
+ css(ivLoader, {
1114
+ display: 'block'
1115
+ });
1116
+
1117
+ // keep visibility hidden until image is loaded
1118
+ css(image, {
1119
+ visibility: 'hidden'
1120
+ });
1121
+
1122
+ // hide snap view if open
1123
+ this.hideSnapView();
1124
+ var onImageLoad = function onImageLoad() {
1125
+ // hide the iv loader
1126
+ css(ivLoader, {
1127
+ display: 'none'
1128
+ });
1129
+
1130
+ // show the image
1131
+ css(image, {
1132
+ visibility: 'visible'
1133
+ });
1134
+
1135
+ // load high resolution image if provided
1136
+ if (hiResImageSrc) {
1137
+ _this9._loadHighResImage(hiResImageSrc);
1138
+ }
1139
+
1140
+ // set loaded flag to true
1141
+ _this9._state.loaded = true;
1142
+
1143
+ // calculate the dimension
1144
+ _this9._calculateDimensions();
1145
+
1146
+ // dispatch image load event
1147
+ if (_this9._listeners.onImageLoaded) {
1148
+ _this9._listeners.onImageLoaded(_this9._callbackData);
1149
+ }
1150
+
1151
+ // reset the zoom
1152
+ _this9.resetZoom();
1153
+ };
1154
+ if (imageLoaded(image)) {
1155
+ onImageLoad();
1156
+ } else {
1157
+ if (typeof this._events.imageLoad === 'function') {
1158
+ this._events.imageLoad();
1159
+ }
1160
+ this._events.imageLoad = assignEvent(image, 'load', onImageLoad);
1161
+ }
1162
+ }
1163
+ }, {
1164
+ key: "_loadHighResImage",
1165
+ value: function _loadHighResImage(hiResImageSrc) {
1166
+ var _this0 = this;
1167
+ var _this$_elements6 = this._elements,
1168
+ imageWrap = _this$_elements6.imageWrap,
1169
+ container = _this$_elements6.container;
1170
+ var lowResImg = this._elements.image;
1171
+ var hiResImage = createElement({
1172
+ tagName: 'img',
1173
+ className: 'iv-image iv-large-image',
1174
+ src: hiResImageSrc,
1175
+ parent: imageWrap,
1176
+ style: lowResImg.style.cssText
1177
+ });
1178
+
1179
+ // add all the style attributes from lowResImg to highResImg
1180
+ hiResImage.style.cssText = lowResImg.style.cssText;
1181
+ this._elements.image = container.querySelectorAll('.iv-image');
1182
+ var onHighResImageLoad = function onHighResImageLoad() {
1183
+ // remove the low size image and set this image as default image
1184
+ remove(lowResImg);
1185
+ _this0._elements.image = hiResImage;
1186
+ // this._calculateDimensions();
1187
+ };
1188
+ if (imageLoaded(hiResImage)) {
1189
+ onHighResImageLoad();
1190
+ } else {
1191
+ if (typeof this._events.hiResImageLoad === 'function') {
1192
+ this._events.hiResImageLoad();
1193
+ }
1194
+ this._events.hiResImageLoad = assignEvent(hiResImage, 'load', onHighResImageLoad);
1195
+ }
1196
+ }
1197
+ }, {
1198
+ key: "_calculateDimensions",
1199
+ value: function _calculateDimensions() {
1200
+ var _this$_elements7 = this._elements,
1201
+ image = _this$_elements7.image,
1202
+ container = _this$_elements7.container,
1203
+ snapView = _this$_elements7.snapView,
1204
+ snapImage = _this$_elements7.snapImage,
1205
+ zoomHandle = _this$_elements7.zoomHandle;
1206
+
1207
+ // calculate content width of image and snap image
1208
+ var imageWidth = parseInt(css(image, 'width'), 10);
1209
+ var imageHeight = parseInt(css(image, 'height'), 10);
1210
+ var contWidth = parseInt(css(container, 'width'), 10);
1211
+ var contHeight = parseInt(css(container, 'height'), 10);
1212
+ var snapViewWidth = snapView.clientWidth;
1213
+ var snapViewHeight = snapView.clientHeight;
1214
+
1215
+ // set the container dimension
1216
+ this._state.containerDim = {
1217
+ w: contWidth,
1218
+ h: contHeight
1219
+ };
1220
+
1221
+ // set the image dimension
1222
+ var ratio = imageWidth / imageHeight;
1223
+ var imgWidth = imageWidth > imageHeight && contHeight >= contWidth || ratio * contHeight > contWidth ? contWidth : ratio * contHeight;
1224
+ var imgHeight = imgWidth / ratio;
1225
+ this._state.imageDim = {
1226
+ w: imgWidth,
1227
+ h: imgHeight
1228
+ };
1229
+
1230
+ // reset image position and zoom
1231
+ css(image, {
1232
+ width: "".concat(imgWidth, "px"),
1233
+ height: "".concat(imgHeight, "px"),
1234
+ left: "".concat((contWidth - imgWidth) / 2, "px"),
1235
+ top: "".concat((contHeight - imgHeight) / 2, "px"),
1236
+ maxWidth: 'none',
1237
+ maxHeight: 'none'
1238
+ });
1239
+
1240
+ // set the snap Image dimension
1241
+ var snapWidth = imgWidth > imgHeight ? snapViewWidth : imgWidth * snapViewHeight / imgHeight;
1242
+ var snapHeight = imgHeight > imgWidth ? snapViewHeight : imgHeight * snapViewWidth / imgWidth;
1243
+ this._state.snapImageDim = {
1244
+ w: snapWidth,
1245
+ h: snapHeight
1246
+ };
1247
+ css(snapImage, {
1248
+ width: "".concat(snapWidth, "px"),
1249
+ height: "".concat(snapHeight, "px")
1250
+ });
1251
+ var zoomSlider = snapView.querySelector('.iv-zoom-slider').clientWidth;
1252
+ // calculate zoom slider area
1253
+ this._state.zoomSliderLength = zoomSlider - zoomHandle.offsetWidth;
1254
+ }
1255
+ }, {
1256
+ key: "resetZoom",
1257
+ value: function resetZoom() {
1258
+ var animate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
1259
+ var zoomValue = this._options.zoomValue;
1260
+ if (!animate) {
1261
+ this._state.zoomValue = zoomValue;
1262
+ }
1263
+ this.zoom(zoomValue);
1264
+ }
1265
+ }, {
1266
+ key: "load",
1267
+ value: function load(imageSrc, hiResImageSrc) {
1268
+ this._images = {
1269
+ imageSrc: imageSrc,
1270
+ hiResImageSrc: hiResImageSrc
1271
+ };
1272
+ this._loadImages();
1273
+ }
1274
+ }, {
1275
+ key: "destroy",
1276
+ value: function destroy() {
1277
+ var _this$_elements8 = this._elements,
1278
+ container = _this$_elements8.container,
1279
+ domElement = _this$_elements8.domElement;
1280
+ // destroy all the sliders
1281
+ Object.entries(this._sliders).forEach(function (_ref) {
1282
+ var _ref2 = _slicedToArray(_ref, 2),
1283
+ slider = _ref2[1];
1284
+ slider.destroy();
1285
+ });
1286
+
1287
+ // unbind all events
1288
+ Object.entries(this._events).forEach(function (_ref3) {
1289
+ var _ref4 = _slicedToArray(_ref3, 2),
1290
+ unbindEvent = _ref4[1];
1291
+ unbindEvent();
1292
+ });
1293
+
1294
+ // clear all the frames
1295
+ this._clearFrames();
1296
+
1297
+ // remove html from the container
1298
+ remove(container.querySelector('.iv-wrap'));
1299
+
1300
+ // remove iv-container class from container
1301
+ removeClass(container, 'iv-container');
1302
+
1303
+ // remove added style from container
1304
+ removeCss(document.querySelector('html'), 'relative');
1305
+
1306
+ // if container has original image, unwrap the image and remove the class
1307
+ // which will happen when domElement is not the container
1308
+ if (domElement !== container) {
1309
+ unwrap(domElement);
1310
+ }
1311
+
1312
+ // remove imageViewer reference from dom element
1313
+ domElement._imageViewer = null;
1314
+ if (this._listeners.onDestroy) {
1315
+ this._listeners.onDestroy();
1316
+ }
1317
+ }
1318
+
1319
+ /**
1320
+ * Data will be passed to the callback registered with each new instance
1321
+ */
1322
+ }, {
1323
+ key: "_callbackData",
1324
+ get: function get() {
1325
+ return {
1326
+ container: this._elements.container,
1327
+ snapView: this._elements.snapView,
1328
+ zoomValue: this._state.zoomValue,
1329
+ reachedMin: Math.abs(this._state.zoomValue - 100) < 1,
1330
+ reachedMax: Math.abs(this._state.zoomValue - this._options.maxZoom) < 1,
1331
+ instance: this
1332
+ };
1333
+ }
1334
+ }]);
1335
+ }();
1336
+ ImageViewer.defaults = {
1337
+ zoomValue: 100,
1338
+ snapView: true,
1339
+ maxZoom: 500,
1340
+ refreshOnResize: true,
1341
+ zoomOnMouseWheel: true,
1342
+ hasZoomButtons: false,
1343
+ zoomStep: 50,
1344
+ listeners: {
1345
+ onInit: null,
1346
+ onDestroy: null,
1347
+ onImageLoaded: null,
1348
+ onZoomChange: null
1349
+ }
1350
+ };
1351
+
1352
+ var fullScreenHtml = "\n <div class=\"iv-fullscreen-container\"></div>\n <div class=\"iv-fullscreen-close\"></div>\n";
1353
+ var FullScreenViewer = /*#__PURE__*/function (_ImageViewer) {
1354
+ function FullScreenViewer() {
1355
+ var _this;
1356
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1357
+ _classCallCheck(this, FullScreenViewer);
1358
+ var fullScreenElem = createElement({
1359
+ tagName: 'div',
1360
+ className: 'iv-fullscreen',
1361
+ html: fullScreenHtml,
1362
+ parent: document.body
1363
+ });
1364
+ var container = fullScreenElem.querySelector('.iv-fullscreen-container');
1365
+
1366
+ // call the ImageViewer constructor
1367
+ _this = _callSuper(this, FullScreenViewer, [container, _objectSpread2(_objectSpread2({}, options), {}, {
1368
+ refreshOnResize: false
1369
+ })]);
1370
+
1371
+ // add fullScreenElem on element list
1372
+ _defineProperty(_this, "hide", function () {
1373
+ // hide the fullscreen
1374
+ css(_this._elements.fullScreen, {
1375
+ display: 'none'
1376
+ });
1377
+
1378
+ // enable scroll
1379
+ removeCss(document.querySelector('html'), 'overflow');
1380
+
1381
+ // remove window event
1382
+ if (_this._events.onWindowResize) {
1383
+ _this._events.onWindowResize();
1384
+ }
1385
+ });
1386
+ _this._elements.fullScreen = fullScreenElem;
1387
+ _this._initFullScreenEvents();
1388
+ return _this;
1389
+ }
1390
+ _inherits(FullScreenViewer, _ImageViewer);
1391
+ return _createClass(FullScreenViewer, [{
1392
+ key: "_initFullScreenEvents",
1393
+ value: function _initFullScreenEvents() {
1394
+ var fullScreen = this._elements.fullScreen;
1395
+ var closeBtn = fullScreen.querySelector('.iv-fullscreen-close');
1396
+
1397
+ // add close button event
1398
+ this._events.onCloseBtnClick = assignEvent(closeBtn, 'click', this.hide);
1399
+ }
1400
+ }, {
1401
+ key: "show",
1402
+ value: function show(imageSrc, hiResImageSrc) {
1403
+ // show the element
1404
+ css(this._elements.fullScreen, {
1405
+ display: 'block'
1406
+ });
1407
+
1408
+ // if image source is provide load image source
1409
+ if (imageSrc) {
1410
+ this.load(imageSrc, hiResImageSrc);
1411
+ }
1412
+
1413
+ // handle window resize
1414
+ this._events.onWindowResize = assignEvent(window, 'resize', this.refresh);
1415
+
1416
+ // disable scroll on html
1417
+ css(document.querySelector('html'), {
1418
+ overflow: 'hidden'
1419
+ });
1420
+ }
1421
+ }, {
1422
+ key: "destroy",
1423
+ value: function destroy() {
1424
+ var fullScreen = this._elements.fullScreen;
1425
+
1426
+ // restore scroll before removing elements
1427
+ this.hide();
1428
+
1429
+ // destroy image viewer
1430
+ _superPropGet(FullScreenViewer, "destroy", this)([]);
1431
+
1432
+ // remove the element
1433
+ remove(fullScreen);
1434
+ }
1435
+ }]);
1436
+ }(ImageViewer);
1437
+
1438
+ ImageViewer.FullScreenViewer = FullScreenViewer;
1439
+
1440
+ return ImageViewer;
1441
+
1442
+ }));