当前位置:首页 > JavaScript

js实现抽奖大圆盘

2026-01-30 19:07:03JavaScript

实现思路

通过HTML5 Canvas绘制圆盘,使用JavaScript控制旋转动画和结果判定。核心逻辑包括绘制扇形区域、添加文字、旋转动画及停止后的结果回调。

js实现抽奖大圆盘

HTML结构

<div class="wheel-container">
  <canvas id="wheelCanvas" width="400" height="400"></canvas>
  <button id="spinBtn">开始抽奖</button>
</div>

CSS样式

.wheel-container {
  position: relative;
  width: 400px;
  margin: 0 auto;
}
#wheelCanvas {
  display: block;
  margin: 20px auto;
}
#spinBtn {
  display: block;
  margin: 10px auto;
  padding: 10px 20px;
  background: #ff4757;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

JavaScript实现

const canvas = document.getElementById('wheelCanvas');
const ctx = canvas.getContext('2d');
const spinBtn = document.getElementById('spinBtn');
const prizes = ['一等奖', '二等奖', '三等奖', '谢谢参与', '再来一次', '优惠券'];
const colors = ['#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF', '#FF9F40'];
let currentRotation = 0;
let isSpinning = false;

// 绘制圆盘
function drawWheel() {
  const centerX = canvas.width / 2;
  const centerY = canvas.height / 2;
  const radius = Math.min(centerX, centerY) - 10;
  const arcAngle = (2 * Math.PI) / prizes.length;

  prizes.forEach((prize, index) => {
    ctx.beginPath();
    ctx.fillStyle = colors[index % colors.length];
    ctx.moveTo(centerX, centerY);
    ctx.arc(centerX, centerY, radius, index * arcAngle, (index + 1) * arcAngle);
    ctx.fill();

    // 添加文字
    ctx.save();
    ctx.translate(centerX, centerY);
    ctx.rotate(index * arcAngle + arcAngle / 2);
    ctx.textAlign = 'right';
    ctx.fillStyle = '#fff';
    ctx.font = '16px Arial';
    ctx.fillText(prize, radius - 20, 10);
    ctx.restore();
  });
}

// 旋转动画
function spin() {
  if (isSpinning) return;
  isSpinning = true;

  const spinDuration = 3000 + Math.random() * 2000;
  const startTime = Date.now();
  const startRotation = currentRotation;
  const targetRotation = startRotation + 10 + Math.random() * 20;

  function animate() {
    const now = Date.now();
    const progress = Math.min((now - startTime) / spinDuration, 1);
    const easeProgress = easeOut(progress);
    currentRotation = startRotation + (targetRotation - startRotation) * easeProgress;

    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.save();
    ctx.translate(canvas.width / 2, canvas.height / 2);
    ctx.rotate(currentRotation);
    ctx.translate(-canvas.width / 2, -canvas.height / 2);
    drawWheel();
    ctx.restore();

    if (progress < 1) {
      requestAnimationFrame(animate);
    } else {
      isSpinning = false;
      const prizeIndex = determinePrize();
      alert(`恭喜获得: ${prizes[prizeIndex]}`);
    }
  }

  requestAnimationFrame(animate);
}

// 缓动函数
function easeOut(t) {
  return 1 - Math.pow(1 - t, 3);
}

// 确定获奖结果
function determinePrize() {
  const normalizedRotation = ((currentRotation % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI);
  const arcAngle = (2 * Math.PI) / prizes.length;
  return Math.floor((2 * Math.PI - normalizedRotation) / arcAngle) % prizes.length;
}

// 初始化
drawWheel();
spinBtn.addEventListener('click', spin);

功能扩展建议

  1. 添加指针元素:在圆盘中心绘制固定指针
  2. 音效支持:旋转时添加音效,停止时播放提示音
  3. 结果高亮:停止后高亮显示获奖区域
  4. 数据动态配置:通过API获取奖品列表
  5. 移动端适配:添加触摸事件支持

注意事项

  1. 旋转动画使用requestAnimationFrame实现流畅效果
  2. 通过缓动函数使旋转呈现先快后慢的效果
  3. 角度计算需处理2π的周期性
  4. 文字绘制时需要进行坐标系变换
  5. 禁止重复点击防止动画冲突

标签: 圆盘js
分享给朋友:

相关文章

js实现图片轮播

js实现图片轮播

实现基础图片轮播 使用HTML、CSS和JavaScript创建一个简单的图片轮播。HTML部分定义轮播容器和图片,CSS设置样式和动画效果,JavaScript处理轮播逻辑。 <div cl…

js实现列表

js实现列表

使用 JavaScript 实现列表 JavaScript 提供了多种方式来实现列表功能,包括数组操作、DOM 元素动态生成等。以下是几种常见的实现方法: 使用数组存储列表数据 数组是 JavaSc…

js 实现链表

js 实现链表

链表的基本概念 链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。与数组不同,链表在内存中是非连续存储的,插入和删除操作效率较高。 链表的实现 在 JavaScrip…

js类实现

js类实现

使用类实现 JavaScript 功能 在 JavaScript 中,类(Class)是一种语法糖,基于原型继承机制。通过 class 关键字可以更直观地定义对象模板。 基本类定义 class…

js实现防洪

js实现防洪

防抖(Debounce)实现 防抖的核心思想是在事件触发后延迟执行回调函数,若在延迟时间内再次触发事件,则重新计时。适用于输入框搜索、窗口调整等场景。 function debounce(func,…

js实现自举

js实现自举

实现 JavaScript 自举的方法 JavaScript 自举(Bootstrap)通常指通过 JavaScript 动态加载自身或依赖的脚本,实现运行时环境的初始化或扩展。以下是几种常见实现方式…