UNPKG

drip-ui

Version:

Lightweight Mobile UI Components built on Vue

399 lines (302 loc) 10.4 kB
import objectAssign from 'object-assign'; var arrayFrom = function arrayFrom(nodeList) { return Array.prototype.slice.call(nodeList); }; var Swiper = /*#__PURE__*/ function () { function Swiper(options) { this._default = { container: '.drip-swiper', item: '.drip-swiper-item', direction: 'vertical', activeClass: 'active', threshold: 50, duration: 300, auto: false, loop: false, interval: 3000, height: 'auto', minMovingDistance: 0 }; this._options = objectAssign(this._default, options); this._options.height = this._options.height.replace('px', ''); this._start = {}; this._move = {}; this._end = {}; this._eventHandlers = {}; this._prev = this._current = this._goto = 0; this._width = this._height = this._distance = 0; this._offset = []; this.$box = this._options.container; this.$container = this._options.container.querySelector('.drip-swiper'); this.$items = this.$container.querySelectorAll(this._options.item); this.count = this.$items.length; this.realCount = this.$items.length; // real items length this._position = []; // used by go event this._firstItemIndex = 0; if (!this.count) { return; } this._init(); this._auto(); this._bind(); this._onResize(); return this; } var _proto = Swiper.prototype; _proto._auto = function _auto() { var me = this; me.stop(); if (me._options.auto) { me.timer = setTimeout(function () { me.next(); }, me._options.interval); } }; _proto.updateItemWidth = function updateItemWidth() { this._width = this.$box.offsetWidth || document.documentElement.offsetWidth; this._distance = this._options.direction === 'horizontal' ? this._width : this._height; }; _proto.stop = function stop() { this.timer && clearTimeout(this.timer); }; _proto._loop = function _loop() { return this._options.loop && this.realCount >= 3; }; _proto._onResize = function _onResize() { var me = this; this.resizeHandler = function () { setTimeout(function () { me.updateItemWidth(); me._setOffset(); me._setTransform(); }, 100); }; window.addEventListener('orientationchange', this.resizeHandler, false); }; _proto._init = function _init() { this._height = this._options.height === 'auto' ? 'auto' : this._options.height - 0; this.updateItemWidth(); this._initPosition(); this._activate(this._current); this._setOffset(); this._setTransform(); if (this._loop()) { this._loopRender(); } }; _proto._initPosition = function _initPosition() { for (var i = 0; i < this.realCount; i++) { this._position.push(i); } }; _proto._movePosition = function _movePosition(position) { var me = this; if (position > 0) { var firstIndex = me._position.splice(0, 1); me._position.push(firstIndex[0]); } else if (position < 0) { var lastIndex = me._position.pop(); me._position.unshift(lastIndex); } }; _proto._setOffset = function _setOffset() { var me = this; var index = me._position.indexOf(me._current); me._offset = []; arrayFrom(me.$items).forEach(function ($item, key) { me._offset.push((key - index) * me._distance); }); }; _proto._setTransition = function _setTransition(duration) { duration = duration || this._options.duration || 'none'; var transition = duration === 'none' ? 'none' : duration + 'ms'; arrayFrom(this.$items).forEach(function ($item, key) { $item.style.webkitTransition = transition; $item.style.transition = transition; }); }; _proto._setTransform = function _setTransform(offset) { var me = this; offset = offset || 0; arrayFrom(me.$items).forEach(function ($item, key) { var distance = me._offset[key] + offset; var transform = "translate3d(" + distance + "px, 0, 0)"; if (me._options.direction === 'vertical') { transform = "translate3d(0, " + distance + "px, 0)"; } $item.style.webkitTransform = transform; $item.style.transform = transform; }); }; _proto._bind = function _bind() { var _this = this; var me = this; me.touchstartHandler = function (e) { me.stop(); me._start.x = e.changedTouches[0].pageX; me._start.y = e.changedTouches[0].pageY; me._setTransition('none'); }; me.touchmoveHandler = function (e) { me._move.x = e.changedTouches[0].pageX; me._move.y = e.changedTouches[0].pageY; var distanceX = me._move.x - me._start.x; var distanceY = me._move.y - me._start.y; var distance = distanceY; var noScrollerY = Math.abs(distanceX) > Math.abs(distanceY); if (me._options.direction === 'horizontal' && noScrollerY) { distance = distanceX; } /* set shorter distance for first and last item for better experience */ if (!_this._options.loop && (_this._current === _this.count - 1 || _this._current === 0)) { distance = distance / 3; } if ((me._options.minMovingDistance && Math.abs(distance) >= me._options.minMovingDistance || !me._options.minMovingDistance) && noScrollerY) { me._setTransform(distance); } noScrollerY && e.preventDefault(); }; me.touchendHandler = function (e) { me._end.x = e.changedTouches[0].pageX; me._end.y = e.changedTouches[0].pageY; var distance = me._end.y - me._start.y; if (me._options.direction === 'horizontal') { distance = me._end.x - me._start.x; } distance = me.getDistance(distance); if (distance !== 0 && me._options.minMovingDistance && Math.abs(distance) < me._options.minMovingDistance) { return; } if (distance > me._options.threshold) { me.move(-1); } else if (distance < -me._options.threshold) { me.move(1); } else { me.move(0); } me._loopRender(); }; me.transitionEndHandler = function (e) { me._activate(me._current); var cb = me._eventHandlers.swiped; cb && cb.apply(me, [me._prev % me.count, me._current % me.count]); me._auto(); me._loopRender(); e.preventDefault(); }; me.$container.addEventListener('touchstart', me.touchstartHandler, false); me.$container.addEventListener('touchmove', me.touchmoveHandler, false); me.$container.addEventListener('touchend', me.touchendHandler, false); me.$items[1] && me.$items[1].addEventListener('webkitTransitionEnd', me.transitionEndHandler, false); }; _proto._loopRender = function _loopRender() { var me = this; if (me._loop()) { // issue #507 (delete cloneNode) if (me._offset[me._offset.length - 1] === 0) { me.$container.appendChild(me.$items[0]); me._loopEvent(1); } else if (me._offset[0] === 0) { me.$container.insertBefore(me.$items[me.$items.length - 1], me.$container.firstChild); me._loopEvent(-1); } } }; _proto._loopEvent = function _loopEvent(num) { var me = this; me._itemDestoy(); me.$items = me.$container.querySelectorAll(me._options.item); me.$items[1] && me.$items[1].addEventListener('webkitTransitionEnd', me.transitionEndHandler, false); me._movePosition(num); me._setOffset(); me._setTransform(); }; _proto.getDistance = function getDistance(distance) { if (this._loop()) { return distance; } else { if (distance > 0 && this._current === 0) { return 0; } else if (distance < 0 && this._current === this.realCount - 1) { return 0; } else { return distance; } } }; _proto._moveIndex = function _moveIndex(num) { if (num !== 0) { this._prev = this._current; this._current += this.realCount; this._current += num; this._current %= this.realCount; } }; _proto._activate = function _activate(index) { var clazz = this._options.activeClass; Array.prototype.forEach.call(this.$items, function ($item, key) { $item.classList.remove(clazz); if (index === Number($item.dataset.index)) { $item.classList.add(clazz); } }); }; _proto.go = function go(index) { var me = this; me.stop(); index = index || 0; index += this.realCount; index = index % this.realCount; index = this._position.indexOf(index) - this._position.indexOf(this._current); me._moveIndex(index); me._setOffset(); me._setTransition(); me._setTransform(); me._auto(); return this; }; _proto.next = function next() { this.move(1); return this; }; _proto.move = function move(num) { this.go(this._current + num); return this; }; _proto.on = function on(event, callback) { if (this._eventHandlers[event]) { console.error("[swiper] event " + event + " is already register"); } if (typeof callback !== 'function') { console.error('[swiper] parameter callback must be a function'); } this._eventHandlers[event] = callback; return this; }; _proto._itemDestoy = function _itemDestoy() { var _this2 = this; this.$items.length && arrayFrom(this.$items).forEach(function (item) { item.removeEventListener('webkitTransitionEnd', _this2.transitionEndHandler, false); }); }; _proto.destroy = function destroy() { this.stop(); this._current = 0; this._setTransform(0); window.removeEventListener('orientationchange', this.resizeHandler, false); this.$container.removeEventListener('touchstart', this.touchstartHandler, false); this.$container.removeEventListener('touchmove', this.touchmoveHandler, false); this.$container.removeEventListener('touchend', this.touchendHandler, false); this._itemDestoy(); // remove clone item (used by loop only 2) if (this._options.loop && this.count === 2) { var $item = this.$container.querySelector(this._options.item + "-clone"); $item && this.$container.removeChild($item); $item = this.$container.querySelector(this._options.item + "-clone"); $item && this.$container.removeChild($item); } }; return Swiper; }(); export default Swiper;