vue3实现列表随机抽奖功能,循环滚动最后减速停在选中项上
代码如下:
<template>
<div>
<div class="slot-machine" ref="slotMachine" style="height: 40px; overflow: hidden;">
<ul ref="list" class="options" :style="{ transform: `translateY(${position}px)` }">
<li v-for="(option, index) in options" :key="index">{{ option }}</li>
</ul>
</div>
<button @click="startSlotMachine">开始抽奖</button>
</div>
</template>
<script>
export default {
data() {
return {
options: [
'选项1',
'选项2',
'选项3',
'选项4',
'选项5',
'选项6',
'选项7',
'选项8',
'选项9',
'选项10',
'选项11',
], // 你的选项列表
position: 0,
duration: 5000, // 抽奖持续时间
speed: 10,
isSpinning: false
};
},
methods: {
startSlotMachine() {
if (!this.isSpinning) {
this.isSpinning = true;
const targetIndex = Math.floor(Math.random() * this.options.length); // 随机选择一个索引作为停止点
const itemHeight = this.$refs.list.querySelectorAll('li')[0].offsetHeight;
const distanceToTravel = itemHeight * (this.options.length * 10000); // 滚动距离,可根据需要调整
const acceleration = 1; // 减速度,可根据需要调整
this.speed = 10;
let currentTime = 0;
const easeOut = (t) => t * (2 - t);
const animate = () => {
if (currentTime < this.duration) {
requestAnimationFrame(animate);
}
currentTime += 10; // 动画每帧持续时间
const distance = easeOut(currentTime / this.duration) * distanceToTravel;
this.speed = acceleration * distance / this.duration;
this.position -= this.speed;
if (this.position <= -targetIndex * itemHeight) {
this.position = -targetIndex * itemHeight;
this.isSpinning = false;
}
};
animate();
}
}
}
};
</script>
<style>
.slot-machine {
border: 1px solid #ccc;
width: 200px;
margin: 20px 0;
position: relative;
}
.options {
list-style: none;
padding: 0;
margin: 0;
transition: transform 1s ease-out;
}
.options li {
height: 40px;
line-height: 40px;
}
</style>