先看看需求:
不抽奖的情况下转盘默认会转(插件不支持这个功能)
再看看这套模板(布局已经弄好,找ui切图微调即可)
一.搞个文件夹丢进去
copy全部
<!--
* new page
* @author: FuJing
* @since: 2023-04-13
* ches.vue
-->
<template>
<div id="app" v-cloak>
<div class="container">
<div class="prize-list" ref="prizeWrap" :style="bgColor">
<div
class="prize-item"
v-for="(item, index) in state.prizeList"
:key="index"
:style="prizeStyle(index)"
>
<img :src="item.pic" alt="" />
<p>{{ item.name }}</p>
</div>
</div>
<div
class="cone"
v-for="(item, index) in state.prizeList"
:key="index"
>
<span v-if="imgId == index ? true : false">
<img :src="item.pic" alt="" />
</span>
</div>
</div>
<div class="begin" @click="start">点击开始抽奖</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, onUnmounted, ref, reactive, computed } from 'vue'
const state = reactive({
prizeList: [
{
name: '玫瑰',
pic: 'https://img1.baidu.com/it/u=1125656938,422247900&fm=253&fmt=auto&app=120&f=JPEG'
},
{
name: '手表',
pic: 'https://img1.baidu.com/it/u=2631716577,1296460670&fm=253&fmt=auto&app=120&f=JPEG'
},
{
name: '苹果',
pic: 'https://img2.baidu.com/it/u=2611478896,137965957&fm=253&fmt=auto&app=138&f=JPEG'
},
{
name: '棒棒糖',
pic: 'https://img2.baidu.com/it/u=576980037,1655121105&fm=253&fmt=auto&app=138&f=PNG'
}
// {
// name: '娃娃',
// pic: 'https://img2.baidu.com/it/u=4075390137,3967712457&fm=253&fmt=auto&app=138&f=PNG'
// },
// {
// name: '木马',
// pic: 'https://img1.baidu.com/it/u=2434318933,2727681086&fm=253&fmt=auto&app=120&f=JPEG'
// },
// {
// name: '德芙',
// pic: 'https://img0.baidu.com/it/u=1378564582,2397555841&fm=253&fmt=auto&app=120&f=JPEG'
// },
// {
// name: '玫瑰',
// pic: 'https://img1.baidu.com/it/u=1125656938,422247900&fm=253&fmt=auto&app=120&f=JPEG'
// }
], // 后台配置的奖品数据
isRunning: false, // 是否正在抽奖
baseRunAngle: 360 * 20, // 总共转动角度 至少5圈
prizeId: 0 // 中奖id
})
const img = ref('')
const prizeWrap: any = ref(null)
// 平均每个奖品角度
const rotateAngle = computed(() => {
const _degree = 360 / state.prizeList.length
return _degree
})
// 要执行总角度数
const totalRunAngle = computed(() => {
return (
state.baseRunAngle +
360 -
state.prizeId * rotateAngle.value -
rotateAngle.value / 2
)
})
// 计算绘制转盘背景
const bgColor = computed(() => {
const _len = state.prizeList.length
const colorList = ['#c90007', '#c90007']
let colorVal = ''
for (let i = 0; i < _len; i++) {
colorVal += `${colorList[i % 2]} ${rotateAngle.value * i}deg ${
rotateAngle.value * (i + 1)
}deg,`
}
return `
background: conic-gradient(${colorVal.slice(0, -1)});
`
})
// 每个奖品布局
const prizeStyle = computed(() => {
const _degree = rotateAngle.value
return (i: any) => {
return `
width: ${2 * 270 * Math.sin(((_degree / 2) * Math.PI) / 180)}px;
height: 270px;
transform: rotate(${_degree * i + _degree / 2}deg);
transform-origin: 50% 100%;
`
}
})
// 开始自动旋转
onMounted(() => {
// prizeWrap.value.style = `${bgColor.value} transform: rotate(-${
// rotateAngle.value / 2
// }deg)`
setTimeout(() => {
prizeWrap.value.style = `
${bgColor.value}
transform: rotate(${totalRunAngle.value / 2}deg);
transition: all 500s ease;
`
}, 50)
})
onUnmounted(() => {
prizeWrap.value.removeEventListener('transitionend', stopRun)
})
// 获取随机数
const getRandomNum = () => {
const num = Math.floor(Math.random() * state.prizeList.length)
return num
}
const startRun = () => {
console.log(state.isRunning, totalRunAngle.value)
// 设置动效
prizeWrap.value.style = `
${bgColor.value}
transform: rotate(${totalRunAngle.value}deg);
transition: all 4s ease;
`
// 监听transition动效停止事件
prizeWrap.value.addEventListener('transitionend', stopRun)
}
let imgId = ref(0)
const start = () => {
const timer = setInterval(() => {
imgId.value += 1
imgId.value = imgId.value == state.prizeList.length ? 0 : imgId.value
console.log(imgId.value)
}, 200)
console.log(state.isRunning, '-----------')
// if (!state.isRunning) {
state.isRunning = true
console.log('开始抽奖,后台请求中奖奖品')
// 请求返回的奖品编号 这里使用随机数 固定奖品地方===================
const prizeId = getRandomNum()
// const prizeId = 1
console.log('中奖ID>>>', prizeId, state.prizeList[prizeId])
state.prizeId = prizeId
startRun()
setTimeout(() => {
img.value = state.prizeList[prizeId].pic
imgId.value = prizeId
clearInterval(timer)
}, 3800)
// }
}
const stopRun = (e: any) => {
console.log(e)
state.isRunning = false
prizeWrap.value.style = `
${bgColor.value}
transform: rotate(${totalRunAngle.value - state.baseRunAngle}deg);
`
}
</script>
<style lang="less" scoped>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
[v-cloak] {
display: none;
}
.container {
width: 710px;
height: 710px;
/*background: #98d3fc url('https://www.jq22.com/demo/vue-luck-draw-pdmm202010260015/img/bg.a4b976d5.png') no-repeat center / 100% 100%;*/
/*background: conic-gradient(
red 6deg, orange 6deg 18deg, yellow 18deg 45deg,
green 45deg 110deg, blue 110deg 200deg, purple 200deg);*/
margin: 0 auto;
position: relative;
}
.prize-list {
width: 710px;
height: 710px;
border-radius: 50%;
border: 10px solid #ffd902;
overflow: hidden;
position: relative;
}
.prize-item {
/*border: 2px solid red;*/
width: 100px !important;
height: 100px !important;
position: absolute;
left: 210px;
// right: 400px;
top: 160px;
// 调整中间奖品的整体位置
margin: 80px 0 0 80px;
}
.prize-item img {
width: 300px;
height: 80px;
// 调整四个奖品的开合度 0 0 调整单个奖品的位置
margin: -230px 0 0 -100px;
display: block;
}
.prize-item p {
color: #fff;
font-size: 12px;
text-align: center;
line-height: 20px;
}
// 中间显示奖品的样式
.cone {
position: absolute;
width: 500px;
height: 500px;
border-radius: 50%;
left: 110px;
right: 0;
top: 105px;
bottom: 0;
animation-name: scaleDraw; /*关键帧名称*/
animation-timing-function: ease-in-out; /*动画的速度曲线*/
animation-iteration-count: infinite; /*动画播放的次数*/
animation-duration: 2s; /*动画所花费的时间*/
overflow: hidden;
img {
width: 100%;
}
}
@keyframes scaleDraw {
/*定义关键帧、scaleDrew是需要绑定到选择器的关键帧名称*/
0% {
transform: scale(1); /*开始为原始大小*/
}
25% {
transform: scale(1); /*放大1.1倍*/
}
50% {
transform: scale(1);
}
75% {
transform: scale(1);
}
100% {
transform: scale(1);
}
}
.btn::before {
content: '';
width: 41px;
height: 39px;
background: url('https://www.jq22.com/demo/jquerylocal201912122316/img/icon_point.png')
no-repeat center / 100% 100%;
position: absolute;
left: 0;
right: 0;
top: -33px;
margin: auto;
}
.imgs {
position: absolute;
}
.begin {
width: 400px;
height: 100px;
background-color: #fff;
margin: 0 auto;
line-height: 100px;
text-align: center;
}
</style>
可以当组件引进去直接用
最后我的成果
转盘直接放背景图就好了(如果位置不对就叫ui给你调角度),以下是我使用到的切图,仅供参考。。。
![在这里插入图片描述](https://img-blog.csdnimg.cn/f0bb7dfdaef745b09c3d33c390def8cc.png
由于我装了自适应插件(viewport 方案)样式如果会错乱就自己调整噢,css地方有注释,方便大家找
如果要跟我一样装自适应插件,请参考(https://blog.csdn.net/qq_62809806/article/details/126850947?spm=1001.2014.3001.5501)
如果有更好的转盘方案欢迎大伙分享噢~