当前位置:首页 > JavaScript

js实现抽奖转盘效果

2026-04-04 11:06:58JavaScript

实现抽奖转盘效果

抽奖转盘通常由旋转动画和结果判定两部分组成。以下是一个基于Canvas和JavaScript的实现方案:

js实现抽奖转盘效果

初始化Canvas和转盘绘制

const canvas = document.getElementById('wheel');
const ctx = canvas.getContext('2d');
const segments = ['一等奖', '二等奖', '三等奖', '谢谢参与', '再来一次'];
const colors = ['#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF'];
const center = { x: canvas.width/2, y: canvas.height/2 };
const radius = Math.min(canvas.width, canvas.height)/2 - 10;

function drawWheel() {
    const arcAngle = (2 * Math.PI) / segments.length;

    segments.forEach((segment, index) => {
        ctx.beginPath();
        ctx.fillStyle = colors[index];
        ctx.moveTo(center.x, center.y);
        ctx.arc(center.x, center.y, radius, 
                index * arcAngle, (index + 1) * arcAngle);
        ctx.lineTo(center.x, center.y);
        ctx.fill();

        // 绘制文本
        ctx.save();
        ctx.translate(center.x, center.y);
        ctx.rotate(index * arcAngle + arcAngle/2);
        ctx.textAlign = 'right';
        ctx.fillStyle = '#fff';
        ctx.font = '16px Arial';
        ctx.fillText(segment, radius - 10, 5);
        ctx.restore();
    });
}

实现旋转动画

let currentRotation = 0;
let isSpinning = false;

function spin() {
    if(isSpinning) return;

    isSpinning = true;
    const spinTime = 3000; // 旋转总时间
    const startTime = Date.now();
    const targetRotation = currentRotation + 10 + Math.random() * 20;

    function animate() {
        const elapsed = Date.now() - startTime;
        const progress = Math.min(elapsed / spinTime, 1);
        const easeOut = 1 - Math.pow(1 - progress, 3);
        currentRotation = easeOut * targetRotation;

        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.save();
        ctx.translate(center.x, center.y);
        ctx.rotate(currentRotation);
        ctx.translate(-center.x, -center.y);
        drawWheel();
        ctx.restore();

        if(progress < 1) {
            requestAnimationFrame(animate);
        } else {
            isSpinning = false;
            determineResult();
        }
    }

    requestAnimationFrame(animate);
}

function determineResult() {
    const normalizedRotation = currentRotation % (2 * Math.PI);
    const segmentAngle = (2 * Math.PI) / segments.length;
    const winningIndex = Math.floor(
        (2 * Math.PI - normalizedRotation) / segmentAngle
    ) % segments.length;

    alert(`恭喜获得: ${segments[winningIndex]}`);
}

HTML结构

<canvas id="wheel" width="400" height="400"></canvas>
<button onclick="spin()">开始抽奖</button>

CSS样式

#wheel {
    display: block;
    margin: 0 auto;
    background: #f5f5f5;
    border-radius: 50%;
    box-shadow: 0 0 10px rgba(0,0,0,0.2);
}

button {
    display: block;
    margin: 20px auto;
    padding: 10px 20px;
    font-size: 16px;
    background: #4CAF50;
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
}

完整实现步骤

  1. 初始化Canvas并设置尺寸
  2. 定义奖项和对应颜色
  3. 绘制转盘扇形区域和文字
  4. 实现旋转动画使用requestAnimationFrame
  5. 添加缓动函数使旋转更自然
  6. 计算最终停止位置确定获奖结果
  7. 添加开始按钮触发旋转

优化建议

  1. 添加指针指示器
  2. 实现多次旋转惯性效果
  3. 增加音效增强体验
  4. 使用图片替代纯色扇形
  5. 添加开始/停止动画的过渡效果

这个实现使用了Canvas绘制和JavaScript动画基础,可以根据需要调整转盘大小、奖项数量和旋转时间等参数。

标签: 转盘效果
分享给朋友:

相关文章

h5页面滑动效果实现

h5页面滑动效果实现

实现H5页面滑动效果的方法 H5页面滑动效果可以通过多种方式实现,包括原生JavaScript、CSS动画或第三方库。以下是几种常见的方法: 使用CSS Scroll Snap CSS Scroll…

vue实现开关效果

vue实现开关效果

使用Vue实现开关效果 使用v-model绑定数据 通过v-model绑定一个布尔值来控制开关状态。当用户点击开关时,布尔值会自动更新。 <template> <div cla…

vue实现tab效果

vue实现tab效果

Vue 实现 Tab 效果的方法 使用动态组件和 v-if 通过 v-if 或 v-show 控制不同标签内容的显示与隐藏,结合点击事件切换当前激活的标签页。 <template>…

vue实现过度效果

vue实现过度效果

Vue 过渡效果实现方法 Vue 提供了内置的 <transition> 和 <transition-group> 组件,用于在元素或组件进入/离开 DOM 时应用过渡效果。…

vue实现菜单效果

vue实现菜单效果

Vue实现菜单效果的方法 基础菜单实现 使用Vue的v-for指令和v-show/v-if可以快速实现基础菜单。通过数据驱动的方式渲染菜单项,结合事件处理实现交互。 <template>…

vue实现水印效果

vue实现水印效果

实现水印效果的几种方法 在Vue中实现水印效果可以通过多种方式,以下是几种常见的方法: 使用CSS背景图 通过CSS的background-image属性可以实现简单的水印效果。定义一个包含水印文本…