详解CSS帧动画 您所在的位置:网站首页 动画一般都是几帧 详解CSS帧动画

详解CSS帧动画

2024-04-12 16:38| 来源: 网络整理| 查看: 265

CSS keyFrames 动画(下文中统称为:CSS帧动画)是CSS中最强大、最实用的功能之一,通过它,我们可以来实现各种各样漂亮的动效。但是对于刚接触到CSS帧动画的开发者而言,可能会遇到一些理解和实现的困难。因此,我们在本文中将深入研究CSS帧动画,理解它们的工作原理,并看看如何用它们实现一些不错的的动画效果。

一、语法

CSS帧动画的核心思想是,它在不同的CSS块之中对不同的CSS属性进行赋值。 下面我们通过一个示例来看看帧动画如何使用的:

首先我们定义了一个CSS帧动画,它将平滑地把元素的水平位置从-100%平移到0%,并将它命名为slide-in:

@keyframes slide-in { from { transform: translateX(-100%); } to { transform: translateX(0%); } }

每个@keyframes语句都需要一个名称! 然后我们通过animation属性将它应用于CSS选择器#app中:

#app { animation: slide-in 1000ms; }

与transition属性一样,animation属性也需要一个持续时间。示例中我们定义动画的持续为1000毫秒。在指定的持续时间内,浏览器将会执行动画,从from中定义的属性值平滑的变成to中定义的的属性值。

我们可以在同一个动画声明中为多个属性制作动画。这里通过一个更炫的一个动画示例来展示:

我们通过示例来初步接触了CSS帧动画,下面我们通过了解CSS帧动画的属性,来进一步理解它。

二、时间函数(Timing functions)

我们可以用animation-timing-function属性去设置帧动画的时间函数,和transition属性一样,默认值是ease。关于时间函数的介绍,在详解CSS过渡属性——transition这一文中有着详细的介绍,本文不再赘述。下例中展示了animation-timing-function的使用:

三、动画循环

默认情况下,帧动画只会运行一次,但我们可以通过animation-iteration-count属性来控制动画运行的次数,下面的示例中,动画执行了3次:

animation-iteration-count 很少指定详细的数值,这个时候,有一个特殊的值infinite就排上了用场,它表示动画无限次循环执行,如下例,我们就实现了一个loading效果动画:

四、分步骤动画

除了通过from和to关键字来定义动画步骤,我们还可以通过百分比来定义,这就意味着我们的动画可以有两个以上的动画步骤:

from 和 to 只是一个语法糖,from代表0%,to代表100%。

这边有个容易的误解的地方,那就是time-function它是分别应用帧动画的每一个步骤的,而不是简单的应用在一个完整的动画中。下面我们通过一个示例来看看time-function如何应用在每一步当中:

在这个示例中,我们没有明确指定time-function,所以默认值是ease,两个动画,一个分两步执行,还有一个分4步执行,但是不管分几步执行,每一步都是一个完整的time-function。这一点我们无法改变,因此在做动画之时,我们只能自己去看有没有问题。

五、交替动画

如果我们想要一个元素有类似“呼吸”的效果——不停放大和缩小,我们可以做一个三步的动画,第一步到第二步的时候,元素放大1.5倍,第二步到第三步,元素缩小为1倍,无限循环运动,就产生了元素“呼吸”的效果:

但是我们还有一种更优雅的方式来实现,使用animation-direction属性,我们这样设置animation-direction: alternate,再来看看效果。

animation-direction属性控制动画的方向:

normal(默认值),正常顺序,在指定的持续时间内从0%到100%; reverse,反转顺序,从后向前执行动画,也就是说在持续时间内100%到0%; alternate,交替顺序,先从0%到100%,再从100%到0%,如此反复。 六、组合写法

在前文中,我们使用了很多animation的属性,如果一个个写,将是件很繁琐的事情。幸运的是,animation和transition属性一样,它也有组合写法。

