unique-interface
Version:
无UI组件库
221 lines (217 loc) • 7.6 kB
JavaScript
var $ = require('ether-vway');
module.exports = {
template: require("./swipe.html"),
assets: [require("./swipe.less")],
props: {
imgList: '',
// speed:动画时间 auto:轮播间隔时间
speed: {
type: Number,
default: 800
},
auto: {
type: Number,
default: 3000
}
},
data: function(){
return {
swiping: false,
animating: false,
index: 0,
pages: [],
timer: null,
pageCount: 0,
newIndex: -1,
ready: false
};
},
computed: {
prevPage: function(){
return this.index === 0 ? this.pages[this.pages.length - 1] : this.pages[this.index - 1];
},
currentPage: function(){
return this.pages[this.index];
},
nextPage: function(){
return this.pages[(this.index + 1) % this.pages.length];
}
},
watch: {
index: function(){
this.currentPage.classList.add('is-active');
this.prevPage.classList.remove('is-active');
this.nextPage.classList.remove('is-active');
}
},
mounted: function() {
var _this = this;
var interval = setInterval(function(){
if (_this.ready) {
clearInterval(interval);
_this.initTimer();
_this.initPages();
if(_this.pageCount < 2) return;
var element = _this.$el;
$.dom.on(element, 'touchstart', function(e){
e.stopPropagation();
});
$.dom.on(element, 'touchmove', function(e){
e.stopPropagation();
});
$.dom.on(element, 'touchend', function(e){
e.stopPropagation();
});
}
}, 100);
},
destroyed: function() {
if (this.timer) this.clearTimer();
},
methods: {
loadImg: function(){
var img = document.querySelector('.swipe-items-wrap img');
var imgStyle = $.dom.css(img);
img.style.display = 'block';
var height = parseInt(imgStyle.height);
img.style.display = imgStyle.display;
this.$emit('loadImg', height);
this.ready = true;
},
pressUpFunction: function(){
this.initTimer();
},
pressFunction: function(){
if (this.timer) {
this.clearTimer();
}
},
panStart: function(e){
this.startTime = new Date();
if(this.animating) return;
this.swiping = true;
},
panEnd: function(e){
this.endTime = new Date();
if(!this.swiping) return;
if(this.endTime - this.startTime > 1000){
this.swiping = false;
return;
}
if (this.timer) this.clearTimer();
var action = e.deltaX > 0 ? 'prev' : 'next';
this.animateAction(action);
this.initTimer();
this.swiping = false;
},
swipeAction: function(action){
if(this.pageCount < 2) return;
if (this.swiping || this.animating) return;
this.swiping = true;
if (this.timer) this.clearTimer();
this.animateAction(action);
this.swiping = false;
this.initTimer();
},
translate: function(element, offset, speed, callback) {
var _this = this;
if (speed) {
element.style.webkitTransition = '-webkit-transform ' + speed + 'ms ease-in-out';
element.style.webkitTransform = 'translate3d(' + offset + 'px, 0, 0)';
var called = false;
var transitionEndCallback = function(){
if (called){
element.removeEventListener('webkitTransitionEnd', transitionEndCallback, false);
return;
}
called = true;
_this.animating = false;
_this.swiping = false;
element.style.webkitTransition = '';
element.style.webkitTransform = '';
if (callback) {
callback.apply(_this, arguments);
}
element.removeEventListener('webkitTransitionEnd', transitionEndCallback, false);
};
element.addEventListener('webkitTransitionEnd', transitionEndCallback, false);
setTimeout(transitionEndCallback, speed + 100);
} else {
element.style.webkitTransition = '';
element.style.webkitTransform = 'translate3d(' + offset + 'px, 0, 0)';
}
},
initPages: function(){
var children = this.$refs.container.children;
children[this.index].classList.add('is-active');
this.pages = children;
this.pageCount = children.length;
},
doAnimate: function(towards, flag) {
this.animating = true;
var pageCount = this.pageCount;
var _this = this,
speed = _this.speed || 300,
index = _this.index;
var offsetLeft, pageWidth = _this.$el.clientWidth;
_this.switchDisplay('block');
if (towards === 'next') {
_this.translate(_this.nextPage, pageWidth);
this.newIndex = (index + 1) % pageCount;
} else {
_this.translate(_this.prevPage, -pageWidth);
this.newIndex = index === 0 ? pageCount - 1 : index - 1;
}
setTimeout(function(){
var width = pageWidth;
if (towards === 'next') {
width = -pageWidth;
_this.translate(_this.nextPage, 0, speed);
} else {
_this.translate(_this.prevPage, 0, speed);
}
_this.translate(_this.currentPage, width, speed, _this.animateCallback);
}, 20);
},
animateCallback: function(){
if (this.newIndex !== -1) {
var newPage = this.pages[this.newIndex];
this.index = this.newIndex;
}
this.switchDisplay('');
},
animateAction: function(action) {
if(this.pageCount < 2) return;
if(this.animating){
return;
}
this.doAnimate(action, true);
},
switchDisplay: function(action){
if(this.pageCount < 3){
return;
}
this.prevPage.style.display = action;
this.nextPage.style.display = action;
},
initTimer: function() {
var _this = this;
_this.clearTimer();
_this.timer = setInterval(function(){
if (!_this.swiping && !_this.animating) {
_this.animateAction('next');
}
}, _this.auto);
},
clearTimer: function() {
clearInterval(this.timer);
this.timer = null;
},
triggerClick: function(obj){
this.$emit('click', obj);
}
},
components: {
'v-touch': require('vue-touch').component
}
};