mand-mobile
Version:
A Vue.js 2.0 Mobile UI Toolkit
699 lines (610 loc) • 22.5 kB
JavaScript
;(function(){
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define(['exports', '../_util/scroller', '../_util/render', '../_util', '../_style/global.css', './style/index.css'], factory);
} else if (typeof exports !== "undefined") {
factory(exports, require('../_util/scroller'), require('../_util/render'), require('../_util'), require('../_style/global.css'), require('./style/index.css'));
} else {
var mod = {
exports: {}
};
factory(mod.exports, global.scroller, global.render, global._util, global.global, global.index);
global.index = mod.exports;
}
})(this, function (exports, _scroller, _render, _util) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _scroller2 = _interopRequireDefault(_scroller);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
var PAGING_SCALE = 0.5;
var PAGING_DURATION = 300;
exports.default = {
name: 'md-swiper',
props: {
autoplay: {
type: Number,
default: 3000,
validator: function validator(value) {
if (value === 0) {
return true;
}
return value >= 500;
}
},
transition: {
type: String,
default: 'slide',
validator: function validator(value) {
return ['slide', 'slideY', 'fade'].indexOf(value) > -1;
}
},
transitionDuration: {
type: Number,
default: 250
},
defaultIndex: {
type: Number,
default: 0,
validator: function validator(value) {
return value > -1;
}
},
hasDots: {
type: Boolean,
default: true
},
isPrevent: {
type: Boolean,
default: true
},
isLoop: {
type: Boolean,
default: true
},
dragable: {
type: Boolean,
default: true
},
useNativeDriver: {
type: Boolean,
default: true
}
},
data: function data() {
return {
ready: false,
dragging: false,
userScrolling: null,
isInitial: false,
duration: 0,
index: 0,
fromIndex: 0,
toIndex: 0,
firstIndex: 0,
lastIndex: 0,
oItemCount: 0,
rItemCount: 0,
dimension: 0,
dragState: {},
touchAngle: 45,
timer: null,
noDrag: false,
scroller: null,
isStoped: true,
$swiper: null,
transitionEndHandler: null
};
},
watch: {
autoplay: {
handler: function handler(val) {
this.duration = val;
},
immediate: true
}
},
computed: {
isLastItem: function isLastItem() {
return this.index === this.rItemCount - 1;
},
isFirstItem: function isFirstItem() {
return this.index === 0;
},
realIndex: function realIndex() {
return this.getIndex();
},
isSlide: function isSlide() {
return this.transition.toLowerCase().indexOf('slide') > -1;
},
isVertical: function isVertical() {
return this.transition === 'slideY';
}
},
mounted: function mounted() {
this.$_resizeEnterBehavior();
},
activated: function activated() {
this.$_resizeEnterBehavior();
},
deactivated: function deactivated() {
this.$_resizeLeaveBehavior();
},
destroyed: function destroyed() {
this.$_resizeLeaveBehavior();
},
methods: {
$_resize: function $_resize() {
var _this = this;
if (this.__resizeTimeout__) {
clearTimeout(this.__resizeTimeout__);
}
var startIndex = this.index;
this.__resizeTimeout__ = setTimeout(function () {
_this.$_reInitItems(startIndex);
}, 300);
},
$_onDragStart: function $_onDragStart(e) {
this.transitionEndHandler && this.transitionEndHandler();
if (this.isPrevent) {
e.preventDefault();
}
this.dragging = true;
this.userScrolling = null;
this.$_doOnTouchStart(e);
},
$_onDragMove: function $_onDragMove(e) {
if (this.isPrevent) {
e.preventDefault();
}
if (!this.dragging) {
return;
}
this.$_doOnTouchMove(e);
},
$_onDragEnd: function $_onDragEnd(e) {
if (this.isPrevent) {
e.preventDefault();
}
if (this.userScrolling) {
this.play(this.duration);
this.dragging = false;
this.dragState = {};
return;
}
if (!this.dragging) {
return;
}
this.$_doOnTouchEnd(e);
this.dragging = false;
},
$_getDimension: function $_getDimension() {
this.dimension = this.isVertical ? this.$el.clientHeight : this.$el.clientWidth;
},
$_initScroller: function $_initScroller() {
var _this2 = this;
var scroller = new _scroller2.default(function (left, top) {
(0, _render.render)(_this2.$swiper, left, top, 1, _this2.useNativeDriver);
}, {
scrollingY: this.isVertical,
scrollingX: !this.isVertical,
snapping: false,
bouncing: false,
animationDuration: this.transitionDuration,
scrollingComplete: function scrollingComplete() {
_this2.transitionEndHandler && _this2.transitionEndHandler();
}
});
var container = this.$swiperBox;
var contentWidth = this.isVertical ? container.clientWidth : container.clientWidth * this.rItemCount;
var contentHeight = this.isVertical ? container.clientHeight * this.rItemCount : container.clientHeight;
scroller.setPosition(container.clientLeft, container.clientTop);
scroller.setDimensions(container.clientWidth, container.clientHeight, contentWidth, contentHeight);
this.scroller = scroller;
},
$_backupItem: function $_backupItem(children) {
var firstNode = children[0].$el.cloneNode(true);
var lastNode = children[children.length - 1].$el.cloneNode(true);
if (children.length > 1 && this.isLoop) {
var firstNodeCopy = this.$swiper.querySelector('.md-swiper-item-first-copy');
var lastNodeCopy = this.$swiper.querySelector('.md-swiper-item-last-copy');
firstNodeCopy && this.$swiper.removeChild(firstNodeCopy);
lastNodeCopy && this.$swiper.removeChild(lastNodeCopy);
firstNode.className += ' md-swiper-item-first-copy';
lastNode.className += ' md-swiper-item-last-copy';
if (this.isVertical) {
firstNode.style.height = this.dimension + 'px';
lastNode.style.height = this.dimension + 'px';
} else {
firstNode.style.width = this.dimension + 'px';
lastNode.style.width = this.dimension + 'px';
}
this.$swiper.appendChild(firstNode);
this.$swiper.insertBefore(lastNode, this.$swiper.childNodes[0]);
this.firstIndex++;
this.lastIndex++;
this.index++;
this.rItemCount += 2;
}
},
$_translate: function $_translate(element, offset) {
var animate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
if (!element) {
(0, _util.warn)('[md-swiper] no element for translate');
return;
}
var x = this.isVertical ? 0 : -offset;
var y = this.isVertical ? -offset : 0;
this.scroller.scrollTo(x, y, animate);
},
$_opacity: function $_opacity() {
var _this3 = this;
var animate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
var opacity = arguments[1];
var children = this.$children;
if (!children || !children.length) {
return;
}
if (typeof opacity !== 'undefined') {
var toIndex = 0;
var fromIndex = this.toIndex;
var itemCount = this.rItemCount;
if (opacity > 0) {
if (fromIndex > 0) {
toIndex = fromIndex - 1;
} else if (fromIndex === 0) {
toIndex = itemCount - 1;
}
} else {
if (fromIndex < itemCount - 1) {
toIndex = fromIndex + 1;
} else if (fromIndex === itemCount - 1) {
toIndex = 0;
}
}
var _from = children[fromIndex].$el;
var _to = children[toIndex].$el;
_from.style.opacity = 1 - Math.abs(opacity);
_from.style.transition = animate ? 'opacity 300ms ease' : '';
_to.style.opacity = Math.abs(opacity);
return;
}
var from = children[this.fromIndex].$el;
var to = children[this.toIndex].$el;
from.style.opacity = 0;
from.style.transition = animate ? 'opacity 500ms ease' : '';
to.style.opacity = 1;
if (animate) {
setTimeout(function () {
_this3.$emit('after-change', _this3.fromIndex, _this3.toIndex);
}, 500);
}
},
$_initState: function $_initState(children, startIndex) {
this.oItemCount = children.length;
this.rItemCount = children.length;
this.noDrag = children.length === 1 || !this.dragable;
this.index = startIndex !== undefined ? this.$_calcDisplayIndex(startIndex) : this.defaultIndex >= 0 && this.defaultIndex < children.length ? parseInt(this.defaultIndex) : 0;
this.firstIndex = 0;
this.lastIndex = children.length - 1;
this.fromIndex = this.index === this.firstIndex ? this.lastIndex : this.index === this.lastIndex ? this.firstIndex : this.index + 1;
this.toIndex = this.index;
},
$_reInitItems: function $_reInitItems(startIndex) {
var children = this.$children;
if (!children || !children.length) {
return;
}
this.$_getDimension();
this.$_initState(children, startIndex);
if (this.isSlide) {
this.$_backupItem(children);
this.$_initScroller();
this.$_translate(this.$swiper, -this.dimension * this.index, false);
} else {
this.$_opacity(false);
}
this.isInitial = true;
},
$_startPlay: function $_startPlay() {
var _this4 = this;
if (this.duration > 0 && this.oItemCount > 1) {
this.$_clearTimer();
this.timer = setInterval(function () {
if (!_this4.isLoop && _this4.index >= _this4.rItemCount - 1) {
return _this4.$_clearTimer();
}
if (!_this4.dragging) {
_this4.next();
}
}, this.duration);
}
},
$_clearTimer: function $_clearTimer() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
},
$_isScroll: function $_isScroll(dragState, diffX, diffY) {
var vertical = this.isVertical;
var currentLeft = dragState.currentLeft,
currentTop = dragState.currentTop,
startLeft = dragState.startLeft,
startTop = dragState.startTop;
if (this.userScrolling === null) {
if (!vertical && currentTop === startTop || vertical && currentLeft === startLeft) {
return false;
} else {
if (diffX * diffX + diffY * diffY >= 25) {
var _touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI;
return !vertical ? _touchAngle > this.touchAngle : 90 - _touchAngle > this.touchAngle;
} else {
return false;
}
}
}
return this.userScrolling;
},
$_calcDisplayIndex: function $_calcDisplayIndex(index) {
if (this.isLoop && this.isSlide && this.oItemCount > 0) {
return index - 1 < 0 ? this.oItemCount - 1 : index - 1 > this.oItemCount - 1 ? 0 : index - 1;
}
return index;
},
$_calcuRealIndex: function $_calcuRealIndex(index) {
if (index < 0) {
index = 0;
} else if (this.oItemCount > 0 && index > this.oItemCount - 1) {
index = this.oItemCount - 1;
}
if (this.isLoop && this.isSlide) {
return index + 1;
}
return index;
},
$_doTransition: function $_doTransition(towards, options) {
var _this5 = this;
if (this.oItemCount === 0) {
return;
}
if (!options && this.oItemCount < 2) {
return;
}
var index = this.index;
var itemCount = this.rItemCount;
var oldIndex = this.index;
if (!towards) {
return;
}
if (options && options.index !== undefined) {
this.index = options.index;
} else if (towards === 'prev') {
if (index > 0) {
this.index = index - 1;
} else if (!this.isSlide && index === 0) {
this.index = itemCount - 1;
} else if (this.isLoop && index === 0) {
this.index = itemCount - 1;
}
} else if (towards === 'next') {
if (index < itemCount - 1) {
this.index = index + 1;
} else if (!this.isSlide && index === itemCount - 1) {
this.index = 0;
} else if (this.isLoop && index === itemCount - 1) {
this.index = 1;
}
}
if (this.isLoop && this.isSlide) {
this.fromIndex = this.$_calcDisplayIndex(oldIndex);
this.toIndex = this.$_calcDisplayIndex(this.index);
} else {
this.fromIndex = this.toIndex;
this.toIndex = this.index;
}
this.$emit('before-change', this.fromIndex, this.toIndex);
if (!this.isSlide) {
this.$_opacity();
return;
}
setTimeout(function () {
var isFirstItem = _this5.isFirstItem && _this5.isLoop;
var isLastItem = _this5.isLastItem && _this5.isLoop;
_this5.transitionEndHandler = function () {
if (isLastItem) {
var x = _this5.isVertical ? 0 : _this5.firstIndex * _this5.dimension;
var y = _this5.isVertical ? _this5.firstIndex * _this5.dimension : 0;
_this5.scroller.scrollTo(x, y, false);
}
if (isFirstItem) {
var _x3 = _this5.isVertical ? 0 : _this5.lastIndex * _this5.dimension;
var _y = _this5.isVertical ? _this5.lastIndex * _this5.dimension : 0;
_this5.scroller.scrollTo(_x3, _y, false);
}
_this5.$emit('after-change', _this5.fromIndex, _this5.toIndex);
_this5.transitionEndHandler = null;
};
_this5.$_translate(_this5.$swiper, -_this5.dimension * _this5.index);
if (isFirstItem) {
_this5.index = _this5.lastIndex;
} else if (isLastItem) {
_this5.index = _this5.firstIndex;
}
}, 10);
},
$_doOnTouchStart: function $_doOnTouchStart(event) {
if (this.noDrag) {
return;
}
this.stop();
var element = this.$el;
var dragState = this.dragState;
var point = event.changedTouches ? event.changedTouches[0] : event;
dragState.startTime = new Date();
dragState.startLeft = point.pageX;
dragState.startTop = point.pageY;
dragState.itemWidth = process.env.MAND_ENV !== 'test' ? element.offsetWidth : 100;
dragState.itemHeight = process.env.MAND_ENV !== 'test' ? element.offsetHeight : 100;
},
$_doOnTouchMove: function $_doOnTouchMove(event) {
if (this.noDrag) {
return;
}
var dragState = this.dragState;
var point = event.changedTouches ? event.changedTouches[0] : event;
dragState.currentLeft = point.pageX;
dragState.currentTop = point.pageY;
var offsetLeft = dragState.currentLeft - dragState.startLeft;
var offsetTop = dragState.currentTop - dragState.startTop;
this.userScrolling = this.$_isScroll(dragState, Math.abs(offsetLeft), Math.abs(offsetTop));
if (this.userScrolling) {
return;
}
event.preventDefault();
var _offsetLeft = Math.min(Math.max(-dragState.itemWidth + 1, offsetLeft), dragState.itemWidth - 1);
var _offsetTop = Math.min(Math.max(-dragState.itemHeight + 1, offsetTop), dragState.itemHeight - 1);
var offset = this.isVertical ? _offsetTop - dragState.itemHeight * this.index : _offsetLeft - dragState.itemWidth * this.index;
if (this.isSlide) {
this.$_translate(this.$swiper, offset, false);
} else {
this.$_opacity(false, offsetLeft / dragState.itemWidth);
}
},
$_doOnTouchEnd: function $_doOnTouchEnd() {
if (this.noDrag) {
return;
}
var dragState = this.dragState;
var towards = null;
var dragDuration = new Date() - dragState.startTime;
var offsetLeft = dragState.currentLeft - dragState.startLeft;
var offsetTop = dragState.currentTop - dragState.startTop;
var itemWidth = dragState.itemWidth;
var itemHeight = dragState.itemHeight;
var index = this.index;
var itemCount = this.rItemCount;
var isFastDrag = dragDuration < PAGING_DURATION;
if (isFastDrag && dragState.currentLeft === undefined) {
this.play(this.duration);
return;
}
if (this.isVertical) {
if (Math.abs(offsetTop) > itemHeight * PAGING_SCALE || isFastDrag) {
towards = offsetTop < 0 ? 'next' : 'prev';
} else {
this.$_translate(this.$swiper, -this.dimension * index, true);
}
} else {
if (Math.abs(offsetLeft) > itemWidth * PAGING_SCALE || isFastDrag) {
towards = offsetLeft < 0 ? 'next' : 'prev';
} else {
if (this.isSlide) {
this.$_translate(this.$swiper, -this.dimension * index, true);
} else {
this.$_opacity(true, 0);
}
}
}
if (!this.isLoop) {
if (index === 0 && towards === 'prev' || index === itemCount - 1 && towards === 'next') {
towards = null;
}
}
this.$_doTransition(towards);
this.dragState = {};
this.play(this.duration);
},
$_resizeEnterBehavior: function $_resizeEnterBehavior() {
var _this6 = this;
this.ready = true;
this.$swiper = this.$el.querySelector('.md-swiper-container');
this.$swiperBox = this.$el.querySelector('.md-swiper-box');
this.$nextTick(function () {
_this6.$_reInitItems();
_this6.play(_this6.duration);
window.addEventListener('resize', _this6.$_resize);
});
},
$_resizeLeaveBehavior: function $_resizeLeaveBehavior() {
this.ready = false;
this.$_clearTimer();
window.removeEventListener('resize', this.$_resize);
if (this.__resizeTimeout__) {
clearTimeout(this.__resizeTimeout__);
}
},
next: function next() {
this.$_doTransition('next');
},
prev: function prev() {
this.$_doTransition('prev');
},
goto: function goto(displayIndex) {
if (isNaN(displayIndex)) {
return;
}
displayIndex = parseInt(displayIndex);
var realIndex = this.$_calcuRealIndex(displayIndex);
var towards = realIndex > this.index ? 'next' : 'pre';
this.$_doTransition(towards, {
index: realIndex
});
this.play(this.duration);
},
getIndex: function getIndex() {
return this.$_calcDisplayIndex(this.index);
},
play: function play() {
var duration = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 3000;
this.$_clearTimer();
if (duration < 500) {
return;
}
this.duration = duration || this.autoplay;
this.$_startPlay();
this.isStoped = false;
},
stop: function stop() {
this.$_clearTimer();
this.isStoped = true;
},
swiperItemCreated: function swiperItemCreated() {
var _this7 = this;
if (!this.ready) {
return;
}
this.$nextTick(function () {
_this7.$_clearTimer();
_this7.$_reInitItems();
if (!_this7.isStoped) {
_this7.play(_this7.duration);
}
});
},
swiperItemDestroyed: (0, _util.debounce)(function () {
var _this8 = this;
if (!this.ready) {
return;
}
this.$nextTick(function () {
_this8.$_clearTimer();
_this8.$_reInitItems();
if (!_this8.isStoped) {
_this8.play(_this8.duration);
}
});
}, 50)
}
};
});
})()
if (module.exports.__esModule) module.exports = module.exports.default
var __vue__options__ = (typeof module.exports === "function"? module.exports.options: module.exports)
__vue__options__.render = function render () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"md-swiper",class:{'md-swiper-vertical': _vm.isVertical, 'md-swiper-fade': !_vm.isSlide, 'disabled': !_vm.isInitial},on:{"mousedown":_vm.$_onDragStart,"mousemove":_vm.$_onDragMove,"mouseup":_vm.$_onDragEnd,"mouseleave":_vm.$_onDragEnd,"touchstart":_vm.$_onDragStart,"touchmove":_vm.$_onDragMove,"touchend":_vm.$_onDragEnd,"touchcancel":_vm.$_onDragEnd}},[_c('div',{staticClass:"md-swiper-box"},[_c('div',{staticClass:"md-swiper-container"},[_vm._t("default")],2)]),_vm._v(" "),(_vm.oItemCount > 1 && _vm.hasDots)?_c('div',{staticClass:"md-swiper-indicators",class:{'disabled': !_vm.hasDots}},[_vm._l((_vm.oItemCount),function(index){return [_c('div',{key:index,staticClass:"md-swiper-indicator",class:{ 'md-swiper-indicator-active': index - 1 === _vm.realIndex }})]})],2):_vm._e()])}
__vue__options__.staticRenderFns = []