.box { /* animation: grow-and-shrink 2000ms; animation-timing-function: ease-in-out; animation-iteration-count: infinite; animation-direction: alternate; 等价下面写法: */ animation: grow-and-shrink 2000ms ease-in-out infinite alternate; }

在组合写法中,顺序不重要,你可以任意书写,但是有一个值是例外,那就是animation-delay属性,它的作用是用来指定动画的延时执行的时间。由于它和动画持续时间animation-duration是一样的值类型,都是s或者ms,所以它必须放在animation-duration后面。为了避免出现困扰,建议animation-delay属性单独书写:

.box { animation: grow-and-shrink 2000ms ease-in-out infinite alternate; animation-delay: 500ms; } 七、填充模式

下面我们通过一个示例来看看帧动画填充模式的问题:

在这个动画中,我们想要做一个元素淡出的效果,动画执行的很好,但是执行完毕后,元素又出现在了屏幕上。

如果我们要绘制元素的不透明度随时间的变化示意图,它看起来像这样:

image.png

为什么元素会变回完全可见?那是因为from和to块中的声明只在动画运行时应用。在1000毫秒之后,动画将自己取消应用,to块中的声明会消失,让元素应用其他地方定义的CSS声明。因为我们没有在其他地方设置这个元素的不透明度,所以它恢复到默认值(1)。

第一种解决这个问题的方法是:在box选择器中添加一个不透明度声明。

在动画执行时,元素会从不透明渐变成透明,然后元素会一直保持透明状态(因为我们在CSS选择器中声明了)。但我们仔细想想,这真的合适吗?有可能我们一开始的时候元素一直需要保持不透明状态呢?

这个时候CCS就提供了animation-fill-mode属性供我们来选择。

1. forwards

animation-fill-mode: forwards 能够让我们保留动画的最终值:

当动画结束时,animation-fill-mode: forwards 将复制/粘贴最后一个块中的声明,并及时将其持久化。

image.png

2. backwards

有时候,我们并不希望动画立即启动,与过渡一样,我们可以使用animation-delay属性声明延迟时间。但是这个可能又引发一些小问题:

在示例的前半秒中,元素是完全可见的,这造成了动画的不协调。

image.png

from和to块中的CSS只在动画运行时应用,动画延迟期并不算在内。所以在前半秒,from块中的CSS没有生效。animation-fill-mode还有一个值可以帮助我们:backward。这将应用帧动画第一个块中的CSS。

image.png

forwards 和 backwards可能有点让人困惑,但这里有一个类比可能会有所帮助理解:想象一下,如果我们从页面加载的那一刻开始录像用户界面,我们可以在录像中前进后退。backwards 相当于录像的后退,forwards 就相当于录像的前进。

下面的示例就是使用animation-fill-mode: backwards的效果,我们可以和前一个例子进行对比:

3. both

如果我们想要保持动画forwards和backwards呢?我们可以使用第三个值both,它在两个方向上都生效:

image.png

.box { animation: slide-in 1000ms ease-out both; animation-delay: 500ms; } 八、使用CSS变量来动态创建动画

本文中已经详细讲解了许多关于帧动画的知识,如果结合CSS变量来定义帧动画,这将是一个更高级的用法。

首先让我们来创建一个弹跳球动画:

CSS动画一般是通用的,但这个动画总是让元素移动20px。如果不同的元素需要不同的移动距离,这样声明肯定是不简洁明了的。但是结合CSS变量,就可以实现:

现在我们重写了Keyframes帧动画的定义,它不是写死移动-20px,而是访问--bounce-offset属性的值,由于该属性在每个CSS选择器中都有不同的值,所以它们的动画也将移动不同的值。这种声明策略让CSS帧动画的复用性有了更大的提升,就类似react中的组件一样。

九、总结

CSS帧动画是一项强大而有趣的能力,让前端应用变得更丰富多彩,交互性更高。本文详细介绍了关于帧动画的相关知识,希望能够对各位有所帮助。

文中如有错误,敬请指正!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有