需要先安装v-touch:npm i v-touch --save-dev
<template>
<div class="wrap">
<v-touch class="img-wrap" ref="parent" @pan="onTouchMove" @panend="onTouchEnd">
<!-- 这里是动态插入的图片 -->
</v-touch>
</div>
</template>
<script>
export default {
computed: {
parent () {
return this.$refs.parent.$el;
},
children () {
return this.parent.children;
},
listLen () {
return this.list.length;
}
},
data () {
return {
curIndex: 0,
list: [
'http://f12stag.kkmh.com/game/190412/OFIBO9jks.png',
'http://f12stag.kkmh.com/game/190103/MvNxrVmuQ.png',
'http://f12stag.kkmh.com/game/190222/JzLnPhqj5.png'
],
imgStyle: 'position: absolute; top: 0; left: 0; width: 200px; height: 100px; transition: all 1s; border: solid blue 1px;',
preImgStyle: 'transform: translateX(-100%);',
curImgStyle: 'transform: translateX(0);',
nextImgStyle: 'transform: translateX(100%);',
timer: null
};
},
methods: {
initBanner () {
if (!this.listLen) {
return;
}
if (this.listLen === 1) {
this.addImgDom('cur');
} else {
this.addImgDom('pre');
this.addImgDom('cur');
this.addImgDom('next');
this.setTimer();
}
},
addImgDom (type) {
let dom = document.createElement('img');
let index = this.curIndex;
if (type === 'pre') {
index--;
} else if (type === 'next') {
index++;
}
dom.src = this.getImgUrl(index);
dom.style.cssText = this.imgStyle + this[`${type}ImgStyle`];
this.parent.appendChild(dom);
},
setTimer () {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
this.timer = setInterval(() => {
this.touchValid = false;
this.updateDomStyle('next');
}, 3000);
},
updateDomStyle (type) {
if (type === 'next') {
let copyDom = this.children[2].cloneNode(true);
copyDom.src = this.getImgUrl(this.curIndex + 2);
copyDom.style.cssText += this.nextImgStyle;
this.parent.appendChild(copyDom);
this.children[1].style.cssText += this.preImgStyle;
this.children[2].style.cssText += this.curImgStyle;
this.curIndex = (this.curIndex + 1) % this.listLen;
this.children[1].addEventListener('transitionend', this.updateChildren(0));
} else {
let copyDom = this.children[0].cloneNode(true);
copyDom.src = this.getImgUrl(this.curIndex - 2);
copyDom.style.cssText += this.preImgStyle;
this.parent.insertBefore(copyDom, this.children[0]);
this.children[1].style.cssText += this.curImgStyle;
this.children[2].style.cssText += this.nextImgStyle;
this.curIndex = (this.curIndex - 1 + this.listLen) % this.listLen;
this.children[1].addEventListener('transitionend', this.updateChildren(3));
}
},
getImgUrl (index) {
return this.list[(index + this.listLen) % this.listLen];
},
updateChildren (index) {
this.touchValid = true;
this.parent.removeChild(this.children[index]);
},
onTouchMove (e) {
// 滑动过程中水平方向位移量
let offsetX = e.deltaX;
// 触摸屏幕时阻止过渡动画
for (let i = 0; i < this.children.length; i++) {
this.children[i].style.transitionDuration = '0s';
}
// e.preventDefault();
// 向左滑
if (offsetX < 0) {
this.children[2].style.transform = `translateX(calc(100% + ${offsetX}px))`;
} else if (offsetX > 0) {
this.children[0].style.transform = `translateX(calc(-100% + ${offsetX}px))`;
}
this.children[1].style.transform = `translateX(${offsetX}px)`;
},
onTouchEnd (e) {
let offsetX = e.deltaX;
// 触摸结束开始过渡动画
for (let i = 0; i < this.children.length; i++) {
this.children[i].style.transitionDuration = '1s';
}
// 向左滑
if (offsetX < 0) {
this.children[1].style.cssText += this.preImgStyle;
this.children[2].style.cssText += this.curImgStyle;
this.updateDomStyle('next');
} else if (offsetX > 0) {
this.children[0].style.cssText += this.curImgStyle;
this.children[1].style.cssText += this.nextImgStyle;
this.updateDomStyle('pre');
}
this.setTimer();
}
},
mounted () {
this.initBanner();
}
};
</script>
<style scoped>
.img-wrap {
position: relative;
margin: 100px auto;
width: 400px;
height: 200px;
border: solid red 1px;
overflow: hidden;
}
</style>
版权声明:本文为Sunny2011111原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。