当前位置:首页 > JavaScript

js实现抽奖大圆盘

2026-01-30 19:07:03JavaScript

实现思路

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

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
分享给朋友:

相关文章

jquery.js

jquery.js

jQuery 简介 jQuery 是一个快速、简洁的 JavaScript 库,用于简化 HTML 文档遍历、事件处理、动画设计和 Ajax 交互。它的设计宗旨是“Write Less, Do Mor…

js实现vue路由

js实现vue路由

Vue路由基础实现 使用Vue Router实现前端路由需要先安装并配置路由库。Vue Router是Vue.js官方的路由管理器。 安装Vue Router: npm install vue-r…

js实现轮播

js实现轮播

实现轮播图的基本思路 轮播图的核心逻辑是通过定时切换展示的图片或内容,通常结合左右滑动按钮和指示器(小圆点)增强交互性。以下是基于原生JavaScript的实现方法。 HTML结构 构建轮播图的HT…

js实现分页

js实现分页

分页的基本实现思路 在JavaScript中实现分页功能通常需要结合前端和后端逻辑。前端负责渲染分页控件和处理用户交互,后端负责提供分页数据。 前端分页实现 纯前端分页适用于数据量较小的情况,可以…

js实现倒计时

js实现倒计时

使用 setInterval 实现倒计时 通过 setInterval 定时器每秒更新剩余时间,适用于简单倒计时场景。 function countdown(seconds, callbac…

js实现全选

js实现全选

实现全选功能的方法 在JavaScript中实现全选功能通常涉及监听全选复选框的点击事件,并根据其状态控制其他复选框的选中状态。以下是几种常见的实现方式: 基础DOM操作实现 通过获取所有目标复选…