小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
先看一下效果图:
最近挺累的,搞一个小动画游戏,放松一下心情...
js代码
export default () => {
const [play, setPlay] = useState(false); // 动画是否运转
const [target, setTarget] = useState(0);
const handleStart = () => {
setPlay((paly) => !paly);
setTarget(0);
};
const handleItem = (i) => {
if (!play) return;
setPlay((paly) => !paly);
setTarget(i);
setTimeout(() => {
message.info('一等奖')
}, 800)
};
const animationStyle = {
animationPlayState: play ? 'running' : 'paused',
};
return (
<div className="wrap">
<div className="egg-content">
<div
className="egg-item transformStyle1"
style={animationStyle}
onClick={() => handleItem(1)}
>
<div className={`egg ${target === 1 && 'activeEgg'}`} />
<img
src={hammer}
className={`hammer ${target === 1 && 'hammerTransform'}`}
/>
</div>
<div
className="egg-item transformStyle2"
style={animationStyle}
onClick={() => handleItem(2)}
>
<div className={`egg ${target === 2 && 'activeEgg'}`} />
<img
src={hammer}
className={`hammer ${target === 2 && 'hammerTransform'}`}
/>
</div>
<div
className="egg-item transformStyle3"
style={animationStyle}
onClick={() => handleItem(3)}
>
<div className={`egg ${target === 3 && 'activeEgg'}`} />
<img
src={hammer}
className={`hammer ${target === 3 && 'hammerTransform'}`}
/>
</div>
</div>
<Row justify="center">
<Button type="primary" onClick={handleStart}>
{play ? 'pause' : 'start'}
</Button>
</Row>
</div>
);
};
css 代码
.wrap {
.egg-content {
height: 460px;
width: 600px;
background-color:cornsilk;
position: relative;
margin: 0 auto;
}
.egg-item {
position: absolute;
width: 200px;
height: 190px;
}
.egg {
height: 200px;
width: 190px;
background-image: url('../../../public/egg_1.png');
background-repeat: no-repeat;
background-size: contain;
}
.hammer {
position: absolute;
top: -80px,;
left: 50%;
height: 80px;
width: 70px;
visibility: hidden;
}
.transformStyle1 {
animation: animX 9s cubic-bezier(0.5, 0, 0.5, 1) -4.5s infinite alternate,
animY 9s cubic-bezier(0.5, 0, 0.5, 1) 0s infinite alternate,
scale 18s cubic-bezier(0.5, 0, 0.5, 1) 0s infinite alternate;
}
.transformStyle2 {
animation: animX 9s cubic-bezier(0.5, 0, 0.5, 1) -10.5s infinite alternate,
animY 9s cubic-bezier(0.5, 0, 0.5, 1) -6s infinite alternate,
scale 18s cubic-bezier(0.5, 0, 0.5, 1) -6s infinite alternate;
}
.transformStyle3 {
animation: animX 9s cubic-bezier(0.5, 0, 0.5, 1) -16.5s infinite alternate,
animY 9s cubic-bezier(0.5, 0, 0.5, 1) -12s infinite alternate,
scale 18s cubic-bezier(0.5, 0, 0.5, 1) -12s infinite alternate;
}
.hammerTransform {
visibility: visible;
transform: rotate(-45deg);
transform-origin: 80px 70px;
animation-name: hammer;
animation-timing-function: ease;
animation-duration: 0.5s;
}
.activeEgg {
background-image: url('../../../public/egg_2.png');
transition-property: background-image;
transition-delay: 0.3s;
}
}
// 小锤子动画
@keyframes hammer {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(-45deg);
}
}
@keyframes animX{
0% {left: 0px;}
100% {left: 400px;}
}
@keyframes animY{
0% {top: 50px;}
100% {top: 200px;}
}
@keyframes scale {
0% {
transform: scale(0.8);
z-index: 10
}
50% {
transform: scale(1);
z-index: 100;
}
100% {
transform: scale(0.8);
z-index: 10
}
}
动画效果解析
怎么让金蛋动起来?
- 将金蛋设置
positon: absolute
,使其脱离文档流,然后添加动画 - 水平(X轴)和垂直(Y轴)方向,即实时改变元素的
top
和left
- 在金蛋运动的过程中,改变金蛋的大小,改变元素的
scale
- 设置动画关键帧
@keyframes
- 设置
animation
.transformStyle1 { animation: animX 9s cubic-bezier(0.5, 0, 0.5, 1) -4.5s infinite alternate, animY 9s cubic-bezier(0.5, 0, 0.5, 1) 0s infinite alternate, scale 18s cubic-bezier(0.5, 0, 0.5, 1) 0s infinite alternate; }
动画属性:
animation-name
:animX
、animY
、scale
animation-duration
:9s
、9s
、18s
animation-timing-function
:cubic-bezier(0.5, 0, 0.5, 1)
(贝塞尔曲线)animation-delay
:-4.5s
、0s
、0s
animation-iteration-count
:infinite
(无限循环)animation-direction
:alternate
(动画交替反向运行)
动画时间计算
-
x和y轴的时间总和是 scale的时间
-
3个图x和y轴动画加起来是18s , 18s/3 等于 6s
-
每个球y轴动画延迟 从0递减6s,
-
x轴与y轴相差动画时长的一半(9s/2)
结语
如果这篇文章帮到了你,欢迎点赞👍和关注⭐️。
文章如有错误之处,希望在评论区指正🙏🙏。