Canvas 实现一个大转盘(幸运之轮)

抛砖引玉喽!!!

使用 Canvas 开发一个大转盘(幸运之轮)的界面是一个很有趣的事情!下面是一个简单的步骤指南,帮助你逐步实现这个项目:地址:github.com/itc-1118/wh...

第一步:设置 Canvas 元素

在 HTML 文件中创建一个包裹 Canvas 元素的容器,并设置样式。

html 复制代码
<div class="canvas-wrapper">
    <!-- 大轮盘 -->
   <canvas id="myCanvas" width="500" height="500"></canvas>
    <!-- 幸运指针 😄 -->
   <canvas id="pointerCanvas" width="500" height="500"></canvas>
</div>
<!-- 金手指 -->
<button id="spinButton">开始旋转</button>

第二步:绘制转盘

绘制一个圆形作为转盘的底座,在圆形上绘制扇形来表示转盘的各个部分,给每个扇形添加不同的颜色或图片来增加视觉效果。

javascript 复制代码
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

 // 绘制幸运之轮的背景
 this.ctx.beginPath();
 this.ctx.arc(250, 250, 200, 0, 2 * Math.PI);
 this.ctx.fillStyle = "lightgray";
 this.ctx.fill();
 this.ctx.closePath();

 // 绘制每个扇区
 let startAngle = 0;
 let endAngle = Math.PI / 3;
 for (let i = 0; i < this.config.sectors.length; i++) {
   this.ctx.beginPath();
   this.ctx.moveTo(250, 250);
   this.ctx.arc(250, 250, 200, startAngle, endAngle);
   this.ctx.closePath();
   this.ctx.fillStyle = this.config.sectors[i];
   this.ctx.fill();
   startAngle = endAngle;
   endAngle += Math.PI / 3;
 }

第三步:绘制指针

绘制一个指针来指示最终停止的位置,可以是一个简单的三角形或其他形状。

javascript 复制代码
this.pointerCtx.clearRect(
   0,
   0,
   this.pointerCanvas.width,
   this.pointerCanvas.height
 );
 this.pointerCtx.beginPath();
 this.pointerCtx.moveTo(250, 50);
 this.pointerCtx.lineTo(230, 150);
 this.pointerCtx.lineTo(270, 150);
 this.pointerCtx.fillStyle = "black";
 this.pointerCtx.fill();
 this.pointerCtx.closePath();

第四步:添加交互性

实现转盘的旋转效果。

  • 可以使用 CSS 或 JavaScript 来实现动画效果。
  • 添加事件监听器,使得点击按钮时转盘可以开始旋转,并在旋转停止时指示中奖位置。
javascript 复制代码
   /**
    * 开始旋转幸运之轮
    * 检查是否已经在旋转中,如果没有,则禁用按钮并计算旋转目标角度。
    */
  startSpin() {
    if (!this.isSpinning) {
      this.isSpinning = true;
      this.spinButton.disabled = true;
      // 计算旋转目标角度
      const targetRotation =
        this.config.targetSectorIndex * (Math.PI / 3) +
        this.config.spinCycles * 2 * Math.PI;
      this.rotateToTarget(targetRotation);
    }
  }

  /**
   * 旋转幸运之轮到目标角度
   * @param {number} targetRotation - 目标旋转角度(弧度)
   */
  rotateToTarget(targetRotation) {
    this.startRotationTime = performance.now();
    this.spinWheel(targetRotation);
  }

  /**
   * 旋转幸运之轮
   * @param {number} targetRotation - 目标旋转角度(弧度)
   */
  spinWheel(targetRotation) {
    const { totalSpinTime } = this.config;
    const currentTime = performance.now();
    const elapsedTime = currentTime - this.startRotationTime;
    const t = Math.min(1, elapsedTime / totalSpinTime);

    // 使用缓动函数计算当前旋转角度
    this.rotationAngle = this.easeOutQuad(t) * targetRotation;

    // 应用旋转并重绘幸运之轮
    this.canvas.style.transform = `rotate(${this.rotationAngle}rad)`;
    this.drawWheel();

    // 如果尚未达到目标旋转角度,则继续请求动画帧
    if (elapsedTime < totalSpinTime) {
      requestAnimationFrame(() => this.spinWheel(targetRotation));
    } else {
      // 完成旋转后启用按钮并重置状态
      this.canvas.style.transform = `rotate(${targetRotation}rad)`;
      this.isSpinning = false;
      this.spinButton.disabled = false;
    }
  }

  /**
   * 缓动函数,用于平滑动画效果
   * @param {number} t - 进度
   * @returns {number} 缓动后的值
   */
  easeOutQuad(t) {
    return t * (2 - t);
  }

第五步:处理逻辑

  1. 确定转盘各个部分的奖品。
  2. 编写逻辑来确定指针最终停在哪个奖品上。
  3. 根据指针停留位置给出相应的奖品信息。

步骤5,根据具体的业务实现,这个简单的示例,你可以根据需要进一步扩展和改进代码,使得你的转盘界面更加丰富和有趣。

相关推荐
Mintopia3 分钟前
Three.js 射线拾取原理:像素世界的侦探故事
前端·javascript·计算机图形学
Qiuner15 分钟前
【源力觉醒 创作者计划】开源、易用、强中文:文心一言4.5或是 普通人/非AI程序员 的第一款中文AI?
人工智能·百度·开源·文心一言·gitcode
掘金安东尼22 分钟前
前端周刊第421期(2025年7月1日–7月6日)
前端·面试·github
摸鱼仙人~24 分钟前
深入理解 classnames:React 动态类名管理的最佳实践
前端·react.js·前端框架
未来之窗软件服务26 分钟前
chrome webdrive异常处理-session not created falled opening key——仙盟创梦IDE
前端·人工智能·chrome·仙盟创梦ide·东方仙盟·数据调式
kymjs张涛27 分钟前
零一开源|前沿技术周报 #6
前端·ios·harmonyos
玲小珑30 分钟前
Next.js 教程系列(十)getStaticPaths 与动态路由的静态生成
前端·next.js
天天鸭36 分钟前
写个vite插件自动处理系统权限,降低99%重复工作
前端·javascript·vite
蓝婷儿41 分钟前
每天一个前端小知识 Day 23 - PWA 渐进式 Web 应用开发
前端
无奈何杨1 小时前
CoolGuard风控中新增移动距离和移动速度指标
前端·后端