在CSS动画中融入弹性缓和

710 阅读7分钟

作为一个创建了无数CSS动画的人,我一直怀念的是keyframestransition 的弹性易用性。是的,你可以使用JavaScript库和其他技巧(我们稍后会讲到),但是,作为一个最纯粹的人,我已经深入研究了这个问题,检查了当前的解决方案,了解了它背后的数学原理,并建立了一个CSS弹性轻松生成器,输出一个纯粹、干净和准确的CSS动画代码。

什么是CSS中的弹性缓解?

首先,让我们试着更好地理解物体的弹性缓解运动。让我们看看一个从A点移动到B点的红球。

小球从A点开始,向目的地B点移动,但它在B点上过了一些幅度,有效地远离了B点。然后,它开始放慢速度,停下来,开始向另一个方向移动,回到B点。它又一次超过了B点--这次的幅度较小--继续重复这种模式,同时每次减少幅度,直到最后停止。

下面是弹性缓和运动在图表上的样子。

Shrinking Wavy Line On Line Graph Showing Value And Time

  1. 球的起始点
  2. 初始运动
  3. 过度瞄准目标
  4. 重复该模式
  5. 终点

在JavaScript中使用动画库

如果你使用GreenSock这样的动画库,只需添加ease:Elastic.easeOut ,然后继续编码。应该注意的是,虽然第三方解决方案可以帮助你克服许多障碍,但它们确实是有代价的--有时是字面意义上的--它们可能会影响你的加载时间、包的大小,等等。

在JavaScript中为弹性轻松编码

如果你不想(或不能)使用JS库,不要担心,你仍然可以用纯代码实现一个缓解功能。是的,它需要不止一行代码,但它非常简单,而且我已经为你做了大部分的工作。

弹性缓和--#1:JS演示

没有描述

我们这里有一个简单的elastic() 函数,它接收一个介于0和1之间的值(dotValue ),并将其转换到点的正确X位置(elasticPosition )。这个函数还接收了两个常数:速度,它影响动画的持续时间,以及运动的速度。请自由发挥这些数字的作用,看看它们如何影响圆点的运动。

当我们点击运行时,dotValue 重置为0,然后函数开始运行。然后,它不断地运行,使用requestAnimationFrame 函数,在每次迭代中增加speed 的值,并为新的值重新计算点的位置。当dotValue 到了1 ,它就停止。

至于数学,我必须承认,我的数学技能远远不足以正确解释那里发生的事情,但我确实从几个不同的资源中检查了这个函数的一些变化,最后得到了这个版本,它是基于easings.net使用的数学,加上一些小的改进。

在这个例子中,我使用了setProperty 函数,它设置了一个CSS自定义属性,控制点的left 位置,但你可以很容易地使用它来控制一个元素的大小、不透明度、角度、颜色等等。只要确保输入值在0和1之间,并且两个const ,根据你的需要正确定义。

使用CSScubic-bezier ease来实现单步弹性

一个简单而奇妙的解决方案是使用cubic-bezier ease来得到一个单步弹性。你可以这样做,给函数的第四个参数一个足够高的值,使动画通过它的目的地,然后返回到它的最终值。

它不像其他解决方案那样丰富,但它不使用JS,很容易,而且有时它就是你所需要的一切。我已经根据这个方法创建了几个例子,你可以使用Lea Verou的这个伟大的工具,玩玩cubic-bezier ,得到你想要的确切结果。

弹性缓和--#2:立方体-比泽尔

没有说明

在CSS中使用关键帧实现弹性缓和

另一种实现纯CSS弹性缓解的方法是用动画关键帧手动定义每一步的运动,以更好地理解这种方法。让我们再看一次图上的运动。

Separated Segments Of Shrinking Wavy Line On Line Graph Showing Value And Time

在这里,你可以看到运动被划分为若干段,这些段被一条垂直的虚线隔开。请注意,这些段上的运动就像我们都知道的内置的CSS缓进缓出计时功能一样,所以我们可以把每个段翻译成一个关键帧,用纯CSS得到一个完全弹性的运动。

这种方法的问题是,你首先需要计算每个关键帧的位置和数值,这不是一件容易的事。而且,如果你的计算不准确,结果可能看起来会有抖动和不一致。为了解决这个问题,我建立了一个简单的发生器,根据你的参数为你创建关键帧。

为了实现最大的通用性,我们需要控制三个变量,这三个变量将反过来控制运动的轨迹。

  • 步数:来回重复的次数
  • 减速:控制每次重复之间的关系
  • 速度:设定轻松度与原始路径的偏移量

为动画创建段的大小

让我们把它分解开来。我们将从动画的步数(段)和它们之间的减速开始。这很重要,因为每一步都会被转化为一个关键帧,而每一步的大小将决定关键帧的位置。

弹性缓解 - #3: 步数

没有说明

如果你移动步数滑块,你就可以控制运动将由多少个片段构成。减速条设置了大小关系。当滑块一路向左时,所有的段都将是相同的尺寸。如果滑块被定位到最右边,每个片段将是前一个片段的一半大小。请注意,如果你使用了太多的步数,而且减速值很高,最后几步可能太小,没有任何效果。

设置速度

现在我们有了关键帧的位置,让我们来谈谈数值的问题。我们会说初始值永远是0,而结束值永远是1。这样,我们以后可以把这些值映射到任何CSS属性上,而速度水平将决定每一步与最终值的偏差程度。

弹性缓解 - #4:速度

没有描述

现在我们有了一个漂亮的弹性图,我们要完成的最后一步是添加一个持续时间滑块,设定动画的总体时间,然后决定我们要做什么动画。

在这个生成器中,我添加了一些常用属性的动画选项,如width,height, 和transform ,但你可以很容易地调整它,使你需要的几乎所有属性都成为动画。

使用该生成器

CSS Elastic ease生成器

没有说明

现在,在全屏上打开生成器。随意使用生成器的输入来控制运动,复制输出代码,并在你的项目中使用它来为你的动画添加弹性。

你可以根据你的需要编辑和改变这个动画。例如,如果你想让你的动画循环播放,你可以放弃animation-fill-mode ,添加animation-iteration-count: infinite; 。或者,你可以添加animation-direction: alternate;animation-delay ,甚至可以为不同的属性组合两个动画。

这里有一个很酷的例子,是使用这个生成器创建的关键帧的动画。

弹性轻松 - #5:例子

没有描述

结语

我梦想有一天,CSS会有一个内置的弹性功能,而这个生成器将变得毫无用处。想一想,如果有一个简单的弹性函数,接受这三个参数并产生一个干净漂亮的弹性缓解,那该多好啊。

.elasticObject {
  animation-name: goElastic;
  animation-duration: 1.5s;
  animation-timing-function: elastic(7, 1.9, 0.5);
}

在那之前,请随意使用这个生成器,以满足你的任何需要,如果你对如何改进这个方法有任何想法或建议,请写在评论里。谢谢

The postIncorporating elastic ease in CSS animationsappeared first onLogRocket Blog.