仿csgo横向滚动抽奖效果 (源码直接复制)
简述
- 最近小伙伴找到我,希望可以写一个仿csgo横向滚动抽奖效果,快速写了一个demo满足需求,记录一下具体代码。
效果
抽奖特效
代码
<template>
<div id="app">
<div>
<div class="wrap">
<div class="check">↑</div>
<div class="list-group-wrap" :class="{ roll_animation: rollState == 'start' }" :style="{
transform: `translateX(${translateX}px)`,
'transition-duration': duration + 'ms',
}">
<div v-for="(item, index) in shaftList" :key="index" :style="{
background: item.color,
}" class="list-group-item">
{{ item.index }}
</div>
<!-- <div class="list-group-wrap"></div> -->
</div>
</div>
<div style="margin-left: 65px; margin-top: 15px">
<button @click="roll({ index: 1 })">1</button>
<button @click="roll({ index: 4 })">4</button>
<button @click="roll({ index: 5 })">5</button>
<button @click="roll({ index: 6 })">6</button>
<button @click="roll({ index: 7 })">7</button>
<button @click="roll({ index: 8 })">8</button>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
prizeList: [
{ "index": 1, "color": "red" },
{ "index": 2, "color": "orange" },
{ "index": 3, "color": "yellow" },
{ "index": 4, "color": "green" },
{ "index": 5, "color": "blue" },
{ "index": 6, "color": "indigo" },
{ "index": 7, "color": "violet" },
{ "index": 8, "color": "pink" },
{ "index": 9, "color": "brown" },
{ "index": 10, "color": "grey" },
{ "index": 11, "color": "purple" },
{ "index": 12, "color": "cyan" },
{ "index": 13, "color": "magenta" },
{ "index": 14, "color": "lime" },
{ "index": 15, "color": "teal" }
],
// 位置
translateX: 0,
// 摇奖状态
rollState: "stop",
// 总的摇奖时间 单位毫秒
duration: 4000,
// 滚动列表
shaftList: [],
selfWidth: 0,
defaultNum: 4,//第一次加载时指针指向的数字 (宽度修改了这里也要改变)
};
},
mounted () {
this.init({
duration: 3500,
});
this.$nextTick(() => {
let element = document.querySelector('.list-group-item')
let computedStyle = window.getComputedStyle(element);
this.selfWidth = Number(computedStyle.width.replace('px', '')) + Number(computedStyle.marginRight.replace('px', ''));
console.log(Number(computedStyle.width.replace('px', '')) + Number(computedStyle.marginRight.replace('px', '')))
})
},
methods: {
// 初始化
init ({
duration = 3500,
}) {
// 最低4秒
if (duration < 4000) {
duration = 4000;
}
this.shaftList = [];
this.shaftList = this.shuffle(this.prizeList, 9);
this.$nextTick(function () {
this.duration = duration;
});
},
// 拷贝们的数组,方遍横项滚动
shuffle (arr, num) {
let tmpShaft = [];
while (num > 0) {
tmpShaft.push(...arr);
num--;
}
return tmpShaft;
},
// 设定位置
setTranslateX (index) {
const groupPrizeLength = this.prizeList.length
// 倒序遍历奖品列表,找出开奖结果的最靠后的下标
for (let k = this.shaftList.length - 1 - groupPrizeLength; k >= 0; k--) {
console.log(this.shaftList[k].index == index, this.shaftList[k].index, index, k)
if (this.shaftList[k].index == index) {
// 延迟滚动
this.translateX = -(k - (this.defaultNum - 1)) * this.selfWidth;
break;
}
}
},
// 摇奖
roll ({
index
}) {
if (this.rollState == "start") {
return console.warn("正在抽奖哦!");
}
this.rollState = "start";
// 滚动到指定位置
this.setTranslateX(index);
setTimeout(() => {
this.stop(index);
}, this.duration + 1000);
},
stop (index) {
this.rollState = "stop";
this.$nextTick(function () {
// 停止滚动之后,位移到第二组奖品列表的对应位置,为下一次摇奖留下滚动空间,实现多次摇奖无缝滚动效果
this.translateX = -(this.prizeList.length + (index - (this.defaultNum))) * this.selfWidth;
});
},
},
};
</script>
<style scoped>
.wrap {
position: relative;
margin-top: 15px;
margin-left: 30px;
width: 740px;
height: 120px;
border: 1px solid #ccc;
border-radius: 5px;
overflow: hidden;
}
.check {
position: absolute;
left: 50%;
right: 50%;
bottom: 0;
z-index: 999;
}
.list-group-wrap {
/* position: absolute; */
width: 63000px;
/* display: flex */
/* align-items: center; */
/* position: absolute; */
/* width: 2400px; */
transition-property: none;
transition-duration: 0s;
padding: 10px;
}
.list-group-item {
display: inline-block;
width: 100px;
height: 100px;
margin-right: 10px;
}
.item_actived {
border: 3px dashed #c5821c;
}
.roll_animation {
transition-property: transform;
transition-timing-function: cubic-bezier(0, 0, 0.58, 1);
}
</style>