CSS结合贝塞尔函数将多个简单的动画堆叠创建更复杂的动画
- 技术交流
- 2024-09-25 20:31:01
我们每天都在网上冲浪,作为开发人员,我们往往会注意到网站上的微妙细节。我一直注意的一件事是网站上的动画有多流畅。动画非常适合 UX 和设计目的。您可以制作一个交互式网站,取悦访问者并让他们记住您的网站。
创建高级动画听起来像是一个困难的话题,但好消息是,在 CSS 中,您可以将多个简单的动画堆叠在一起以创建一个更复杂的动画!
在这篇博文中,您将了解以下内容:
什么是立方贝塞尔以及如何使用它们在一行 CSS 中创建“复杂”动画;
如何相互堆叠动画以创建高级动画;
如何通过应用您上面学到的两点来创建过山车动画。
注意:本文假定您具有 CSS 动画的基本知识。如果没有,请在继续阅读本文之前查看此链接。
立方贝济耶:它们是什么?
CSS 中的立方贝塞尔函数是一个缓动函数,可让您完全控制动画相对于时间的行为。以下是官方定义:
三次贝塞尔缓动函数是一种由四个实数定义的缓动函数,这些实数指定三次贝塞尔曲线的两个控制点 P1 和 P2,其端点 P0 和 P3 分别固定在 (0, 0) 和 (1, 1)。P1 和 P2 的 x 坐标限制在范围 [0, 1]。
注意:如果您想了解有关缓动函数的更多信息,可以查看本文。它揭示了线性、立方贝塞尔和楼梯功能的工作原理!
但什么是缓动函数?让我们从线性曲线开始
想象两个点 P0 和 P1,其中 P0 是动画的起点,P1 是终点。现在想象另一个点在两点之间线性移动,如下所示:
这就是所谓的线性曲线!它是最简单的动画,你可能在开始学习CSS之前用过它。
下一步:二次贝塞尔曲线
假设您有三个点:P0、P1 和 P2。您希望动画从 P0 移动到 P2。在这种情况下,P1 是控制动画曲线的控制点。
二次贝塞尔的思想如下:
连接 P0 和 P1 之间以及 P1 和 P2 之间的假想线(由灰线表示)。
点 Q0 沿 P0 和 P1 之间的线移动。同时,点 Q1 沿着 P1 和 P2 之间的线移动。
连接 Q0 和 Q1 之间的假想线(由绿线表示)。
在Q0和Q1开始移动的同时,B点开始沿着绿线移动。点 B 采用的路径是动画路径。
请注意,Q1、Q2 和 B 不会以相同的速度移动。他们必须同时开始,同时完成自己的道路。因此,每个点根据其移动的线长度以适当的速度移动。
最后:三次贝塞尔曲线
三次贝塞尔曲线由 4 个点组成:P0、P1、P2 和 P3。动画从 P0 开始,到 P3 结束。P1 和 P2 是我们的控制点。
三次贝塞尔的工作原理如下:
连接 (P0, P1)、(P1, P2) 和 (P2, P3) 之间的虚线。这由灰线表示。
点 Q0、Q1 和 Q2 分别沿线 (P0、P1)、(P1、P2) 和 (P2, P3) 移动。
连接 (Q0, Q1) 和 (Q1, Q2) 之间的虚线。它们由绿线表示。
点 R0 和 R1 分别沿线 (Q0, Q1) 和 (Q1, Q2) 移动。
连接 R0 和 R1 之间的线(由蓝线表示)。
最后,点 B 沿连接 R0 和 R1 之间的线移动。此点沿动画路径移动。
如果您想更好地了解立方贝济尔的工作原理,我建议您查看此 desmos 链接。使用控制点并检查动画如何随时间变化。(请注意,链接中的动画由黑线表示。
堆叠动画
具有许多步骤的大动画可以分解为多个小动画。您可以通过将动画延迟属性添加到 CSS 来实现这一点。计算延迟很简单;您将所有动画的时间相加,然后再计算其动画延迟。
例如:
animation: movePointLeft 4s linear forwards, movePointDown 3s linear forwards;
在这里,我们有两个动画,movePointLeft和movePointDown。movePointLeft 的动画延迟将为零,因为它是我们首先要运行的动画。但是,movePointDown 的动画延迟将为 4 秒,因为 movePointLeft 将在该时间之后完成。
因此,动画延迟属性将如下所示:
animation-delay: 0s, 4s;
请注意,如果同时启动两个或多个动画,则它们的动画延迟将相同。此外,在计算即将出现的动画的动画延迟时,会将它们视为一个动画。
例如:
animation: x 4s linear forwards, y 4s linear forwards, jump 2s linear forwards;
假设我们想同时启动 x 和 y。在这种情况下,x 和 y 的动画延迟将为零,而跳转动画的动画延迟将为 4 秒(而不是 8 秒!
animation-delay: 0s, 0s, 4s;
创造过山车
现在我们已经涵盖了基础知识,是时候应用我们学到的东西了!
了解动画
过山车路径由三部分组成:
滑动部分,
循环部分,
还将有一些动画在上面的两个动画之间创建水平空间。
设置事物
我们将首先创建一个简单的球,它将成为我们过山车的“推车”。
1. 将其添加到新 HTML 文件的正文中:
<div id="the-cart" ></div>
2. 将其添加到您的 CSS 文件中:
.cart {
background-color: rgb(100, 210, 128);
height: 50px;
width: 50px;
border: 1px solid black;
border-radius: 50px;
position: absolute;
left: 10vw;
top: 30vh;
}
我将使用视口宽度 (vw) 和视口高度 (vh) 属性来使动画响应。您可以自由使用任何您想要的单位。
滑动部分
创建可以使用立方贝塞尔函数完成球滑动的部分!动画由 2 个动画组成,一个沿 x 轴,另一个沿 y 轴。x 轴动画是沿 x 轴的法线动画。我们可以定义其关键帧如下:
@keyframes x {
to {
left: 40vw;
}
}
将其添加到球路径中的动画属性中,如下所示:
animation: x 4s linear forwards
y 轴动画是我们将使用立方贝塞尔函数的动画。让我们首先定义动画的关键帧。我们希望起点和终点之间的差异非常小,以至于球达到几乎相同的高度。
@keyframes y {
to {
top: 29.99vh;
}
}}
现在让我们考虑一下立方贝塞尔函数。我们希望我们的路径首先缓慢地向右移动,然后当它滑动时,它应该走得更快。
向右缓慢移动意味着 $P 1$ 将沿 x 轴移动。所以,我们知道它在(V,0)。我们需要选择一个合适的 V,使我们的动画缓慢地向右移动,但不要太多,以至于它占用整个空间。在这种情况下,我发现 0.55 最适合。
为了达到滑动效果,我们需要将 P2 向下移动 y 轴(负值),因此 P2=(X, -Y)。Y 应该是一个很大的值。在这种情况下,我选择了 Y=5000。为了得到 X,我们知道我们的动画速度在滑动时应该更快,在再次上升时应该更慢。因此,X 越接近零,动画在滑动时就越陡峭。在这种情况下,设 X = 0.8。
现在你有你的立方贝塞尔函数,它将是立方贝塞尔(0.55, 0, 0.2, -800)。
让我们将关键帧添加到动画属性中:
animation: x 4s linear forwards,
y 4s cubic-bezier(0.55, 0, 0.2, -5000) forwards;
这是我们动画的第一部分,因此动画延迟为零。我们应该添加一个 animation-delay 属性,因为从以下动画开始,动画将在与第一个动画不同的时间启动。
animation-delay: 0s, 0s;
添加水平空间
在进行循环之前,球应沿 x 轴移动一小段时间,以便两个动画之间留有空间。所以,让我们这样做吧!
定义关键帧:
@keyframes x2 {
to {
left: 50vw;
}
}
将其添加到动画属性:
animation: x 4s linear forwards,
y 4s cubic-bezier(0.55, 0, 0.2, -5000) forwards, x2 0.5s linear forwards;
此动画应在滑动动画之后开始,滑动动画需要四秒钟;因此,动画延迟将为四秒:
animation-delay: 0s, 0s, 4s;
循环部分
要在 CSS 中创建圆圈(循环),我们需要将圆移动到循环的中心并从那里开始动画。我们希望圆的半径为 100px,因此我们将圆的位置更改为顶部:20vh(30 是所需的半径(此处为 10vh))。但是,这需要在滑动动画完成后发生,因此我们将创建另一个持续时间为零的动画,并添加合适的动画延迟。
创建关键帧:
@keyframes pointOfCircle {
to {
top: 20vh;
}
}
将此添加到持续时间 = 0s 的动画列表中:
animation: x 4s linear forwards,
y 4s cubic-bezier(0.55, 0, 0.2, -5000) forwards, x2 0.5s linear forwards,
pointOfCircle 0s linear forwards;
添加动画延迟,即 4.5 秒:
animation-delay: 0s, 0s, 4s, 4.5s;
循环本身
要创建循环动画:
创建一个关键帧,将球移回旧位置,然后旋转球:
@keyframes loop {
from {
transform: rotate(0deg) translateY(10vh) rotate(0deg);
}
to {
transform: rotate(-360deg) translateY(10vh) rotate(360deg);
}
}
将循环关键帧添加到动画属性:
animation: x 4s linear forwards,
y 4s cubic-bezier(0.55, 0, 0.2, -5000) forwards, x2 0.5s linear forwards,
pointOfCircle 0s linear forwards, loop 3s linear forwards;
添加动画延迟,此处也将是 4.5 秒:
animation-delay: 0s, 0s, 4s, 4.5s, 4.5s;
快完成了!我们只需要在动画结束后沿 x 轴移动球,这样球就不会像上图中那样在循环后完全停止。
添加关键帧:
@keyframes x3 {
to {
left: 70vw;
}
}
将关键帧添加到动画属性:
animation: x 4s linear forwards,
y 4s cubic-bezier(0.55, 0, 0.2, -800) forwards, x2 0.5s linear forwards,
pointOfCircle 0s linear forwards, loop 3s linear forwards,
x3 2s linear forwards;
加上合适的延迟,这里将是 7.5 秒:
animation-delay: 0s, 0s, 4s, 4.5s, 4.5s, 7.5s;
在本文中,我们介绍了如何组合多个关键帧来创建复杂的动画路径。我们还介绍了三次贝塞尔以及如何使用它们来创建自己的缓动函数。
CSS结合贝塞尔函数将多个简单的动画堆叠创建更复杂的动画由讯客互联技术交流栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“ CSS结合贝塞尔函数将多个简单的动画堆叠创建更复杂的动画”