@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,962 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+ var _util = require("./util");
8
+ var _Slider = _interopRequireDefault(require("./Slider"));
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
10
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
11
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
12
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
13
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); 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; } }
14
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
15
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
16
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
17
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
18
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
19
+ function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
20
+ function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
21
+ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
22
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
23
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
24
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
25
+ var ImageViewer = /*#__PURE__*/function () {
26
+ function ImageViewer(element) {
27
+ var _this = this;
28
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
29
+ _classCallCheck(this, ImageViewer);
30
+ _defineProperty(this, "zoom", function (perc, point) {
31
+ var _options = _this._options,
32
+ _elements = _this._elements,
33
+ _state = _this._state;
34
+ var curPerc = _state.zoomValue,
35
+ imageDim = _state.imageDim,
36
+ containerDim = _state.containerDim,
37
+ zoomSliderLength = _state.zoomSliderLength;
38
+ var image = _elements.image,
39
+ zoomHandle = _elements.zoomHandle;
40
+ var maxZoom = _options.maxZoom;
41
+ perc = Math.round(Math.max(100, perc));
42
+ perc = Math.min(maxZoom, perc);
43
+ point = point || {
44
+ x: containerDim.w / 2,
45
+ y: containerDim.h / 2
46
+ };
47
+ var curLeft = parseFloat((0, _util.css)(image, 'left'));
48
+ var curTop = parseFloat((0, _util.css)(image, 'top'));
49
+
50
+ // clear any panning frames
51
+ _this._clearFrames();
52
+ var step = 0;
53
+ var baseLeft = (containerDim.w - imageDim.w) / 2;
54
+ var baseTop = (containerDim.h - imageDim.h) / 2;
55
+ var baseRight = containerDim.w - baseLeft;
56
+ var baseBottom = containerDim.h - baseTop;
57
+ var _zoom = function zoom() {
58
+ step++;
59
+ if (step < 16) {
60
+ _this._frames.zoomFrame = requestAnimationFrame(_zoom);
61
+ }
62
+ var tickZoom = (0, _util.easeOutQuart)(step, curPerc, perc - curPerc, 16);
63
+ // snap in at the last percent to more often land at the exact value
64
+ // only do that at the target percent value to make the animation as smooth as possible
65
+ if (Math.abs(perc - tickZoom) < 1) {
66
+ tickZoom = perc;
67
+ }
68
+ var ratio = tickZoom / curPerc;
69
+ var imgWidth = imageDim.w * tickZoom / 100;
70
+ var imgHeight = imageDim.h * tickZoom / 100;
71
+ var newLeft = -((point.x - curLeft) * ratio - point.x);
72
+ var newTop = -((point.y - curTop) * ratio - point.y);
73
+
74
+ // fix for left and top
75
+ newLeft = Math.min(newLeft, baseLeft);
76
+ newTop = Math.min(newTop, baseTop);
77
+
78
+ // fix for right and bottom
79
+ if (newLeft + imgWidth < baseRight) {
80
+ newLeft = baseRight - imgWidth; // newLeft - (newLeft + imgWidth - baseRight)
81
+ }
82
+ if (newTop + imgHeight < baseBottom) {
83
+ newTop = baseBottom - imgHeight; // newTop + (newTop + imgHeight - baseBottom)
84
+ }
85
+ (0, _util.css)(image, {
86
+ height: "".concat(imgHeight, "px"),
87
+ width: "".concat(imgWidth, "px"),
88
+ left: "".concat(newLeft, "px"),
89
+ top: "".concat(newTop, "px")
90
+ });
91
+ _this._state.zoomValue = tickZoom;
92
+ _this._resizeSnapHandle(imgWidth, imgHeight, newLeft, newTop);
93
+
94
+ // update zoom handle position
95
+ (0, _util.css)(zoomHandle, {
96
+ left: "".concat((tickZoom - 100) * zoomSliderLength / (maxZoom - 100), "px")
97
+ });
98
+
99
+ // dispatch zoom changed event
100
+ if (_this._listeners.onZoomChange) {
101
+ _this._listeners.onZoomChange(_this._callbackData);
102
+ }
103
+ };
104
+ _zoom();
105
+ });
106
+ _defineProperty(this, "_clearFrames", function () {
107
+ var _this$_frames = _this._frames,
108
+ slideMomentumCheck = _this$_frames.slideMomentumCheck,
109
+ sliderMomentumFrame = _this$_frames.sliderMomentumFrame,
110
+ zoomFrame = _this$_frames.zoomFrame;
111
+ clearInterval(slideMomentumCheck);
112
+ cancelAnimationFrame(sliderMomentumFrame);
113
+ cancelAnimationFrame(zoomFrame);
114
+ });
115
+ _defineProperty(this, "_resizeSnapHandle", function (imgWidth, imgHeight, imgLeft, imgTop) {
116
+ var _elements = _this._elements,
117
+ _state = _this._state;
118
+ var snapHandle = _elements.snapHandle,
119
+ image = _elements.image;
120
+ var imageDim = _state.imageDim,
121
+ containerDim = _state.containerDim,
122
+ zoomValue = _state.zoomValue,
123
+ snapImageDim = _state.snapImageDim;
124
+ var imageWidth = imgWidth || imageDim.w * zoomValue / 100;
125
+ var imageHeight = imgHeight || imageDim.h * zoomValue / 100;
126
+ var imageLeft = imgLeft || parseFloat((0, _util.css)(image, 'left'));
127
+ var imageTop = imgTop || parseFloat((0, _util.css)(image, 'top'));
128
+ var left = -imageLeft * snapImageDim.w / imageWidth;
129
+ var top = -imageTop * snapImageDim.h / imageHeight;
130
+ var handleWidth = containerDim.w * snapImageDim.w / imageWidth;
131
+ var handleHeight = containerDim.h * snapImageDim.h / imageHeight;
132
+ (0, _util.css)(snapHandle, {
133
+ top: "".concat(top, "px"),
134
+ left: "".concat(left, "px"),
135
+ width: "".concat(handleWidth, "px"),
136
+ height: "".concat(handleHeight, "px")
137
+ });
138
+ _this._state.snapHandleDim = {
139
+ w: handleWidth,
140
+ h: handleHeight
141
+ };
142
+ });
143
+ _defineProperty(this, "showSnapView", function (noTimeout) {
144
+ var _this$_state = _this._state,
145
+ snapViewVisible = _this$_state.snapViewVisible,
146
+ zoomValue = _this$_state.zoomValue,
147
+ loaded = _this$_state.loaded;
148
+ var snapView = _this._elements.snapView;
149
+ if (!_this._options.snapView) return;
150
+ if (snapViewVisible || zoomValue <= 100 || !loaded) return;
151
+ clearTimeout(_this._frames.snapViewTimeout);
152
+ _this._state.snapViewVisible = true;
153
+ (0, _util.css)(snapView, {
154
+ opacity: 1,
155
+ pointerEvents: 'inherit'
156
+ });
157
+ if (!noTimeout) {
158
+ _this._frames.snapViewTimeout = setTimeout(_this.hideSnapView, 1500);
159
+ }
160
+ });
161
+ _defineProperty(this, "hideSnapView", function () {
162
+ var snapView = _this._elements.snapView;
163
+ (0, _util.css)(snapView, {
164
+ opacity: 0,
165
+ pointerEvents: 'none'
166
+ });
167
+ _this._state.snapViewVisible = false;
168
+ });
169
+ _defineProperty(this, "refresh", function () {
170
+ var animate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
171
+ _this._calculateDimensions();
172
+ _this.resetZoom(animate);
173
+ });
174
+ var _this$_findContainerA = this._findContainerAndImageSrc(element, options),
175
+ container = _this$_findContainerA.container,
176
+ domElement = _this$_findContainerA.domElement,
177
+ imageSrc = _this$_findContainerA.imageSrc,
178
+ hiResImageSrc = _this$_findContainerA.hiResImageSrc;
179
+
180
+ // containers for elements
181
+ this._elements = {
182
+ container: container,
183
+ domElement: domElement
184
+ };
185
+ this._options = _objectSpread(_objectSpread({}, ImageViewer.defaults), options);
186
+
187
+ // container for all events
188
+ this._events = {};
189
+ this._listeners = this._options.listeners || {};
190
+
191
+ // container for all timeout and frames
192
+ this._frames = {};
193
+
194
+ // container for all sliders
195
+ this._sliders = {};
196
+
197
+ // maintain current state
198
+ this._state = {
199
+ zoomValue: this._options.zoomValue
200
+ };
201
+ this._images = {
202
+ imageSrc: imageSrc,
203
+ hiResImageSrc: hiResImageSrc
204
+ };
205
+ this._init();
206
+ if (imageSrc) {
207
+ this._loadImages();
208
+ }
209
+
210
+ // store reference of imageViewer in domElement
211
+ domElement._imageViewer = this;
212
+ }
213
+ return _createClass(ImageViewer, [{
214
+ key: "zoomInButton",
215
+ get: function get() {
216
+ return this._options.hasZoomButtons ? '<div class="iv-button-zoom--in" role="button"></div>' : '';
217
+ }
218
+ }, {
219
+ key: "zoomOutButton",
220
+ get: function get() {
221
+ return this._options.hasZoomButtons ? '<div class="iv-button-zoom--out" role="button"></div>' : '';
222
+ }
223
+ }, {
224
+ key: "imageViewHtml",
225
+ get: function get() {
226
+ 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 ");
227
+ }
228
+ }, {
229
+ key: "_findContainerAndImageSrc",
230
+ value: function _findContainerAndImageSrc(element) {
231
+ var domElement = element;
232
+ var imageSrc, hiResImageSrc;
233
+ if (typeof element === 'string') {
234
+ domElement = document.querySelector(element);
235
+ }
236
+
237
+ // throw error if imageViewer is already assigned
238
+ if (domElement._imageViewer) {
239
+ throw new Error('An image viewer is already being initiated on the element.');
240
+ }
241
+ var container = element;
242
+ if (domElement.tagName === 'IMG') {
243
+ imageSrc = domElement.src;
244
+ hiResImageSrc = domElement.getAttribute('high-res-src') || domElement.getAttribute('data-high-res-src');
245
+
246
+ // wrap the image with iv-container div
247
+ container = (0, _util.wrap)(domElement, {
248
+ className: 'iv-container iv-image-mode',
249
+ style: {
250
+ display: 'inline-block',
251
+ overflow: 'hidden'
252
+ }
253
+ });
254
+
255
+ // hide the image and add iv-original-img class
256
+ (0, _util.css)(domElement, {
257
+ opacity: 0,
258
+ position: 'relative',
259
+ zIndex: -1
260
+ });
261
+ } else {
262
+ imageSrc = domElement.getAttribute('src') || domElement.getAttribute('data-src');
263
+ hiResImageSrc = domElement.getAttribute('high-res-src') || domElement.getAttribute('data-high-res-src');
264
+ }
265
+ return {
266
+ container: container,
267
+ domElement: domElement,
268
+ imageSrc: imageSrc,
269
+ hiResImageSrc: hiResImageSrc
270
+ };
271
+ }
272
+ }, {
273
+ key: "_init",
274
+ value: function _init() {
275
+ // initialize the dom elements
276
+ this._initDom();
277
+
278
+ // initialize slider
279
+ this._initImageSlider();
280
+ this._initSnapSlider();
281
+ this._initZoomSlider();
282
+
283
+ // enable pinch and zoom feature for touch screens
284
+ this._pinchAndZoom();
285
+
286
+ // enable scroll zoom interaction
287
+ this._scrollZoom();
288
+
289
+ // enable double tap to zoom interaction
290
+ this._doubleTapToZoom();
291
+
292
+ // initialize events
293
+ this._initEvents();
294
+ }
295
+ }, {
296
+ key: "_initDom",
297
+ value: function _initDom() {
298
+ var container = this._elements.container;
299
+
300
+ // add image-viewer layout elements
301
+ (0, _util.createElement)({
302
+ tagName: 'div',
303
+ className: 'iv-wrap',
304
+ html: this.imageViewHtml,
305
+ parent: container
306
+ });
307
+
308
+ // add container class on the container
309
+ (0, _util.addClass)(container, 'iv-container');
310
+
311
+ // if the element is static position, position it relatively
312
+ if ((0, _util.css)(container, 'position') === 'static') {
313
+ (0, _util.css)(container, {
314
+ position: 'relative'
315
+ });
316
+ }
317
+
318
+ // save references for later use
319
+ this._elements = _objectSpread(_objectSpread({}, this._elements), {}, {
320
+ snapView: container.querySelector('.iv-snap-view'),
321
+ snapImageWrap: container.querySelector('.iv-snap-image-wrap'),
322
+ imageWrap: container.querySelector('.iv-image-wrap'),
323
+ snapHandle: container.querySelector('.iv-snap-handle'),
324
+ zoomHandle: container.querySelector('.iv-zoom-handle'),
325
+ zoomIn: container.querySelector('.iv-button-zoom--in'),
326
+ zoomOut: container.querySelector('.iv-button-zoom--out')
327
+ });
328
+ if (this._listeners.onInit) {
329
+ this._listeners.onInit(this._callbackData);
330
+ }
331
+ }
332
+ }, {
333
+ key: "_initImageSlider",
334
+ value: function _initImageSlider() {
335
+ var _this2 = this;
336
+ var _elements = this._elements;
337
+ var imageWrap = _elements.imageWrap;
338
+ var positions, currentPos;
339
+
340
+ /* Add slide interaction to image */
341
+ var imageSlider = new _Slider["default"](imageWrap, {
342
+ isSliderEnabled: function isSliderEnabled() {
343
+ var _this2$_state = _this2._state,
344
+ loaded = _this2$_state.loaded,
345
+ zooming = _this2$_state.zooming,
346
+ zoomValue = _this2$_state.zoomValue;
347
+ return loaded && !zooming && zoomValue > 100;
348
+ },
349
+ onStart: function onStart(e, position) {
350
+ var snapSlider = _this2._sliders.snapSlider;
351
+
352
+ // clear all animation frame and interval
353
+ _this2._clearFrames();
354
+ snapSlider.onStart();
355
+
356
+ // reset positions
357
+ positions = [position, position];
358
+ currentPos = undefined;
359
+ _this2._frames.slideMomentumCheck = setInterval(function () {
360
+ if (!currentPos) return;
361
+ positions.shift();
362
+ positions.push({
363
+ x: currentPos.mx,
364
+ y: currentPos.my
365
+ });
366
+ }, 50);
367
+ },
368
+ onMove: function onMove(e, position) {
369
+ var snapImageDim = _this2._state.snapImageDim;
370
+ var snapSlider = _this2._sliders.snapSlider;
371
+ var imageCurrentDim = _this2._getImageCurrentDim();
372
+ currentPos = position;
373
+ snapSlider.onMove(e, {
374
+ dx: -position.dx * snapImageDim.w / imageCurrentDim.w,
375
+ dy: -position.dy * snapImageDim.h / imageCurrentDim.h
376
+ });
377
+ },
378
+ onEnd: function onEnd() {
379
+ var snapImageDim = _this2._state.snapImageDim;
380
+ var snapSlider = _this2._sliders.snapSlider;
381
+ var imageCurrentDim = _this2._getImageCurrentDim();
382
+
383
+ // clear all animation frame and interval
384
+ _this2._clearFrames();
385
+ var step, positionX, positionY;
386
+ var xDiff = positions[1].x - positions[0].x;
387
+ var yDiff = positions[1].y - positions[0].y;
388
+ var _momentum = function momentum() {
389
+ if (step <= 60) {
390
+ _this2._frames.sliderMomentumFrame = requestAnimationFrame(_momentum);
391
+ }
392
+ positionX += (0, _util.easeOutQuart)(step, xDiff / 3, -xDiff / 3, 60);
393
+ positionY += (0, _util.easeOutQuart)(step, yDiff / 3, -yDiff / 3, 60);
394
+ snapSlider.onMove(null, {
395
+ dx: -(positionX * snapImageDim.w / imageCurrentDim.w),
396
+ dy: -(positionY * snapImageDim.h / imageCurrentDim.h)
397
+ });
398
+ step++;
399
+ };
400
+ if (Math.abs(xDiff) > 30 || Math.abs(yDiff) > 30) {
401
+ step = 1;
402
+ positionX = currentPos.dx;
403
+ positionY = currentPos.dy;
404
+ _momentum();
405
+ }
406
+ }
407
+ });
408
+ imageSlider.init();
409
+ this._sliders.imageSlider = imageSlider;
410
+ }
411
+ }, {
412
+ key: "_initSnapSlider",
413
+ value: function _initSnapSlider() {
414
+ var _this3 = this;
415
+ var snapHandle = this._elements.snapHandle;
416
+ var startHandleTop, startHandleLeft;
417
+ var snapSlider = new _Slider["default"](snapHandle, {
418
+ isSliderEnabled: function isSliderEnabled() {
419
+ return _this3._state.loaded;
420
+ },
421
+ onStart: function onStart() {
422
+ var _this3$_frames = _this3._frames,
423
+ slideMomentumCheck = _this3$_frames.slideMomentumCheck,
424
+ sliderMomentumFrame = _this3$_frames.sliderMomentumFrame;
425
+ startHandleTop = parseFloat((0, _util.css)(snapHandle, 'top'));
426
+ startHandleLeft = parseFloat((0, _util.css)(snapHandle, 'left'));
427
+
428
+ // stop momentum on image
429
+ clearInterval(slideMomentumCheck);
430
+ cancelAnimationFrame(sliderMomentumFrame);
431
+ },
432
+ onMove: function onMove(e, position) {
433
+ var _this3$_state = _this3._state,
434
+ snapHandleDim = _this3$_state.snapHandleDim,
435
+ snapImageDim = _this3$_state.snapImageDim;
436
+ var image = _this3._elements.image;
437
+ var imageCurrentDim = _this3._getImageCurrentDim();
438
+
439
+ // find handle left and top and make sure they lay between the snap image
440
+ var maxLeft = Math.max(snapImageDim.w - snapHandleDim.w, startHandleLeft);
441
+ var maxTop = Math.max(snapImageDim.h - snapHandleDim.h, startHandleTop);
442
+ var minLeft = Math.min(0, startHandleLeft);
443
+ var minTop = Math.min(0, startHandleTop);
444
+ var left = (0, _util.clamp)(startHandleLeft + position.dx, minLeft, maxLeft);
445
+ var top = (0, _util.clamp)(startHandleTop + position.dy, minTop, maxTop);
446
+ var imgLeft = -left * imageCurrentDim.w / snapImageDim.w;
447
+ var imgTop = -top * imageCurrentDim.h / snapImageDim.h;
448
+ (0, _util.css)(snapHandle, {
449
+ left: "".concat(left, "px"),
450
+ top: "".concat(top, "px")
451
+ });
452
+ (0, _util.css)(image, {
453
+ left: "".concat(imgLeft, "px"),
454
+ top: "".concat(imgTop, "px")
455
+ });
456
+ }
457
+ });
458
+ snapSlider.init();
459
+ this._sliders.snapSlider = snapSlider;
460
+ }
461
+ }, {
462
+ key: "_initZoomSlider",
463
+ value: function _initZoomSlider() {
464
+ var _this4 = this;
465
+ var _this$_elements = this._elements,
466
+ snapView = _this$_elements.snapView,
467
+ zoomHandle = _this$_elements.zoomHandle;
468
+
469
+ // zoom in zoom out using zoom handle
470
+ var sliderElm = snapView.querySelector('.iv-zoom-slider');
471
+ var leftOffset, handleWidth;
472
+
473
+ // on zoom slider we have to follow the mouse and set the handle to its position.
474
+ var zoomSlider = new _Slider["default"](sliderElm, {
475
+ isSliderEnabled: function isSliderEnabled() {
476
+ return _this4._state.loaded;
477
+ },
478
+ onStart: function onStart(eStart) {
479
+ var slider = _this4._sliders.zoomSlider;
480
+ leftOffset = sliderElm.getBoundingClientRect().left;
481
+ handleWidth = parseInt((0, _util.css)(zoomHandle, 'width'), 10);
482
+
483
+ // move the handle to current mouse position
484
+ slider.onMove(eStart);
485
+ },
486
+ onMove: function onMove(e) {
487
+ var maxZoom = _this4._options.maxZoom;
488
+ var zoomSliderLength = _this4._state.zoomSliderLength;
489
+ var clientX = e.clientX !== undefined ? e.clientX : e.touches[0].clientX;
490
+ var newLeft = (0, _util.clamp)(clientX - leftOffset - handleWidth / 2, 0, zoomSliderLength);
491
+ var zoomValue = 100 + (maxZoom - 100) * newLeft / zoomSliderLength;
492
+ _this4.zoom(zoomValue);
493
+ }
494
+ });
495
+ zoomSlider.init();
496
+ this._sliders.zoomSlider = zoomSlider;
497
+ }
498
+ }, {
499
+ key: "_initEvents",
500
+ value: function _initEvents() {
501
+ this._snapViewEvents();
502
+
503
+ // handle window resize
504
+ if (this._options.refreshOnResize) {
505
+ this._events.onWindowResize = (0, _util.assignEvent)(window, 'resize', this.refresh);
506
+ }
507
+ this._events.onDragStart = (0, _util.assignEvent)(this._elements.container, 'dragstart', _util.preventDefault);
508
+ }
509
+ }, {
510
+ key: "_snapViewEvents",
511
+ value: function _snapViewEvents() {
512
+ var _this5 = this;
513
+ var _this$_elements2 = this._elements,
514
+ imageWrap = _this$_elements2.imageWrap,
515
+ snapView = _this$_elements2.snapView;
516
+
517
+ // show snapView on mouse move
518
+ this._events.snapViewOnMouseMove = (0, _util.assignEvent)(imageWrap, ['touchmove', 'mousemove'], function () {
519
+ _this5.showSnapView();
520
+ });
521
+
522
+ // keep showing snapView if on hover over it without any timeout
523
+ this._events.mouseEnterSnapView = (0, _util.assignEvent)(snapView, ['mouseenter', 'touchstart'], function () {
524
+ _this5._state.snapViewVisible = false;
525
+ _this5.showSnapView(true);
526
+ });
527
+
528
+ // on mouse leave set timeout to hide snapView
529
+ this._events.mouseLeaveSnapView = (0, _util.assignEvent)(snapView, ['mouseleave', 'touchend'], function () {
530
+ _this5._state.snapViewVisible = false;
531
+ _this5.showSnapView();
532
+ });
533
+ if (!this._options.hasZoomButtons) {
534
+ return;
535
+ }
536
+ var _this$_elements3 = this._elements,
537
+ zoomOut = _this$_elements3.zoomOut,
538
+ zoomIn = _this$_elements3.zoomIn;
539
+ this._events.zoomInClick = (0, _util.assignEvent)(zoomIn, ['click'], function () {
540
+ _this5.zoom(_this5._state.zoomValue + _this5._options.zoomStep || 50);
541
+ });
542
+ this._events.zoomOutClick = (0, _util.assignEvent)(zoomOut, ['click'], function () {
543
+ _this5.zoom(_this5._state.zoomValue - _this5._options.zoomStep || 50);
544
+ });
545
+ }
546
+ }, {
547
+ key: "_pinchAndZoom",
548
+ value: function _pinchAndZoom() {
549
+ var _this6 = this;
550
+ var _this$_elements4 = this._elements,
551
+ imageWrap = _this$_elements4.imageWrap,
552
+ container = _this$_elements4.container;
553
+
554
+ // apply pinch and zoom feature
555
+ var onPinchStart = function onPinchStart(eStart) {
556
+ var _this6$_state = _this6._state,
557
+ loaded = _this6$_state.loaded,
558
+ startZoomValue = _this6$_state.zoomValue;
559
+ var events = _this6._events;
560
+ if (!loaded) return;
561
+ var touch0 = eStart.touches[0];
562
+ var touch1 = eStart.touches[1];
563
+ if (!(touch0 && touch1)) {
564
+ return;
565
+ }
566
+ _this6._state.zooming = true;
567
+ var contOffset = container.getBoundingClientRect();
568
+
569
+ // find distance between two touch points
570
+ var startDist = (0, _util.getTouchPointsDistance)(eStart.touches);
571
+
572
+ // find the center for the zoom
573
+ var center = {
574
+ x: (touch1.clientX + touch0.clientX) / 2 - contOffset.left,
575
+ y: (touch1.clientY + touch0.clientY) / 2 - contOffset.top
576
+ };
577
+ var moveListener = function moveListener(eMove) {
578
+ // eMove.preventDefault();
579
+
580
+ var newDist = (0, _util.getTouchPointsDistance)(eMove.touches);
581
+ var zoomValue = startZoomValue + (newDist - startDist) / 2;
582
+ _this6.zoom(zoomValue, center);
583
+ };
584
+ var endListener = function endListener(eEnd) {
585
+ // unbind events
586
+ events.pinchMove();
587
+ events.pinchEnd();
588
+ _this6._state.zooming = false;
589
+ // properly resume move event if one finger remains
590
+ if (eEnd.touches.length === 1) {
591
+ _this6._sliders.imageSlider.startHandler(eEnd);
592
+ }
593
+ };
594
+
595
+ // remove events if already assigned
596
+ if (events.pinchMove) events.pinchMove();
597
+ if (events.pinchEnd) events.pinchEnd();
598
+
599
+ // assign events
600
+ events.pinchMove = (0, _util.assignEvent)(document, 'touchmove', moveListener);
601
+ events.pinchEnd = (0, _util.assignEvent)(document, 'touchend', endListener);
602
+ };
603
+ this._events.pinchStart = (0, _util.assignEvent)(imageWrap, 'touchstart', onPinchStart);
604
+ }
605
+ }, {
606
+ key: "_scrollZoom",
607
+ value: function _scrollZoom() {
608
+ var _this7 = this;
609
+ /* Add zoom interaction in mouse wheel */
610
+ var _options = this._options;
611
+ var _this$_elements5 = this._elements,
612
+ container = _this$_elements5.container,
613
+ imageWrap = _this$_elements5.imageWrap;
614
+ var changedDelta = 0;
615
+ var onMouseWheel = function onMouseWheel(e) {
616
+ var _this7$_state = _this7._state,
617
+ loaded = _this7$_state.loaded,
618
+ zoomValue = _this7$_state.zoomValue;
619
+ if (!_options.zoomOnMouseWheel || !loaded) return;
620
+
621
+ // clear all animation frame and interval
622
+ _this7._clearFrames();
623
+
624
+ // cross-browser wheel delta
625
+ var delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail || -e.deltaY));
626
+ var newZoomValue = zoomValue * (100 + delta * _util.ZOOM_CONSTANT) / 100;
627
+ if (!(newZoomValue >= 100 && newZoomValue <= _options.maxZoom)) {
628
+ changedDelta += Math.abs(delta);
629
+ } else {
630
+ changedDelta = 0;
631
+ }
632
+ e.preventDefault();
633
+ if (changedDelta > _util.MOUSE_WHEEL_COUNT) return;
634
+ var contOffset = container.getBoundingClientRect();
635
+ var x = e.clientX - contOffset.left;
636
+ var y = e.clientY - contOffset.top;
637
+ _this7.zoom(newZoomValue, {
638
+ x: x,
639
+ y: y
640
+ });
641
+
642
+ // show the snap viewer
643
+ _this7.showSnapView();
644
+ };
645
+ this._events.scrollZoom = (0, _util.assignEvent)(imageWrap, 'wheel', onMouseWheel);
646
+ }
647
+ }, {
648
+ key: "_doubleTapToZoom",
649
+ value: function _doubleTapToZoom() {
650
+ var _this8 = this;
651
+ var imageWrap = this._elements.imageWrap;
652
+ // handle double tap for zoom in and zoom out
653
+
654
+ var touchTime = 0;
655
+ var point;
656
+ var onDoubleTap = function onDoubleTap(e) {
657
+ if (touchTime === 0) {
658
+ touchTime = Date.now();
659
+ point = {
660
+ x: e.clientX,
661
+ y: e.clientY
662
+ };
663
+ } else if (Date.now() - touchTime < 500 && Math.abs(e.clientX - point.x) < 50 && Math.abs(e.clientY - point.y) < 50) {
664
+ if (_this8._state.zoomValue === _this8._options.zoomValue) {
665
+ _this8.zoom(200);
666
+ } else {
667
+ _this8.resetZoom();
668
+ }
669
+ touchTime = 0;
670
+ } else {
671
+ touchTime = 0;
672
+ }
673
+ };
674
+ this._events.doubleTapToZoom = (0, _util.assignEvent)(imageWrap, 'click', onDoubleTap);
675
+ }
676
+ }, {
677
+ key: "_getImageCurrentDim",
678
+ value: function _getImageCurrentDim() {
679
+ var _this$_state2 = this._state,
680
+ zoomValue = _this$_state2.zoomValue,
681
+ imageDim = _this$_state2.imageDim;
682
+ return {
683
+ w: imageDim.w * (zoomValue / 100),
684
+ h: imageDim.h * (zoomValue / 100)
685
+ };
686
+ }
687
+ }, {
688
+ key: "_loadImages",
689
+ value: function _loadImages() {
690
+ var _this9 = this;
691
+ var _images = this._images,
692
+ _elements = this._elements;
693
+ var imageSrc = _images.imageSrc,
694
+ hiResImageSrc = _images.hiResImageSrc;
695
+ var container = _elements.container,
696
+ snapImageWrap = _elements.snapImageWrap,
697
+ imageWrap = _elements.imageWrap;
698
+ var ivLoader = container.querySelector('.iv-loader');
699
+
700
+ // remove old images
701
+ (0, _util.remove)(container.querySelectorAll('.iv-snap-image, .iv-image'));
702
+
703
+ // add snapView image
704
+ var snapImage = (0, _util.createElement)({
705
+ tagName: 'img',
706
+ className: 'iv-snap-image',
707
+ src: imageSrc,
708
+ insertBefore: snapImageWrap.firstChild,
709
+ parent: snapImageWrap
710
+ });
711
+
712
+ // add image
713
+ var image = (0, _util.createElement)({
714
+ tagName: 'img',
715
+ className: 'iv-image iv-small-image',
716
+ src: imageSrc,
717
+ parent: imageWrap
718
+ });
719
+ this._state.loaded = false;
720
+
721
+ // store image reference in _elements
722
+ this._elements.image = image;
723
+ this._elements.snapImage = snapImage;
724
+ (0, _util.css)(ivLoader, {
725
+ display: 'block'
726
+ });
727
+
728
+ // keep visibility hidden until image is loaded
729
+ (0, _util.css)(image, {
730
+ visibility: 'hidden'
731
+ });
732
+
733
+ // hide snap view if open
734
+ this.hideSnapView();
735
+ var onImageLoad = function onImageLoad() {
736
+ // hide the iv loader
737
+ (0, _util.css)(ivLoader, {
738
+ display: 'none'
739
+ });
740
+
741
+ // show the image
742
+ (0, _util.css)(image, {
743
+ visibility: 'visible'
744
+ });
745
+
746
+ // load high resolution image if provided
747
+ if (hiResImageSrc) {
748
+ _this9._loadHighResImage(hiResImageSrc);
749
+ }
750
+
751
+ // set loaded flag to true
752
+ _this9._state.loaded = true;
753
+
754
+ // calculate the dimension
755
+ _this9._calculateDimensions();
756
+
757
+ // dispatch image load event
758
+ if (_this9._listeners.onImageLoaded) {
759
+ _this9._listeners.onImageLoaded(_this9._callbackData);
760
+ }
761
+
762
+ // reset the zoom
763
+ _this9.resetZoom();
764
+ };
765
+ if ((0, _util.imageLoaded)(image)) {
766
+ onImageLoad();
767
+ } else {
768
+ if (typeof this._events.imageLoad === 'function') {
769
+ this._events.imageLoad();
770
+ }
771
+ this._events.imageLoad = (0, _util.assignEvent)(image, 'load', onImageLoad);
772
+ }
773
+ }
774
+ }, {
775
+ key: "_loadHighResImage",
776
+ value: function _loadHighResImage(hiResImageSrc) {
777
+ var _this0 = this;
778
+ var _this$_elements6 = this._elements,
779
+ imageWrap = _this$_elements6.imageWrap,
780
+ container = _this$_elements6.container;
781
+ var lowResImg = this._elements.image;
782
+ var hiResImage = (0, _util.createElement)({
783
+ tagName: 'img',
784
+ className: 'iv-image iv-large-image',
785
+ src: hiResImageSrc,
786
+ parent: imageWrap,
787
+ style: lowResImg.style.cssText
788
+ });
789
+
790
+ // add all the style attributes from lowResImg to highResImg
791
+ hiResImage.style.cssText = lowResImg.style.cssText;
792
+ this._elements.image = container.querySelectorAll('.iv-image');
793
+ var onHighResImageLoad = function onHighResImageLoad() {
794
+ // remove the low size image and set this image as default image
795
+ (0, _util.remove)(lowResImg);
796
+ _this0._elements.image = hiResImage;
797
+ // this._calculateDimensions();
798
+ };
799
+ if ((0, _util.imageLoaded)(hiResImage)) {
800
+ onHighResImageLoad();
801
+ } else {
802
+ if (typeof this._events.hiResImageLoad === 'function') {
803
+ this._events.hiResImageLoad();
804
+ }
805
+ this._events.hiResImageLoad = (0, _util.assignEvent)(hiResImage, 'load', onHighResImageLoad);
806
+ }
807
+ }
808
+ }, {
809
+ key: "_calculateDimensions",
810
+ value: function _calculateDimensions() {
811
+ var _this$_elements7 = this._elements,
812
+ image = _this$_elements7.image,
813
+ container = _this$_elements7.container,
814
+ snapView = _this$_elements7.snapView,
815
+ snapImage = _this$_elements7.snapImage,
816
+ zoomHandle = _this$_elements7.zoomHandle;
817
+
818
+ // calculate content width of image and snap image
819
+ var imageWidth = parseInt((0, _util.css)(image, 'width'), 10);
820
+ var imageHeight = parseInt((0, _util.css)(image, 'height'), 10);
821
+ var contWidth = parseInt((0, _util.css)(container, 'width'), 10);
822
+ var contHeight = parseInt((0, _util.css)(container, 'height'), 10);
823
+ var snapViewWidth = snapView.clientWidth;
824
+ var snapViewHeight = snapView.clientHeight;
825
+
826
+ // set the container dimension
827
+ this._state.containerDim = {
828
+ w: contWidth,
829
+ h: contHeight
830
+ };
831
+
832
+ // set the image dimension
833
+ var ratio = imageWidth / imageHeight;
834
+ var imgWidth = imageWidth > imageHeight && contHeight >= contWidth || ratio * contHeight > contWidth ? contWidth : ratio * contHeight;
835
+ var imgHeight = imgWidth / ratio;
836
+ this._state.imageDim = {
837
+ w: imgWidth,
838
+ h: imgHeight
839
+ };
840
+
841
+ // reset image position and zoom
842
+ (0, _util.css)(image, {
843
+ width: "".concat(imgWidth, "px"),
844
+ height: "".concat(imgHeight, "px"),
845
+ left: "".concat((contWidth - imgWidth) / 2, "px"),
846
+ top: "".concat((contHeight - imgHeight) / 2, "px"),
847
+ maxWidth: 'none',
848
+ maxHeight: 'none'
849
+ });
850
+
851
+ // set the snap Image dimension
852
+ var snapWidth = imgWidth > imgHeight ? snapViewWidth : imgWidth * snapViewHeight / imgHeight;
853
+ var snapHeight = imgHeight > imgWidth ? snapViewHeight : imgHeight * snapViewWidth / imgWidth;
854
+ this._state.snapImageDim = {
855
+ w: snapWidth,
856
+ h: snapHeight
857
+ };
858
+ (0, _util.css)(snapImage, {
859
+ width: "".concat(snapWidth, "px"),
860
+ height: "".concat(snapHeight, "px")
861
+ });
862
+ var zoomSlider = snapView.querySelector('.iv-zoom-slider').clientWidth;
863
+ // calculate zoom slider area
864
+ this._state.zoomSliderLength = zoomSlider - zoomHandle.offsetWidth;
865
+ }
866
+ }, {
867
+ key: "resetZoom",
868
+ value: function resetZoom() {
869
+ var animate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
870
+ var zoomValue = this._options.zoomValue;
871
+ if (!animate) {
872
+ this._state.zoomValue = zoomValue;
873
+ }
874
+ this.zoom(zoomValue);
875
+ }
876
+ }, {
877
+ key: "load",
878
+ value: function load(imageSrc, hiResImageSrc) {
879
+ this._images = {
880
+ imageSrc: imageSrc,
881
+ hiResImageSrc: hiResImageSrc
882
+ };
883
+ this._loadImages();
884
+ }
885
+ }, {
886
+ key: "destroy",
887
+ value: function destroy() {
888
+ var _this$_elements8 = this._elements,
889
+ container = _this$_elements8.container,
890
+ domElement = _this$_elements8.domElement;
891
+ // destroy all the sliders
892
+ Object.entries(this._sliders).forEach(function (_ref) {
893
+ var _ref2 = _slicedToArray(_ref, 2),
894
+ slider = _ref2[1];
895
+ slider.destroy();
896
+ });
897
+
898
+ // unbind all events
899
+ Object.entries(this._events).forEach(function (_ref3) {
900
+ var _ref4 = _slicedToArray(_ref3, 2),
901
+ unbindEvent = _ref4[1];
902
+ unbindEvent();
903
+ });
904
+
905
+ // clear all the frames
906
+ this._clearFrames();
907
+
908
+ // remove html from the container
909
+ (0, _util.remove)(container.querySelector('.iv-wrap'));
910
+
911
+ // remove iv-container class from container
912
+ (0, _util.removeClass)(container, 'iv-container');
913
+
914
+ // remove added style from container
915
+ (0, _util.removeCss)(document.querySelector('html'), 'relative');
916
+
917
+ // if container has original image, unwrap the image and remove the class
918
+ // which will happen when domElement is not the container
919
+ if (domElement !== container) {
920
+ (0, _util.unwrap)(domElement);
921
+ }
922
+
923
+ // remove imageViewer reference from dom element
924
+ domElement._imageViewer = null;
925
+ if (this._listeners.onDestroy) {
926
+ this._listeners.onDestroy();
927
+ }
928
+ }
929
+
930
+ /**
931
+ * Data will be passed to the callback registered with each new instance
932
+ */
933
+ }, {
934
+ key: "_callbackData",
935
+ get: function get() {
936
+ return {
937
+ container: this._elements.container,
938
+ snapView: this._elements.snapView,
939
+ zoomValue: this._state.zoomValue,
940
+ reachedMin: Math.abs(this._state.zoomValue - 100) < 1,
941
+ reachedMax: Math.abs(this._state.zoomValue - this._options.maxZoom) < 1,
942
+ instance: this
943
+ };
944
+ }
945
+ }]);
946
+ }();
947
+ ImageViewer.defaults = {
948
+ zoomValue: 100,
949
+ snapView: true,
950
+ maxZoom: 500,
951
+ refreshOnResize: true,
952
+ zoomOnMouseWheel: true,
953
+ hasZoomButtons: false,
954
+ zoomStep: 50,
955
+ listeners: {
956
+ onInit: null,
957
+ onDestroy: null,
958
+ onImageLoaded: null,
959
+ onZoomChange: null
960
+ }
961
+ };
962
+ var _default = exports["default"] = ImageViewer;