实现目标
image.png
旁边的不管,是贴图,主要是中心区域:
1、先用ctx.arc画出扇形并填充颜色
2、在相应的扇形内填充奖品的图片和文字
3、 控制转盘能在指定奖品id的时候能旋转到相应的扇形区域
- 画出扇形
关键代码
let canvasW = canvas.width // 画板的高度
let canvasH = canvas.height // 画板的宽度
let colors = ['RGBA(255, 243, 211, 1)', 'RGBA(255, 250, 237, 1)']
//计算每个奖项所占角度数,以弧度计
let baseAngle = (Math.PI * 2) / this.prizeList.length // this.prizeList是我的奖品数组
for (let index = 0; index < this.prizeList.length; index++) {
ctx.save()
let angle = index * baseAngle
ctx.beginPath() //开始绘制
ctx.arc(
canvasW * 0.5,
canvasH * 0.5,
0,
angle,
angle + baseAngle,
false
)
// 把开始绘制弧线的位置移到12点钟方向并绘制弧线
ctx.arc(
canvasW * 0.5,
canvasH * 0.5,
240,
baseAngle * index - Math.PI / 2 - baseAngle / 2,
baseAngle * (index + 1) - Math.PI / 2 - baseAngle / 2,
false
)
// ctx.lineTo ( canvasW * 0.5 , canvasW * 0.5 );
if (index % 2 == 0) {
ctx.fillStyle = colors[0] //设置每个扇形区域的颜色
} else {
ctx.fillStyle = colors[1] //设置每个扇形区域的颜色
}
ctx.stroke() //开始链线
ctx.fill() //填充颜色
ctx.restore()
}
- 填充相应文字和图片
for (let index = 0; index < this.prizeList.length; index++) {
let angle = index * baseAngle
let img = new Image()
img.src = this.prizeList[index].image
let that = this
img.onload = function() {
ctx.save()
ctx.beginPath()
//把画布移到中心。240是我的半径
ctx.translate(240, 240)
//rotate方法旋转当前的绘图
ctx.rotate(angle)
// 填充文字和图片 具体的位置看自己的设计稿
ctx.fillText(that.prizeList[index].name, 0, -217)
ctx.fillText(that.prizeList[index].remark, 0, -194)
ctx.drawImage(img, -50, -180, 100, 100)
ctx.closePath()
ctx.restore()
}
}
- 控制转盘 见下列全部代码
<template>
<div class="turntable-pages">
<div ref="turntable" class="turntable" :style="rotateRound">
<!-- <div
v-for="(item, index) in prizeList"
:class="'prize prize' + index"
:key="index"
>
<p>{{ item.name }}</p>
<p>{{ item.value }}花瓣</p>
<img :src="item.img" alt="" />
</div> -->
<canvas id="wheelCanvas" width="480px" height="480px"
>抱歉!浏览器不支持。</canvas
>
</div>
<img
src="../images/turntable_pointer@2x.png"
alt=""
class="turntable-btn"
@click="startTurntable"
/>
</div>
</template>
<script>
export default {
props: {
prizeList: {
type: Array,
default: () => [],
},
winPrize: {
type: Object,
default: () => {},
},
toRotate: {
type: Boolean,
default: false,
},
},
data() {
return {
prizeNum: 6, //奖品摆放数量
}
},
filters: {
// 处理超长名字
formatName(name, len) {
return name.length >= len ? name.slice(0, len) + '...' : name
},
},
computed: {
//控制转盘转到准确位置
rotateRound() {
if (this.toRotate) {
const count = this.prizeList.findIndex(
item => item.id === this.winPrize.prizeId
)
let num = 360 - count * (360 / this.prizeList.length)
return {
transform: `rotate(${360 * 3 + num}deg)`,
transition: 'all 5s',
}
} else {
return {}
}
},
},
watch: {
prizeList(val) {
if (val.length > 0) {
this.drawing()
}
},
},
mounted() {
this.$refs.turntable.addEventListener(
'webkitTransitionEnd',
this.init,
false
)
this.drawing()
},
methods: {
//开启转盘
startTurntable() {
// 去修改this.toRotate的值为true,并请求后端抽奖的结果
this.$emit('startTurn')
},
//弹出中奖弹框
init() {
this.$emit('showPrizePopup')
},
// 绘图
drawing() {
let canvas = document.getElementById('wheelCanvas')
let ctx = canvas.getContext('2d')
let canvasW = canvas.width // 画板的高度
let canvasH = canvas.height // 画板的宽度
//计算每个奖项所占角度数,以弧度计
let baseAngle = (Math.PI * 2) / this.prizeList.length
ctx.clearRect(0, 0, canvasW, canvasH) //去掉背景默认的黑色
ctx.strokeStyle = 'RGBA(249, 228, 178, 1)' //设置画图线的颜色
ctx.font = '22px PingFangSC-Semibold' //设置字号字体
let colors = ['RGBA(255, 243, 211, 1)', 'RGBA(255, 250, 237, 1)']
// let colors = ['#fff', '#000']
for (let index = 0; index < this.prizeList.length; index++) {
ctx.save()
let angle = index * baseAngle
// let angle = 0 * baseAngle
ctx.beginPath() //开始绘制
ctx.arc(
canvasW * 0.5,
canvasH * 0.5,
0,
angle,
angle + baseAngle,
false
)
// 把开始绘制弧线的位置移到12点钟方向并绘制弧线
ctx.arc(
canvasW * 0.5,
canvasH * 0.5,
240,
baseAngle * index - Math.PI / 2 - baseAngle / 2,
baseAngle * (index + 1) - Math.PI / 2 - baseAngle / 2,
false
)
// ctx.lineTo ( canvasW * 0.5 , canvasW * 0.5 );
if (index % 2 == 0) {
ctx.fillStyle = colors[0] //设置每个扇形区域的颜色
} else {
ctx.fillStyle = colors[1] //设置每个扇形区域的颜色
}
ctx.stroke() //开始链线
ctx.fill() //填充颜色
ctx.restore()
}
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'
ctx.fillStyle = 'rgba(255, 67, 93, 1)'
for (let index = 0; index < this.prizeList.length; index++) {
let angle = index * baseAngle
let img = new Image()
img.src = this.prizeList[index].image
let that = this
img.onload = function() {
ctx.save()
ctx.beginPath()
//把画布移到中心
ctx.translate(240, 240)
//rotate方法旋转当前的绘图
ctx.rotate(angle)
// 填充文字和图片
ctx.fillText(that.prizeList[index].name, 0, -217)
ctx.fillText(that.prizeList[index].remark, 0, -194)
ctx.drawImage(img, -50, -180, 100, 100)
ctx.closePath()
ctx.restore()
}
}
},
},
}
</script>
<style lang="scss" scoped>
.turntable-pages {
position: absolute;
width: 680px;
height: 680px;
top: 266px;
left: 50%;
transform: translateX(-50%);
font-family: PingFang SC;
.turntable-btn {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 121px;
height: 136px;
}
.turntable {
width: 680px;
height: 680px;
position: relative;
background: url('../images/turntable.png') no-repeat;
background-size: 100% 100%;
.prize {
position: absolute;
width: 474px;
height: 474px;
top: 50%;
left: 50%;
border-radius: 50%;
text-align: center;
// margin-top: 5px;
transform: translate(-50%, -50%);
p {
text-align: center;
font-size: 22px;
font-weight: 600;
color: #ff435d;
margin-top: 4px;
&:first-child {
margin-top: 10px;
}
}
img {
width: 96px;
height: 96px;
}
}
#wheelCanvas {
position: absolute;
top: 50.5%;
left: 50%;
transform: translate(-50%, -50%);
width: 474px;
height: 474px;
border-radius: 50%;
}
}
}
</style>
网友评论