实现思路
- 状态管理:使用
useState
来管理动画的不同阶段状态,例如 isSlidingIn
表示是否正在从左侧滑入,isPaused
表示是否处于停顿阶段,isScaling
表示是否正在放大,isRotating
表示是否正在旋转。
- 动画触发条件:可以通过某个事件(如按钮点击)来触发动画序列。当触发事件发生时,设置
isSlidingIn
为 true
,从而开始动画序列。
- 控制动画顺序和时间间隔:利用
useEffect
钩子函数来监听状态变化。当 isSlidingIn
变为 true
时,开始左侧滑入动画。在滑入动画结束后(可以通过 animationend
事件监听),设置 isPaused
为 true
,并通过 setTimeout
在2秒后将 isPaused
设置为 false
且 isScaling
设置为 true
。同理,在放大动画结束后,设置 isRotating
为 true
开始旋转动画。
- 动画实现:使用CSS的
@keyframes
规则定义各个动画,通过 useRef
获取DOM元素并应用相应的动画类名。
关键代码
import React, { useState, useEffect, useRef } from'react';
import './styles.css';
const AnimationComponent = () => {
const [isSlidingIn, setIsSlidingIn] = useState(false);
const [isPaused, setIsPaused] = useState(false);
const [isScaling, setIsScaling] = useState(false);
const [isRotating, setIsRotating] = useState(false);
const elementRef = useRef(null);
const startAnimation = () => {
setIsSlidingIn(true);
};
useEffect(() => {
const handleAnimationEnd = (e) => {
if (e.target === elementRef.current) {
if (isSlidingIn) {
setIsSlidingIn(false);
setIsPaused(true);
setTimeout(() => {
setIsPaused(false);
setIsScaling(true);
}, 2000);
} else if (isScaling) {
setIsScaling(false);
setIsRotating(true);
}
}
};
if (elementRef.current) {
elementRef.current.addEventListener('animationend', handleAnimationEnd);
}
return () => {
if (elementRef.current) {
elementRef.current.removeEventListener('animationend', handleAnimationEnd);
}
};
}, [isSlidingIn, isScaling]);
return (
<div>
<button onClick={startAnimation}>开始动画</button>
<div
ref={elementRef}
className={`animated-element ${isSlidingIn? 'slide-in' : ''} ${isPaused? 'paused' : ''} ${isScaling? 'scale' : ''} ${isRotating? 'rotate' : ''}`}
/>
</div>
);
};
export default AnimationComponent;
CSS代码(styles.css)
.animated-element {
width: 100px;
height: 100px;
background-color: blue;
}
@keyframes slide-in {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
@keyframes scale {
from {
transform: scale(1);
}
to {
transform: scale(1.5);
}
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.slide-in {
animation: slide-in 1s forwards;
}
.paused {
animation-play-state: paused;
}
.scale {
animation: scale 1s forwards;
}
.rotate {
animation: rotate 2s forwards;
}