react实现卡片动画
React 实现卡片动画的方法
使用 CSS Transition 实现基础动画
在 React 组件中直接通过 CSS 的 transition 属性实现平滑动画效果。定义一个卡片组件,通过状态控制类名变化触发动画。
import React, { useState } from 'react';
import './Card.css';
function Card() {
const [isHovered, setIsHovered] = useState(false);
return (
<div
className={`card ${isHovered ? 'hovered' : ''}`}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
Card Content
</div>
);
}
配套 CSS 文件:
.card {
width: 200px;
height: 200px;
background: #fff;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
transition: all 0.3s ease;
}
.card.hovered {
transform: translateY(-5px);
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
使用 React Spring 实现物理动画
通过 react-spring 库实现更复杂的物理动画效果,支持弹簧动画、轨迹动画等高级特性。
import { useSpring, animated } from 'react-spring';
function SpringCard() {
const [active, setActive] = useState(false);
const styles = useSpring({
transform: active ? 'scale(1.05)' : 'scale(1)',
boxShadow: active
? '0 10px 20px rgba(0,0,0,0.2)'
: '0 2px 5px rgba(0,0,0,0.1)',
config: { mass: 1, tension: 300, friction: 15 }
});
return (
<animated.div
style={styles}
onMouseEnter={() => setActive(true)}
onMouseLeave={() => setActive(false)}
className="card"
>
Spring Card
</animated.div>
);
}
使用 Framer Motion 实现声明式动画
framer-motion 提供更简洁的声明式动画 API,支持手势动画和布局动画。
import { motion } from 'framer-motion';
function MotionCard() {
return (
<motion.div
className="card"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5 }}
>
Framer Motion Card
</motion.div>
);
}
实现卡片翻转效果
通过 3D 变换实现双面卡片翻转效果,结合 React 状态管理控制翻转状态。
function FlipCard() {
const [flipped, setFlipped] = useState(false);
return (
<div
className={`flip-card ${flipped ? 'flipped' : ''}`}
onClick={() => setFlipped(!flipped)}
>
<div className="flip-card-inner">
<div className="flip-card-front">
Front Content
</div>
<div className="flip-card-back">
Back Content
</div>
</div>
</div>
);
}
配套 CSS:
.flip-card {
perspective: 1000px;
width: 200px;
height: 200px;
}
.flip-card-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.6s;
transform-style: preserve-3d;
}
.flip-card.flipped .flip-card-inner {
transform: rotateY(180deg);
}
.flip-card-front, .flip-card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.flip-card-back {
transform: rotateY(180deg);
}
卡片入场动画
结合 React 生命周期或 Hooks 实现卡片列表的入场动画效果。
import { useEffect, useRef } from 'react';
function AnimatedList() {
const cards = [1, 2, 3, 4];
const refs = useRef([]);
useEffect(() => {
refs.current.forEach((el, i) => {
el.style.animation = `fadeIn 0.5s ease ${i * 0.1}s forwards`;
});
}, []);
return (
<div className="card-list">
{cards.map((card, i) => (
<div
key={card}
ref={el => refs.current[i] = el}
className="card"
style={{ opacity: 0 }}
>
Card {card}
</div>
))}
</div>
);
}
配套 CSS:
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.card-list .card {
margin-bottom: 10px;
}






