纯 CSS 动画实现(简单,但交互性有限)
这种方法适合制作一个自动播放、无法手动控制的转盘。

HTML 结构
创建一个圆形的转盘,并把它分成多个扇形区域,每个区域可以是一个 <div>,里面包含奖品名称。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">纯CSS转盘</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="wheel-container">
<div class="wheel">
<div class="segment segment-1">一等奖</div>
<div class="segment segment-2">二等奖</div>
<div class="segment segment-3">三等奖</div>
<div class="segment segment-4">谢谢参与</div>
<div class="segment segment-5">再来一次</div>
<div class="segment segment-6">幸运奖</div>
</div>
</div>
</body>
</html>
CSS 样式
关键点在于:
.wheel设置为圆形 (border-radius: 50%),并设置transform-origin: center以确保旋转围绕中心点。.segment使用绝对定位 (position: absolute),并通过transform: rotate()和skew()来将矩形元素扭曲成扇形。- 使用
@keyframes定义旋转动画。
/* style.css */
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f0f0f0;
margin: 0;
}
.wheel-container {
position: relative;
width: 300px;
height: 300px;
}
.wheel {
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #ddd;
position: relative;
overflow: hidden;
animation: spin 10s linear infinite; /* 自动旋转动画 */
}
.segment {
position: absolute;
width: 50%;
height: 50%;
transform-origin: right bottom; /* 关键:设置旋转原点为右下角 */
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
color: white;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
}
/* 扇形扭曲和颜色 */
.segment-1 { transform: rotate(0deg) skew(-60deg); background-color: #FF6384; }
.segment-2 { transform: rotate(60deg) skew(-60deg); background-color: #36A2EB; }
.segment-3 { transform: rotate(120deg) skew(-60deg); background-color: #FFCE56; }
.segment-4 { transform: rotate(180deg) skew(-60deg); background-color: #4BC0C0; }
.segment-5 { transform: rotate(240deg) skew(-60deg); background-color: #9966FF; }
.segment-6 { transform: rotate(300deg) skew(-60deg); background-color: #FF9F40; }
/* 文字需要反向扭曲以保持水平 */
.segment span {
transform: skew(60deg) rotate(-30deg); /* 根据扇形角度调整 */
position: absolute;
left: 20px;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
缺点:这种方法无法通过 JavaScript 动态控制停止的位置和角度,交互性很差。
JavaScript + CSS Transform 实现(推荐,功能强大)
这是最常用和最灵活的方法,我们用一个指针来指示中奖结果,通过 JavaScript 动态控制转盘的旋转角度。

HTML 结构
增加一个指针和按钮。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">JS控制转盘</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>幸运大转盘</h1>
<div class="wheel-wrapper">
<!-- 指针 -->
<div class="pointer"></div>
<!-- 转盘主体 -->
<div class="wheel" id="wheel">
<div class="segment" data-prize="一等奖">一等奖</div>
<div class="segment" data-prize="二等奖">二等奖</div>
<div class="segment" data-prize="三等奖">三等奖</div>
<div class="segment" data-prize="谢谢参与">谢谢参与</div>
<div class="segment" data-prize="再来一次">再来一次</div>
<div class="segment" data-prize="幸运奖">幸运奖</div>
</div>
</div>
<button id="spinBtn">开始旋转</button>
<div id="result"></div>
<script src="script.js"></script>
</body>
</html>
CSS 样式
与方案一类似,但需要调整指针和转盘的样式,确保指针在转盘上方且指向中心。
/* style.css */
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f0f0f0;
margin: 0;
font-family: sans-serif;
}
.wheel-wrapper {
position: relative;
width: 300px;
height: 300px;
margin-bottom: 30px;
}
.wheel {
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #ddd;
position: relative;
overflow: hidden;
border: 8px solid #333;
transition: transform 4s cubic-bezier(0.17, 0.67, 0.12, 0.99); /* 关键:平滑过渡效果 */
}
.segment {
position: absolute;
width: 50%;
height: 50%;
transform-origin: right bottom;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
color: white;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
}
.segment span {
transform: skew(60deg) rotate(-30deg);
position: absolute;
left: 20px;
}
/* ... (其他 segment 的样式同方案一) */
.segment-1 { transform: rotate(0deg) skew(-60deg); background-color: #FF6384; }
.segment-2 { transform: rotate(60deg) skew(-60deg); background-color: #36A2EB; }
.segment-3 { transform: rotate(120deg) skew(-60deg); background-color: #FFCE56; }
.segment-4 { transform: rotate(180deg) skew(-60deg); background-color: #4BC0C0; }
.segment-5 { transform: rotate(240deg) skew(-60deg); background-color: #9966FF; }
.segment-6 { transform: rotate(300deg) skew(-60deg); background-color: #FF9F40; }
/* 指针样式 */
.pointer {
position: absolute;
top: -15px;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 30px solid #ff0000;
z-index: 10;
}
button {
padding: 10px 20px;
font-size: 18px;
cursor: pointer;
}
#result {
margin-top: 20px;
font-size: 24px;
font-weight: bold;
color: #333;
height: 30px; /* 给结果一个固定高度,避免布局跳动 */
}
JavaScript 逻辑(核心)
这是控制转盘的关键,逻辑如下:
- 获取元素:获取转盘、按钮、结果提示等 DOM 元素。
- 定义奖品和角度:创建一个数组,存储每个奖品对应的角度范围。
- 点击事件:为按钮添加点击事件监听器。
- 计算旋转角度:
- 随机选择一个奖品。
- 计算该奖品对应的目标角度,为了让转盘多转几圈,目标角度 =
360 * n (圈数) + 目标扇形中心角度。 - 为了防止连续点击,在旋转开始时禁用按钮,旋转结束后再启用。
- 应用旋转:使用
element.style.transform = 'rotate(Xdeg)'来旋转转盘。 - 显示结果:在旋转结束后,显示中奖结果。
// script.js
document.addEventListener('DOMContentLoaded', () => {
const wheel = document.getElementById('wheel');
const spinBtn = document.getElementById('spinBtn');
const resultDiv = document.getElementById('result');
const prizes = [
{ name: '一等奖', angle: 0 },
{ name: '二等奖', angle: 60 },
{ name: '三等奖', angle: 120 },
{ name: '谢谢参与', angle: 180 },
{ name: '再来一次', angle: 240 },
{ name: '幸运奖', angle: 300 }
];
const prizeCount = prizes.length;
const anglePerPrize = 360 / prizeCount;
let isSpinning = false;
spinBtn.addEventListener('click', () => {
if (isSpinning) return; // 防止重复点击
isSpinning = true;
spinBtn.disabled = true;
resultDiv.textContent = '';
// 1. 随机选择一个奖品
const winningIndex = Math.floor(Math.random() * prizeCount);
const winningPrize = prizes[winningIndex];
// 2. 计算目标角度
// 指针指向顶部,对应0度,为了让某个奖品停在指针下,
// 转盘需要旋转的角度是 (360 - 奖品的起始角度) + 奖品扇形的一半角度。
// 为了多转几圈,我们加上 360 * 5 (5圈)
const extraSpins = 5; // 额外旋转的圈数
const targetAngle = 360 * extraSpins + (360 - winningPrize.angle + anglePerPrize / 2);
// 3. 应用旋转
wheel.style.transform = `rotate(${targetAngle}deg)`;
// 4. 旋转结束后显示结果
setTimeout(() => {
resultDiv.textContent = `恭喜你中得: ${winningPrize.name}!`;
isSpinning = false;
spinBtn.disabled = false;
}, 4000); // 4秒后显示结果,与CSS过渡时间匹配
});
});
使用 Canvas 或 SVG 实现(更灵活,适合复杂图形)
如果你的转盘设计非常复杂,比如每个扇形有自己的图片、渐变色或者动态效果,使用 Canvas 或 SVG 会更合适。

Canvas 示例思路
- HTML: 创建一个
<canvas>元素。 - JavaScript:
- 获取
canvas的 2D 上下文 (getContext('2d'))。 - 使用
canvas的 API 绘制圆形和扇形 (arc,moveTo,lineTo,fill)。 - 绘制文字。
- 旋转:通过
translate移动坐标原点到画布中心,然后使用rotate旋转整个画布,再绘制转盘。 - 动画:使用
requestAnimationFrame在每一帧中清除画布、更新旋转角度、重新绘制,实现平滑动画。
- 获取
SVG 示例思路
- HTML: 使用 SVG 的
<circle>,<path>,<text>等元素构建转盘。<path>可以轻松绘制扇形。
- JavaScript:
- 通过
document.querySelector()或document.getElementById()获取 SVG 元素或其内部的扇形、文字元素。 - 控制方式与方案二类似,可以直接操作 SVG 元素的
transform属性,或者操作<g>(分组) 元素来实现整个转盘的旋转,SVG 的transform属性同样支持rotate函数。
- 通过
总结与对比
| 特性 | 方案一 (纯CSS) | 方案二 (JS+CSS Transform) | 方案三 (Canvas/SVG) |
|---|---|---|---|
| 实现难度 | 简单 | 中等 | 较高 |
| 交互控制 | 极差 | 优秀 | 优秀 |
| 性能 | 优秀 | 优秀 | 复杂图形时可能稍差 |
| 灵活性 | 低 | 高 | 极高 |
| 适用场景 | 装饰性、自动播放的动画 | 绝大多数抽奖、游戏场景 | 复杂图形、动态数据可视化、游戏 |
对于绝大多数“控制网页转盘”的需求,方案二(JavaScript + CSS Transform)是最佳选择,它在易用性、性能和灵活性之间取得了完美的平衡。
