简介
在这篇文章中,我们将学习如何使用 HTML5 和 JavaScript 来实现一个幸运大转盘的抽奖效果。这个转盘能够模拟现实中的幸运转盘抽奖机制,通过点击按钮,用户能够看到不同奖品的抽取结果。接下来,我们将逐步分析代码,看看如何实现这一功能。
效果展示
在这个幸运大转盘中,玩家可以通过点击“GO”按钮触发转盘的旋转,并最终抽取一个奖品。转盘上的每个奖品都有不同的概率,最终的奖品会通过一个漂亮的闪烁效果呈现给用户。

功能介绍
1.转盘绘制:
- 使用 HTML5 Canvas 来绘制转盘的轮廓和奖品扇形。
- 每个奖品区域会用不同的颜色显示,并且会显示奖品的图标和名称。
2.奖品设置:
- 每个奖品都有一个名字和图片,且不同奖品的出现概率不同。
3.转盘旋转:
- 点击“GO”按钮时,转盘开始旋转,并且最终选中一个奖品。
- 转盘旋转时,采用闪烁效果,使最终的奖品更加突出。
4.结果显示:
- 旋转结束后,会弹出一个模态框显示中奖的奖品,包括奖品名称和图片。
代码分析
<body>
<!-- 轮盘 -->
<h1>幸运大转盘</h1>
<div class="wheel-container">
<canvas id="wheelCanvas" width="500" height="500"></canvas>
<button class="go-button" id="goButton">GO</button>
</div>
<!-- 结果弹窗 -->
<div class="modal" id="resultModal">
<div class="modal-content">
<span class="close-button" id="closeModal">×</span>
<h2>恭喜!</h2>
<img id="prizeImage" class="prize-image" src="" alt="奖品图片">
<p id="prizeText"></p>
</div>
</div>
<script>
const canvas = document.getElementById('wheelCanvas');
const ctx = canvas.getContext('2d');
const goButton = document.getElementById('goButton');
const modal = document.getElementById('resultModal');
const closeModal = document.getElementById('closeModal');
const prizeText = document.getElementById('prizeText');
// 奖品配置(name奖品名称,probability:概率,pic:图片信息)
const prizes = [
{ name: "宝马", probability: 12.00, pic:'../Image/drawWheel/1.png' },
{ name: "兰博基尼", probability: 10.00, pic:'../Image/drawWheel/2.png' },
{ name: "烈焰头饰", probability: 20.00, pic:'../Image/drawWheel/3.png'},
{ name: "冰雪头饰", probability: 8.00, pic:'../Image/drawWheel/4.png' },
{ name: "代金券", probability: 3.00, pic:'../Image/drawWheel/6.png' },
{ name: "宝石", probability: 25.50, pic:'../Image/drawWheel/7.png' },
{ name: "金币", probability: 5.00, pic:'../Image/drawWheel/8.png' },
{ name: "礼包", probability: 0.50, pic:'../Image/drawWheel/9.png' },
{ name: "Miss", probability: 6, pic:'../Image/drawWheel/10.png' },
{ name: "再来一次", probability: 6.00, pic:'../Image/drawWheel/11.png' },
];
const normalColors = ['#FFD700', '#FF4500']; // 金色和橙红色
const highlightColors = ['#FFE44D', '#FF6347']; // 亮金色和亮橙红色
const radius = 240;//轮盘半径
const centerX = canvas.width / 2;//轮盘中心x坐标
const centerY = canvas.height / 2;//轮盘中心y坐标
let isSpinning = false;//是否正在旋转
let highlightedIndex = -1;//当前高亮显示的奖品索引
// 预加载图片
const images = prizes.map(prize => {
const img = new Image();
img.src = prize.pic;
return img;
});
// 绘制转盘
function drawWheel() {
ctx.clearRect(0, 0, canvas.width, canvas.height);//清除画布
const anglePerPrize = (Math.PI * 2) / prizes.length;//每个扇形的角度
prizes.forEach((prize, index) => {
const startAngle = index * anglePerPrize;//每个扇形的起始角度
const endAngle = (index + 1) * anglePerPrize;//每个扇形的结束角度
// 绘制扇形
ctx.beginPath();//开始绘制路径
ctx.moveTo(centerX, centerY);//移动到中心点
ctx.arc(centerX, centerY, radius, startAngle, endAngle);//绘制弧线
ctx.closePath();//关闭路径
// 判断是否需要高亮显示
if (index === highlightedIndex) {
ctx.fillStyle = highlightColors[index % 2];//设置高亮颜色
} else {
ctx.fillStyle = normalColors[index % 2];//设置正常颜色
}
ctx.fill();//填充
// 绘制图片
ctx.save();//保存当前状态
ctx.translate(centerX, centerY);//移动到中心点
ctx.rotate(startAngle + anglePerPrize / 2);//旋转
// 计算图片位置和大小
const imgSize = 60; // 图片大小
const imgDistance = radius * 0.7; // 图片距离中心的距离
// 绘制图片,确保图片已加载
if (images[index].complete) {
// 保存当前旋转状态
ctx.save();
// 反向旋转,抵消扇形的旋转,使图片保持垂直
ctx.rotate(-(startAngle + anglePerPrize / 2));
// 计算图片在扇形中的位置
const x = Math.cos(startAngle + anglePerPrize / 2) * imgDistance;//计算图片在扇形中的x坐标
const y = Math.sin(startAngle + anglePerPrize / 2) * imgDistance;//计算图片在扇形中的y坐标
ctx.drawImage(
images[index],//图片
x - imgSize / 2,//图片x坐标
y - imgSize / 2,//图片y坐标
imgSize,//图片宽度
imgSize//图片高度
);
// 绘制奖品名称
ctx.font = '14px Arial';//设置字体
ctx.fillStyle = '#FFFFFF';//设置文字颜色
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';//设置阴影颜色
ctx.shadowBlur = 4;//设置阴影模糊度
ctx.shadowOffsetX = 2;//设置阴影偏移量
ctx.shadowOffsetY = 2;//设置阴影偏移量
ctx.textAlign = 'center';//设置文字对齐方式
ctx.textBaseline = 'middle';//设置文字基线
// 文字位置在图片下方
ctx.fillText(
prize.name, //奖品名称
x,
y + imgSize/2 + 12
);
// 清除阴影效果
ctx.shadowColor = 'transparent';//阴影颜色
ctx.shadowBlur = 0;//阴影模糊度
ctx.shadowOffsetX = 0;//阴影偏移量
ctx.shadowOffsetY = 0;//阴影偏移量
// 恢复旋转状态
ctx.restore();//恢复旋转状态
}
ctx.restore();//恢复旋转状态
});
// 绘制中心圆形遮罩
ctx.beginPath();//开始绘制路径
ctx.arc(centerX, centerY, 50, 0, Math.PI * 2);//绘制圆形
ctx.fillStyle = '#2d2d2d';//设置填充颜色
ctx.fill();//填充
}
// 根据概率获取奖品
function getRandomPrize() {
const random = Math.random() * 100;//随机数
let probabilitySum = 0;//概率总和
for (let i = 0; i < prizes.length; i++) {//遍历奖品
probabilitySum += prizes[i].probability;//累加概率
if (random <= probabilitySum) {//如果随机数小于等于概率总和
return i;//返回奖品索引
}
}
return prizes.length - 1;//返回最后一个奖品索引
}
// 亮起一圈
function lightUpOneRound(prizeIndex, callback) {
let currentIndex = 0;
const speed = 100; // 每个扇形亮起的时间间隔
function lightUp() {
if (currentIndex >= prizes.length) {//如果当前索引大于等于奖品数量
callback();//回调函数
return;
}
highlightedIndex = currentIndex;//当前高亮显示的奖品索引
drawWheel();
currentIndex++;
setTimeout(lightUp, speed);
}
lightUp();//亮起一圈
}
// 最终奖品闪烁效果
function flashFinalPrize(index) {
let flashCount = 0;
const maxFlashes = 5; // 闪烁次数
const flashSpeed = 200; // 闪烁间隔时间
function flash() {
if (flashCount >= maxFlashes * 2) {
highlightedIndex = index; // 最后保持高亮
drawWheel();
isSpinning = false;
goButton.disabled = false;
// 显示中奖信息和图片
const prizeImage = document.getElementById('prizeImage');
prizeImage.src = prizes[index].pic;
prizeText.textContent = `您获得了:${prizes[index].name}`;
modal.style.display = 'block';
return;
}
highlightedIndex = flashCount % 2 === 0 ? index : -1;
drawWheel();
flashCount++;
setTimeout(flash, flashSpeed);
}
flash();
}
// 开始抽奖
function spin() {
if (isSpinning) return;//如果正在旋转,则返回
isSpinning = true;//设置正在旋转
goButton.disabled = true;//禁用按钮
// 随机选择奖品
const prizeIndex = getRandomPrize();//随机选择奖品
// 先亮一圈,然后显示最终结果
lightUpOneRound(prizeIndex, () => {
// 短暂暗下来
highlightedIndex = -1;
drawWheel();
// 延迟一下再显示最终结果
setTimeout(() => {
flashFinalPrize(prizeIndex);
}, 500);
});
}
// 等待所有图片加载完成后初始化
let loadedImages = 0;
images.forEach(img => {
img.onload = () => {
loadedImages++;
if (loadedImages === images.length) {
drawWheel();
}
};
});
// 事件监听
goButton.addEventListener('click', spin);
closeModal.addEventListener('click', () => {
modal.style.display = 'none';
});
window.addEventListener('click', (event) => {
if (event.target === modal) {
modal.style.display = 'none';
}
});
</script>
</body>
核心功能详解:
绘制转盘:使用Canvas API绘制转盘,并根据奖品的数量与分布绘制相应的扇形区域。
转盘旋转:通过设置旋转角度和利用setTimeout控制旋转的速度,实现转盘的旋转动画。
随机奖品抽取:通过 Math.random 生成随机数,按照奖品的概率分配机制,决定最终的中奖结果。
总结
通过HTML5和JavaScript的结合,我们实现了一个简单而有趣的幸运大转盘游戏。用户可以通过点击按钮触发转盘旋转,并显示最终的奖品。这个项目展示了如何使用Canvas API绘制图形,以及如何实现旋转动画和随机奖品抽取功能。

8530

被折叠的 条评论
为什么被折叠?



