UNPKG

zview-mobile

Version:

Mobile UI Components, based on Vue.js and ionic CSS.

220 lines (172 loc) 5.08 kB
// default options const DEFAULT_OPTIONS = { itemClass: '.swiper-item', direction: 'vertical', threshold: 30, duration: 250, transitionEnd: noop } // utilities const extend = (target, source) => { for (var key in source) { target[key] = source[key] } return target } function noop() {} function execFn(fn) { setTimeout(fn || noop, 0)} function Swiper(container, swiperOptions) { let options = extend(DEFAULT_OPTIONS, swiperOptions) let prev = 0 let current = 0 let offset = 0 let items = container.querySelectorAll(options.itemClass) let count = items.length let width = container.getBoundingClientRect().width || container.offsetWidth let height = container.getBoundingClientRect().height || container.offsetHeight // Setup function setup() { // reset container's width and height var w = width; var h = height * count if (options.direction === 'horizontal') { w = width * count h = height } container.style.width = w + 'px' container.style.height = h + 'px' // set width and height for every single swipe item let pos = count while (pos--) { let item = items[pos] item.style.width = width + 'px' item.style.height = height + 'px' } } // Activate a item function activate(index) { offset = index * height let transform = 'translate3d(0, -' + offset + 'px, 0)' if (options.direction == 'horizontal') { offset = index * width; transform = 'translate3d(-' + offset + 'px, 0, 0)'; } let duration = options.duration + 'ms' let style = container.style style.webkitTransition = style.transition = duration style.webkitTransform = style.transform = transform } // Events // init varialbles let start = {} let move = {} let end = {} const events = { start: function (e) { let touch = e.changedTouches[0] start.x = touch.pageX start.y = touch.pageY start.time = +new Date() let style = container.style style.webkitTransition = style.transition = 'none' }, move: function (e) { // ensure swiping with one touch and not pinching // if ( event.touches.length > 1 || event.scale && event.scale !== 1) return let touch = e.changedTouches[0] move.x = touch.pageX move.y = touch.pageY let dist = move.y - start.y let transform = 'translate3d(0, ' + (dist - offset) + 'px, 0)' if (options.direction == 'horizontal') { dist = move.x - start.x transform = 'translate3d(' + (dist - offset) + 'px, 0, 0)' } let style = container.style style.webkitTransform = style.transfrom = transform e.preventDefault() }, end: function (e) { let touch = e.changedTouches[0] end.x = touch.pageX end.y = touch.pageY let dist = end.y - start.y if (options.direction == 'horizontal') { dist = end.x - start.x } prev = current if (dist > options.threshold) { current = current == 0 ? 0 : --current e.preventDefault() } else if (dist < -options.threshold) { current = current < count - 1 ? ++current : current e.preventDefault() } activate(current) }, transitionEnd: function (e) { options.transitionEnd && options.transitionEnd.call(e, prev, current) e.preventDefault() } } function resize() { execFn(setup) } // bind events function bind() { container.addEventListener('touchstart', events.start) container.addEventListener('touchmove', events.move) container.addEventListener('touchend', events.end) container.addEventListener('transitionEnd', noop) container.addEventListener('webkitTransitionEnd', events.transitionEnd) container.addEventListener('resize', resize) } function unbind() { container.removeEventListener('touchstart', events.start) container.removeEventListener('touchmove', events.move) container.removeEventListener('touchend', events.end) container.removeEventListener('transitionEnd', noop) container.removeEventListener('webkitTransitionEnd', events.transitionEnd) container.removeEventListener('resize', resize) } window.addEventListener('resize', resize) setup() bind() // Publish APIs function noTransition() { let style = container.style style.webkitTransition = style.transition = 'none' } return { resize: setup, destroy: function () { unbind() window.removeEventListener('resize', resize) }, next: function () { noTransition() current = current < count - 1 ? ++current : current activate(current) }, prev: function () { noTransition() current = current == 0 ? 0 : --current activate(current) }, go: function (index) { noTransition() current = index activate(current) }, count: count, activeIndex: function () { return current; } } } export default Swiper