无缝滚动效果 ,外加 手指的移动效果
思路:
1.无缝滚动1个内容区域,复制一下这个内容,追加到改内容的后面,形成无缝滚动的效果
2.手指左滑右滑进行x轴方向的加减
代码如下:
<template>
<div class="scroll-container" ref="container">
<div
class="scroll-content"
ref="content"
@touchstart.stop="handlerTouchStart"
@touchmove.stop="handlerTouchMove"
@touchend.stop="handlerTouchEnd"
>
<!-- 滚动内容放在这里 -->
<div class="list">
<div v-for="(item, index) in list" :key="index">
<img :src="item" alt="" />
</div>
</div>
</div>
</div>
</template>
<script>
import a from "../assets/imgs/1.jpg";
import b from "../assets/imgs/2.jpg";
import c from "../assets/imgs/3.jpg";
import d from "../assets/imgs/4.jpg";
import e from "../assets/imgs/5.jpg";
import f from "../assets/imgs/6.jpg";
import g from "../assets/imgs/7.jpg";
import h from "../assets/imgs/8.jpg";
import i from "../assets/imgs/9.jpg";
import j from "../assets/imgs/10.jpg";
export default {
data() {
return {
list: [a, b, c, d, e, f, g, h, i, j],
startLocation: 0, //手指起始位置
step: 2, //移动步长
offsetX: 0, //水平方向移动的距离
timerid: null, //任务id
moveDistance: 0, //手指滑动的距离
contentWidth: 0 //一个容器的宽度
};
},
mounted() {
this.$nextTick(() => {
// 获取滚动内容元素和容器元素
const content = this.$refs.content;
const container = this.$refs.container;
// 获取滚动内容的宽度
this.contentWidth = content.offsetWidth;
// 复制滚动内容并追加到原来的内容后面
const clone = content.cloneNode(true);
content.parentNode.appendChild(clone);
// 设置滚动内容的总宽度,使其可以无限循环滚动
container.style.width = this.contentWidth * 2 + "px";
// 开启动画
this.startAnimation();
});
},
methods: {
startAnimation() {
this.offsetX += this.step;
// if (this.offsetX <= 0 || this.offsetX >= this.contentWidth) {
// this.offsetX = 0;
// }
// if (this.offsetX % this.contentWidth == 0) this.offsetX = 0;
this.limitX();
this.updateAnimate(this.offsetX);
this.timerid = requestAnimationFrame(this.startAnimation);
},
updateAnimate(x) {
this.$refs.container.setAttribute(
"style",
`width:${2 * this.contentWidth}px;transform: translateX(${-x}px)`
);
},
handlerTouchStart(e) {
cancelAnimationFrame(this.timerid);
this.startLocation = e.touches[0].pageX;
},
handlerTouchMove(e) {
const current = e.touches[0].pageX;
// 手指滑动距离
this.moveDistance = Math.floor(e.touches[0].pageX - this.startLocation);
if (current > this.startLocation) {
// 往右划
this.offsetX -= Math.abs(this.moveDistance);
} else {
// 往左滑
this.offsetX += Math.abs(this.moveDistance);
}
// 判断边界距离
this.limitX();
// if (this.offsetX <= 0 || this.offsetX >= 1000) {
// this.offsetX = 0;
// }
// if (this.offsetX % this.contentWidth == 0) this.offsetX = 0;
this.updateAnimate(this.offsetX);
},
handlerTouchEnd() {
this.startAnimation();
},
limitX() {
if (this.offsetX <= 0 || this.offsetX >= this.contentWidth) {
this.offsetX = 0;
}
if (this.offsetX % this.contentWidth == 0) this.offsetX = 0;
}
}
};
</script>
<style scoped lang="less">
.list {
height: 100px;
// background: papayawhip;
display: flex;
div {
width: 100px;
height: 100px;
img {
width: 100%;
height: 100%;
}
}
}
.scroll-container {
overflow-x: scroll;
white-space: nowrap;
}
.scroll-content {
display: inline-block;
}
.scroll-content {
// animation: scroll 20s linear infinite;
}
// @keyframes scroll {
// 0% {
// transform: translateX(0);
// }
// 100% {
// transform: translateX(-100%);
// }
// }
</style>