调佣代码
<template>
<div class="content minHeight100">
<div style="width:300px;margin:50px auto">
<div class="flex margin-bottom-2x">
<h4 class="red margin-right-1x">剩余抽奖次数:{{ num }}</h4>
<button class="color-btn bg-cyan anim-but-5-cyan" @click="startRotation">抽奖</button>
</div>
<div class="turntableBox">
<img src="../../assets/images/Pointer.png"
class="RoundTurntableImg" alt="">
<RoundTurntable ref="roundTurntable" :prizeData="prizeData" :rotateCircle="rotateCircle"
:duringTime="duringTime" :turntableStyleOption="turntableStyleOption" @endRotation="endRotation"
class="turntable">
<template #item="scope">
<div class="turntable-name">{{ scope.item.level }}</div>
<div class="turntable-img">
<img :src="scope.item.picture" />
</div>
</template>
</RoundTurntable>
</div>
</div>
</div>
</template>
<script>
import RoundTurntable from '@/view/luckDraw/RoundTurntable';
import {message} from "ant-design-vue"
export default {
name: 'lattice',
components: {
RoundTurntable
},
data() {
return {
// 转盘上的奖品数据
prizeData: [{
id: 1,
level: '2000元京东券',
picture: require('../../assets/images/gift.png')
},
{
id: 2,
level: '300元京东券',
picture: require('../../assets/images/gift.png')
},
{
id: 3,
level: '加班一天',
picture: require('../../assets/images/gift.png')
},
{
id: 4,
level: '50元话费券',
picture: require('../../assets/images/gift.png')
},
{
id: 5,
level: '100元话费券',
picture: require('../../assets/images/gift.png')
},
{
id: 6,
level: '50元现金',
picture: require('../../assets/images/gift.png')
},
{
id: 7,
level: '50元现金',
picture: require('../../assets/images/gift.png')
},
{
id: 8,
level: '50元现金',
picture: require('../../assets/images/gift.png')
}
],
// 转动的圈数
rotateCircle: 6,
// 转动需要持续的时间(s)
duringTime: 4.5,
// 转盘样式的选项
turntableStyleOption: {
// 背景色
prizeBgColors: ['#ffe0d6', '#fffdfe', '#ffe0d6', '#fffdfe', '#ffe0d6', '#fffdfe', '#ffe0d6',
'#fffdfe'
],
// 转盘的外边框颜色
borderColor: '#fede87'
},
// 中奖的奖品的index
prizeIndex: -1,
// 用来锁定转盘,避免同时多次点击转动
isLocking: false,
// 剩余抽奖次数
num: 5
};
},
methods: {
// 开始抽奖
startRotation() {
// 如果还不可以转动
if (!this.canBeRotated()) {
return false;
}
// 开始转动
// 先上锁
this.isLocking = true;
// 设置在哪里停下,应该与后台交互,这里随机抽取0~5
const index = Math.floor(Math.random() * this.prizeData.length);
// 成功后次数减少一次
this.num--;
this.prizeIndex = index;
// 告诉子组件,开始转动了
this.$refs.roundTurntable.rotate(index);
},
// 已经转动完转盘触发的函数
endRotation() {
// 提示中奖
message.success(`恭喜您获奖啦,您的奖品是;${this.prizeData[this.prizeIndex].level}`);
// 解锁
this.isLocking = false;
},
// 判断是否可以转动
canBeRotated() {
if (this.num <= 0) {
alert('已经木有次数啦!');
return false;
}
if (this.isLocking) {
return false;
}
return true;
}
}
};
</script>
<style lang="scss">
.turntableBox {
position: relative;
width: 300px;
height: 300px;
.RoundTurntableImg {
width: 50px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 10;
cursor: pointer;
}
}
.turntable {
position: absolute;
// left: calc(50% - 145px);
// top: calc(50% - -10px);
width: 300px;
height: 300px;
}
.turntable-name {
/*background: pink;*/
position: absolute;
left: 10px;
top: 20px;
width: calc(100% - 20px);
font-size: 14px;
text-align: center;
// color: #fff;
color: aqua;
}
.turntable-img {
position: relative;
/*要居中就要50% - 宽度 / 2*/
left: calc(70% - 100px / 2);
top: 40px;
width: 60px;
height: 60px;
img {
display: inline-block;
width: 60%;
height: 60%;
}
}
</style>
</style>
@/view/luckDraw/RoundTurntable 代码
<template>
<div class="turntable" ref="turntable">
<div class="myTurntable" :style="{transform: rotateAngle, transition: rotateTransition}">
<canvas id="canvas" ref="canvas">
当前浏览器版本过低,请使用其他浏览器尝试
</canvas>
<div>
</div>
<div class="prize-container">
<div v-for="(item, index) in prizeData" :key="index" class="item" :style="getRotateAngle(index)">
<slot name="item" :item="item"></slot>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'round-turntable',
mounted() {
this.init();
},
props: {
prizeData: {
required: true
},
rotateCircle: {
default: 6
},
turntableStyleOption: {
default: () => {
return {
// 背景色
prizeBgColors: ['#ffdfd4', '#fffdfe', '#ffdfd4', '#fffdfe', '#ffdfd4', '#fffdfe', '#ffdfd4', '#fffdfe'],
// 转盘的外边框颜色
borderColor: '#f9dc84'
};
}
},
duringTime: {
default: 4.5
}
},
data() {
return {
// 开始转动的角度
startRotateDegree: 0,
rotateAngle: 0,
rotateTransition: ''
};
},
methods: {
// 根据index计算每一格要旋转的角度的样式
getRotateAngle(index) {
const angle = 360 / this.prizeData.length * index + (180 / this.prizeData.length);
return {
transform: `rotate(${angle}deg)`
};
},
// 初始化圆形转盘canvas
init() {
// 各种数据
const data = this.turntableStyleOption;
const prizeNum = this.prizeData.length;
const {
prizeBgColors,
borderColor
} = data;
// 开始绘画
const canvas = this.$refs.canvas;
const ctx = canvas.getContext('2d');
const canvasW = this.$refs.canvas.width = this.$refs.turntable.clientWidth; // 画板的高度
const canvasH = this.$refs.canvas.height = this.$refs.turntable.clientHeight; // 画板的宽度
// translate方法重新映射画布上的 (0,0) 位置
ctx.translate(0, canvasH);
// rotate方法旋转当前的绘图,因为文字适合当前扇形中心线垂直的!
ctx.rotate(-90 * Math.PI / 180);
// 圆环的外圆的半径
const outRadius = canvasW / 2;
// 圆环的内圆的半径
const innerRadius = 0;
const baseAngle = Math.PI * 2 / prizeNum; // 计算每个奖项所占角度数
ctx.clearRect(0, 0, canvasW, canvasH); // 去掉背景默认的黑色
ctx.strokeStyle = borderColor; // 设置画图线的颜色
for (let index = 0; index < prizeNum; index++) {
const angle = index * baseAngle;
ctx.fillStyle = prizeBgColors[index]; // 设置每个扇形区域的颜色
ctx.beginPath(); // 开始绘制
// 标准圆弧:arc(x,y,radius,startAngle,endAngle,anticlockwise)
ctx.arc(canvasW * 0.5, canvasH * 0.5, outRadius, angle, angle + baseAngle, false);
ctx.arc(canvasW * 0.5, canvasH * 0.5, innerRadius, angle + baseAngle, angle, true);
ctx.stroke(); // 开始链线
ctx.fill(); // 填充颜色
ctx.save(); // 保存当前环境的状态
}
},
// 转动起来
rotate(index) {
// 运转时长
const duringTime = this.duringTime;
const rotateAngle = this.startRotateDegree + this.rotateCircle * 360 + 360 - (180 / this.prizeData.length +
360 / this.prizeData.length * index) - this.startRotateDegree % 360;
this.startRotateDegree = rotateAngle;
this.rotateAngle = `rotate(${rotateAngle}deg)`;
this.rotateTransition = `transform ${duringTime}s cubic-bezier(0.250, 0.460, 0.455, 0.995)`;
setTimeout(() => {
this.$emit('endRotation');
}, duringTime * 1000 + 500);
}
}
};
</script>
<style scoped lang="scss">
.turntable {
.myTurntable {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.prize-container {
position: absolute;
left: 25%;
top: 0;
width: 50%;
height: 50%;
.item {
/*background: pink;*/
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
transform-origin: center bottom;
}
}
}
</style>