• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1(function() {
2  {%- include scripts/lib/swiper.js -%}
3  var SOURCES = window.TEXT_VARIABLES.sources;
4  window.Lazyload.js(SOURCES.jquery, function() {
5    var template =
6      '<div class="swiper gallery__swiper">' +
7        '<div class="swiper__wrapper">' +
8        '</div>' +
9        '<div class="swiper__button swiper__button--prev fas fa-chevron-left"></div>' +
10        '<div class="swiper__button swiper__button--next fas fa-chevron-right"></div>' +
11      '</div>';
12    function setState($item, zoom, translate) {
13      $item.css('transform', 'scale(' + zoom + ') translate(' + translate.x +  'px,' + translate.y + 'px)');
14    }
15    function Gallery(root, items) {
16      this.$root = $(root);
17      this.$swiper = null;
18      this.$swiperWrapper = null;
19      this.$activeItem = null;
20      this.$items = [];
21      this.contentWidth = 0;
22      this.contentHeight = 0;
23      this.swiper = null;
24      this.items = items;
25      this.disabled = false;
26      this.curIndex = 0;
27      this.touchCenter = null;
28      this.lastTouchCenter = null;
29      this.zoomRect = null;
30      this.lastZoomRect = null;
31      this.lastTranslate = null;
32      this.translate = null;
33      this.lastZoom = 1;
34      this.preZoom = 1;
35      this.zoom = 1;
36    }
37    Gallery.prototype.init = function() {
38      var i, item, items = this.items, size, self = this, touchstartFingerCount = 0;
39      this.$root.append(template);
40      this.$swiper = this.$root.find('.gallery__swiper');
41      this.$swiperWrapper = this.$root.find('.swiper__wrapper');
42      this.contentWidth = this.$swiperWrapper && this.$swiperWrapper.width();
43      this.contentHeight = this.$swiperWrapper && this.$swiperWrapper.height();
44      for (i = 0; i < items.length; i++) {
45        item = items[i];
46        size = this._calculateImageSize(item.w, item.h);
47        this.$items.push($(
48          '<div class="swiper__slide">' +
49            '<div class="gallery-item">' +
50              '<div class="gallery-item__content">' +
51                '<img src="' + item.src + '" style="width:' + size.w + 'px;height:' + size.h +  'px"/>' +
52              '</div>' +
53            '</div>' +
54          '</div>'
55        ));
56      }
57      this.$swiperWrapper && this.$swiperWrapper.append(this.$items);
58      this.swiper = this.$swiper && this.$swiper.swiper({
59        onChangeEnd: function() {
60          self._handleChangeEnd.apply(self, Array.prototype.slice.call(arguments));
61        }
62      });
63      $(window).on('resize', function() {
64        if (self.disabled) { return; }
65        self._resizeImageSize();
66      });
67      // Char Code: 37  ⬅, 39  ➡
68      $(window).on('keyup', function(e) {
69        if (window.isFormElement(e.target || e.srcElement) || self.disabled) { return; }
70        if (e.which === 37) {
71          self.swiper && self.swiper.previous();
72        } else if (e.which === 39) {
73          self.swiper && self.swiper.next();
74        }
75      });
76      function getRect(touch0, touch1) {
77        return {
78          o: {
79            x: (touch0.pageX + touch1.pageX) / 2,
80            y: (touch0.pageY + touch1.pageY) / 2
81          },
82          w: Math.abs(touch0.pageX - touch1.pageX),
83          h: Math.abs(touch0.pageY - touch1.pageY)
84        };
85      }
86      function getTouches(e) {
87        return e.touches || e;
88      }
89      function getTouchesCount(e) {
90        if (e.touches) {
91          return e.touches.length;
92        } else {
93          return 1;
94        }
95      }
96      this.$swiperWrapper.on('touchstart', function(e) {
97        var touch0, touch1, rect;
98        touchstartFingerCount = getTouchesCount(e);
99        if (touchstartFingerCount > 1) {
100          touch0 = e.touches[0];
101          touch1 = e.touches[1];
102          rect = getRect(touch0, touch1);
103          self.lastZoomRect = { w: rect.w, h: rect.h };
104          self.lastTouchCenter = rect.o;
105        } else {
106          var touch = getTouches(e)[0];
107          self.lastTouchCenter = { x: touch.pageX, y: touch.pageY };
108        }
109      });
110      this.$swiperWrapper.on('touchmove', function(e) {
111        if (touchstartFingerCount === getTouchesCount(e)) {
112          if (touchstartFingerCount > 1) {
113            var touch0 = e.touches[0];
114            var touch1 = e.touches[1];
115            var rect = getRect(touch0, touch1);
116            self.zoomRect = { w: rect.w, h: rect.h };
117            self.touchCenter = rect.o;
118            self._zoom(); self._translate();
119            setState(self.$activeItem, self.zoom, self.translate);
120          } else {
121            var touch = getTouches(e)[0];
122            self.touchCenter = { x: touch.pageX, y: touch.pageY };
123            self._translate();
124            setState(self.$activeItem, self.zoom, self.translate);
125          }
126        }
127      });
128      this.$swiperWrapper.on('touchend', function(e) {
129        self.lastZoom = self.zoom;
130        self.lastTranslate = self.translate;
131        touchstartFingerCount = 0;
132      });
133      this.$root.on('touchmove', function(e) {
134        if (self.disabled) { return; }
135        e.preventDefault();
136      });
137    };
138
139    Gallery.prototype._translate = function() {
140      this.translate = this.touchCenter && this.lastTouchCenter && this.lastTranslate ? {
141        x: (this.touchCenter.x - this.lastTouchCenter.x) / this.zoom + this.lastTranslate.x,
142        y: (this.touchCenter.y - this.lastTouchCenter.y) / this.zoom + this.lastTranslate.y
143      } : { x: 0, y: 0 };
144    }
145    Gallery.prototype._zoom = function() {
146      this.zoom = (this.zoomRect.w + this.zoomRect.h) / (this.lastZoomRect.w + this.lastZoomRect.h) * this.lastZoom;
147      this.zoom > 1 ? this.$activeItem.addClass('zoom') : this.$activeItem.removeClass('zoom');
148      this.preZoom = this.zoom;
149    }
150
151    Gallery.prototype._calculateImageSize = function(w, h) {
152      var scale = 1;
153      if (this.contentWidth > 0 && this.contentHeight > 0 && w > 0 && h > 0) {
154        scale = Math.min(
155          Math.min(w, this.contentWidth) / w,
156          Math.min(h, this.contentHeight) / h);
157      }
158      return { w: Math.floor(w * scale), h: Math.floor(h * scale) };
159    };
160
161    Gallery.prototype._resizeImageSize = function() {
162      var i, $item, $items = this.$items, item, size;
163      this.contentWidth = this.$swiperWrapper && this.$swiperWrapper.width();
164      this.contentHeight = this.$swiperWrapper && this.$swiperWrapper.height();
165      if ($items.length < 1) { return; }
166      for (i = 0; i < $items.length; i++) {
167        item = this.items[i], $item = $items[i];
168        size = this._calculateImageSize(item.w, item.h);
169        item.width = size.w; item.height = size.h;
170        $item && $item.find('img').css({ width: size.w, height: size.h });
171      }
172    };
173    Gallery.prototype._handleChangeEnd = function(index, $dom, preIndex, $preDom) {
174      this.curIndex = index;
175      this.lastZoomRect = null; this.lastZoomRect = null;
176      this.lastTranslate = this.translate = { x: 0, y:0 };
177      this.lastZoom = this.preZoom = this.zoom = 1;
178      this.$activeItem = $dom.find('.gallery-item__content');
179      setState($preDom.find('.gallery-item__content'), this.zoom, this.translate);
180    };
181
182    Gallery.prototype.refresh = function() {
183      this.swiper && this.swiper.refresh();
184      this._resizeImageSize();
185    };
186    Gallery.prototype.setOptions = function(options) {
187      this.disabled = options.disabled;
188      this.swiper && this.swiper.setOptions(options);
189    };
190    window.Gallery = Gallery;
191  });
192})();