react实现翻牌抽奖动画
实现翻牌抽奖动画的思路
翻牌抽奖动画的核心是卡片翻转效果,通常包含正面和反面两个状态。通过CSS 3D变换和React的状态管理,可以轻松实现这一效果。
基本组件结构
创建一个FlipCard组件,包含正面和反面两个子组件。使用transform-style: preserve-3d和rotateY实现3D翻转效果。
import React, { useState } from 'react';
import './FlipCard.css';
const FlipCard = ({ frontContent, backContent }) => {
const [isFlipped, setIsFlipped] = useState(false);
return (
<div className="flip-card-container">
<div className={`flip-card ${isFlipped ? 'flipped' : ''}`}>
<div className="flip-card-front">
{frontContent}
</div>
<div className="flip-card-back">
{backContent}
</div>
</div>
<button onClick={() => setIsFlipped(!isFlipped)}>
{isFlipped ? '翻回去' : '抽奖'}
</button>
</div>
);
};
export default FlipCard;
CSS样式实现
关键CSS样式需要定义3D变换和过渡效果:
.flip-card-container {
perspective: 1000px;
width: 200px;
height: 300px;
}
.flip-card {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform 0.6s;
}
.flip-card.flipped {
transform: rotateY(180deg);
}
.flip-card-front, .flip-card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
display: flex;
align-items: center;
justify-content: center;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
.flip-card-front {
background-color: #f8f8f8;
}
.flip-card-back {
background-color: #ff5722;
color: white;
transform: rotateY(180deg);
}
抽奖逻辑扩展
添加抽奖逻辑,随机选择奖品并在翻转后显示:
const prizes = [
'一等奖',
'二等奖',
'三等奖',
'谢谢参与'
];
const FlipLottery = () => {
const [result, setResult] = useState('');
const [isFlipped, setIsFlipped] = useState(false);
const drawLottery = () => {
if (!isFlipped) {
const randomIndex = Math.floor(Math.random() * prizes.length);
setResult(prizes[randomIndex]);
setIsFlipped(true);
} else {
setIsFlipped(false);
}
};
return (
<div className="flip-card-container">
<div className={`flip-card ${isFlipped ? 'flipped' : ''}`}>
<div className="flip-card-front">
<h2>点击抽奖</h2>
</div>
<div className="flip-card-back">
<h2>{result}</h2>
</div>
</div>
<button onClick={drawLottery}>
{isFlipped ? '再来一次' : '开始抽奖'}
</button>
</div>
);
};
动画优化
添加更流畅的动画效果和交互反馈:
.flip-card {
transition: transform 0.6s cubic-bezier(0.4, 0.0, 0.2, 1);
}
button {
margin-top: 20px;
padding: 10px 20px;
background: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background 0.3s;
}
button:hover {
background: #45a049;
}
多卡片布局
如果需要展示多个可翻转卡片,可以创建一个卡片网格:
const PrizeGrid = () => {
const [cards, setCards] = useState(
Array(9).fill().map((_, i) => ({
id: i,
flipped: false,
prize: prizes[Math.floor(Math.random() * prizes.length)]
}))
);
const flipCard = (id) => {
setCards(cards.map(card =>
card.id === id ? {...card, flipped: !card.flipped} : card
));
};
return (
<div className="prize-grid">
{cards.map(card => (
<div key={card.id} className="grid-item">
<div className={`flip-card ${card.flipped ? 'flipped' : ''}`}>
<div className="flip-card-front" onClick={() => flipCard(card.id)}>
<h3>?</h3>
</div>
<div className="flip-card-back">
<h3>{card.prize}</h3>
</div>
</div>
</div>
))}
</div>
);
};
对应的网格样式:
.prize-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
max-width: 800px;
margin: 0 auto;
}
.grid-item {
perspective: 1000px;
width: 100%;
height: 150px;
}
这些实现方式提供了从基础到进阶的翻牌抽奖动画解决方案,可以根据具体需求进行调整和扩展。







