简单的思路
<div class="ball" />
.ball {
width: 50px;
height: 50px;
border-radius: 50%;
left: 100px;
top: 300px;
animation: move 2s infinite;
background: red;
position: relative;
}
@keyframes move {
to {
transform: translate(100px, 500px);
}
}
如果只是简单粗暴地添加 translate
属性,那么动画的效果是不尽人意。
动作分解
抛物线可以把它看作是两个方向的运动,首先一个是水平方向匀速移动,第二是竖直方向自由落体移动。
尝试两个动画
@keyframes moveX {
to {
transform: translateX(100px);
}
}
@keyframes moveY {
to {
transform: translateY(500px);
}
}
.ball {
animation:
moveX 2s linear infinite,
moveY 2s linear infinite;
}
可以看到,动画已经变形了。因为这两个动画都改变了transform,导致了相互影响。本来 moveX 是横向移动100个像素,而 transform 又改动了,不横向移动了,又变成纵向移动500个像素,相互冲突。
尝试两个元素
将小球作为子元素,父元素负责水平方向的移动,子元素负责竖直方向的移动。
<div class="ball">
<div class="inner" />
</div>
.ball {
position: fixed;
width: 50px;
height: 50px;
border-radius: 50%;
border: 1px dashed #aaa;
left: 100px;
top: 300px;
animation: moveX 2s linear infinite;
}
.inner {
background: #fc5e56;
width: 100%;
height: 100%;
border-radius: 50%;
animation: moveY 2s linear infinite;
}
@keyframes moveX {
to {
transform: translateX(100px);
}
}
@keyframes moveY {
to {
transform: translateY(500px);
}
}
可以看到,带有虚线边框的父元素带着子元素水平方向移动,随后子元素竖直方向移动。
带点优化
.inner {
background: #fc5e56;
width: 100%;
height: 100%;
border-radius: 50%;
animation: moveParabola 2s ease-in-out infinite;
}
@keyframes moveX {
to {
transform: translateX(100px);
}
}
@keyframes moveParabola {
0% {
transform: translateY(0);
}
50% {
transform: translateY(-100px); /* 顶点,向上运动 */
}
100% {
transform: translateY(360px); /* 回到起始高度 */
}
}