uniapp小程序转盘抽奖代码
以下是一个简单的uniapp小程序转盘抽奖代码示例:
- 在template中添加转盘和抽奖按钮:
<template>
<view>
<canvas canvas-id="myCanvas"></canvas>
<button @click="startLottery">{{btnText}}</button>
</view>
</template>
- 在script中添加相关变量和方法:
<script>
export default {
data() {
return {
btnText: '开始抽奖',
startAngle: 0,
endAngle: 0,
prizeIndex: 0,
isLottery: false,
prizes: ['奖品1', '奖品2', '奖品3', '奖品4', '奖品5', '奖品6', '奖品7', '奖品8'],
};
},
mounted() {
this.drawLottery();
},
methods: {
drawLottery() {
// 绘制转盘
// ...
},
startLottery() {
if (this.isLottery) {
return;
}
this.isLottery = true;
this.btnText = '抽奖中...';
const min = 5; // 最小的圈数
const max = 10; // 最大的圈数
const round = Math.floor(Math.random() * (max - min + 1)) + min;
this.prizeIndex = Math.floor(Math.random() * this.prizes.length);
const prizeAngle = 360 / this.prizes.length;
this.startAngle = 0;
this.endAngle = round * 360 + (this.prizeIndex + 0.5) * prizeAngle;
this.rotate();
},
rotate() {
// 转盘旋转动画
// ...
},
lotteryComplete() {
this.isLottery = false;
this.btnText = '再次抽奖';
uni.showToast({
title: `恭喜你获得${this.prizes[this.prizeIndex]}`,
icon: 'none',
});
},
},
};
</script>
- 实现转盘绘制和旋转动画的方法:
drawLottery() {
const ctx = uni.createCanvasContext('myCanvas', this);
const width = uni.upx2px(750);
const height = uni.upx2px(750);
const radius = 0.9 * width / 2;
const center = { x: width / 2, y: height / 2 };
const prizeAngle = 360 / this.prizes.length;
ctx.translate(center.x, center.y);
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI);
ctx.setFillStyle('#FFDAB9');
ctx.fill();
ctx.save();
for (let i = 0; i < this.prizes.length; i++) {
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.arc(0, 0, radius, i * prizeAngle * Math.PI / 180, (i + 1) * prizeAngle * Math.PI / 180);
ctx.closePath();
ctx.setFillStyle(i % 2 === 0 ? '#FFC125' : '#FFA500');
ctx.fill();
ctx.beginPath();
ctx.setFontSize(uni.upx2px(30));
ctx.setFillStyle('#FFFFFF');
ctx.setTextAlign('center');
ctx.setTextBaseline('middle');
ctx.translate(0, -0.6 * radius);
ctx.rotate((i + 0.5) * prizeAngle * Math.PI / 180);
ctx.fillText(this.prizes[i], 0, 0);
ctx.rotate(-(i + 0.5) * prizeAngle * Math.PI / 180);
ctx.translate(0, 0.6 * radius);
}
ctx.restore();
ctx.draw();
},
rotate() {
const ctx = uni.createCanvasContext('myCanvas', this);
const duration = 5000; // 转盘旋转的时间
let startTime = 0;
let lastTime = 0;
let rotateAngle = 0;
const animate = () => {
const currentTime = Date.now();
if (lastTime === 0) {
lastTime = currentTime;
}
const deltaTime = currentTime - lastTime;
if (deltaTime > 0) {
rotateAngle = this.startAngle + (this.endAngle - this.startAngle) * (currentTime - startTime) / duration;
ctx.rotate(rotateAngle * Math.PI / 180);
ctx.draw();
lastTime = currentTime;
}
if (currentTime - startTime < duration) {
requestAnimationFrame(animate);
} else {
this.startAngle = rotateAngle % 360;
this.endAngle = 0;
this.lotteryComplete();
}
};
requestAnimationFrame(() => {
startTime = Date.now();
animate();
});
},
- 最后,可以在style中设置canvas的宽高:
<style>
canvas {
width: 750upx;
height: 750upx;
}
</style>
完整代码示例:(仅供参考,具体实现方式可能会有所不同)
<template>
<view>
<canvas canvas-id="myCanvas"></canvas>
<button @click="startLottery">{{btnText}}</button>
</view>
</template>
<script>
export default {
data() {
return {
btnText: '开始抽奖',
startAngle: 0,
endAngle: 0,
prizeIndex: 0,
isLottery: false,
prizes: ['奖品1', '奖品2', '奖品3', '奖品4', '奖品5', '奖品6', '奖品7', '奖品8'],
};
},
mounted() {
this.drawLottery();
},
methods: {
drawLottery() {
const ctx = uni.createCanvasContext('myCanvas', this);
const width = uni.upx2px(750);
const height = uni.upx2px(750);
const radius = 0.9 * width / 2;
const center = { x: width / 2, y: height / 2 };
const prizeAngle = 360 / this.prizes.length;
ctx.translate(center.x, center.y);
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI);
ctx.setFillStyle('#FFDAB9');
ctx.fill();
ctx.save();
for (let i = 0; i < this.prizes.length; i++) {
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.arc(0, 0, radius, i * prizeAngle * Math.PI / 180, (i + 1) * prizeAngle * Math.PI / 180);
ctx.closePath();
ctx.setFillStyle(i % 2 === 0 ? '#FFC125' : '#FFA500');
ctx.fill();
ctx.beginPath();
ctx.setFontSize(uni.upx2px(30));
ctx.setFillStyle('#FFFFFF');
ctx.setTextAlign('center');
ctx.setTextBaseline('middle');
ctx.translate(0, -0.6 * radius);
ctx.rotate((i + 0.5) * prizeAngle * Math.PI / 180);
ctx.fillText(this.prizes[i], 0, 0);
ctx.rotate(-(i + 0.5) * prizeAngle * Math.PI / 180);
ctx.translate(0, 0.6 * radius);
}
ctx.restore();
ctx.draw();
},
startLottery() {
if (this.isLottery) {
return;
}
this.isLottery = true;
this.btnText = '抽奖中...';
const min = 5;
const max = 10;
const round = Math.floor(Math.random() * (max - min + 1)) + min;
this.prizeIndex = Math.floor(Math.random() * this.prizes.length);
const prizeAngle = 360 / this.prizes.length;
this.startAngle = 0;
this.endAngle = round * 360 + (this.prizeIndex + 0.5) * prizeAngle;
this.rotate();
},
rotate() {
const ctx = uni.createCanvasContext('myCanvas', this);
const duration = 5000;
let startTime = 0;
let lastTime = 0;
let rotateAngle = 0;
const animate = () => {
const currentTime = Date.now();
if (lastTime === 0) {
lastTime = currentTime;
}
const deltaTime = currentTime - lastTime;
if (deltaTime > 0) {
rotateAngle = this.startAngle + (this.endAngle - this.startAngle) * (currentTime - startTime) / duration;
ctx.rotate(rotateAngle * Math.PI / 180);
ctx.draw();
lastTime = currentTime;
}
if (currentTime - startTime < duration) {
requestAnimationFrame(animate);
} else {
this.startAngle = rotateAngle % 360;
this.endAngle = 0;
this.lotteryComplete();
}
};
requestAnimationFrame(() => {
startTime = Date.now();
animate();
});
},
lotteryComplete() {
this.isLottery = false;
this.btnText = '再次抽奖';
uni.showToast({
title: `恭喜你获得${this.prizes[this.prizeIndex]}`,
icon: 'none',
});
},
},
};
</script>
<style>
canvas {
width: 750upx;
height: 750upx;
}
</style>
原文地址: http://www.cveoy.top/t/topic/6fy 著作权归作者所有。请勿转载和采集!