react实现抽奖功能
实现抽奖功能的基本思路
抽奖功能通常包括奖品展示、抽奖动画、中奖结果展示等模块。React的组件化开发模式非常适合实现这类交互功能。
基础抽奖组件结构
创建基础的抽奖组件结构:
import React, { useState } from 'react';
const Lottery = ({ prizes }) => {
const [isRolling, setIsRolling] = useState(false);
const [result, setResult] = useState(null);
return (
<div className="lottery-container">
<div className="prizes-display">
{prizes.map((prize, index) => (
<div key={index} className="prize-item">
{prize.name}
</div>
))}
</div>
<button
onClick={handleDraw}
disabled={isRolling}
>
{isRolling ? '抽奖中...' : '开始抽奖'}
</button>
{result && (
<div className="result-modal">
恭喜获得: {result.name}
</div>
)}
</div>
);
};
抽奖动画实现
使用CSS动画或JavaScript定时器实现抽奖动画效果:
const handleDraw = () => {
setIsRolling(true);
setResult(null);
// 模拟抽奖动画
const animationDuration = 3000; // 3秒
const startTime = Date.now();
const timer = setInterval(() => {
const elapsed = Date.now() - startTime;
if (elapsed >= animationDuration) {
clearInterval(timer);
setIsRolling(false);
const winnerIndex = Math.floor(Math.random() * prizes.length);
setResult(prizes[winnerIndex]);
}
}, 100);
};
权重控制抽奖
如果需要按权重抽奖,可添加概率计算:

const getWeightedRandom = (items) => {
const totalWeight = items.reduce((sum, item) => sum + (item.weight || 1), 0);
let random = Math.random() * totalWeight;
for (const item of items) {
if (random < item.weight) return item;
random -= item.weight;
}
return items[items.length - 1];
};
// 使用方式
const winner = getWeightedRandom(prizes);
转盘抽奖实现
对于转盘式抽奖,可使用CSS transform和动画:
const Wheel = ({ segments }) => {
const [rotation, setRotation] = useState(0);
const [spinning, setSpinning] = useState(false);
const spin = () => {
setSpinning(true);
const spinDuration = 5000; // 5秒
const rotations = 5; // 旋转5圈
const targetAngle = 360 * rotations + (360 / segments.length) * Math.floor(Math.random() * segments.length);
setRotation(prev => prev + targetAngle);
setTimeout(() => {
setSpinning(false);
// 计算最终奖项
}, spinDuration);
};
return (
<div
className="wheel"
style={{
transform: `rotate(${rotation}deg)`,
transition: spinning ? `transform ${spinDuration/1000}s cubic-bezier(0.1, 0.7, 0.1, 1)` : 'none'
}}
>
{segments.map((segment, i) => (
<div
key={i}
className="segment"
style={{
transform: `rotate(${i * (360 / segments.length)}deg)`,
backgroundColor: segment.color
}}
>
{segment.name}
</div>
))}
</div>
);
};
九宫格抽奖实现
九宫格抽奖的常见实现方式:

const GridLottery = ({ items }) => {
const [activeIndex, setActiveIndex] = useState(null);
const [result, setResult] = useState(null);
const draw = () => {
let current = 0;
const totalSteps = 20; // 跑动格子数
const speed = 100; // 初始速度ms
const animate = () => {
setActiveIndex(current % items.length);
current++;
if (current < totalSteps) {
setTimeout(animate, speed + current * 10); // 减速效果
} else {
const winnerIndex = Math.floor(Math.random() * items.length);
setResult(items[winnerIndex]);
}
};
animate();
};
return (
<div className="grid-container">
{items.map((item, i) => (
<div
key={i}
className={`grid-item ${activeIndex === i ? 'active' : ''}`}
>
{item.name}
</div>
))}
<button onClick={draw}>开始抽奖</button>
</div>
);
};
优化与注意事项
抽奖结果应确保随机性,避免可预测性。对于重要抽奖活动,建议结合后端随机算法。
动画性能优化可考虑使用requestAnimationFrame代替setTimeout。
移动端适配需要注意触摸事件和响应式布局。
重要抽奖活动应记录抽奖日志,确保可追溯和审计。






