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})();