详解CSS帧动画 | 您所在的位置:网站首页 › 动画一般都是几帧 › 详解CSS帧动画 |
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; } 七、填充模式下面我们通过一个示例来看看帧动画填充模式的问题:
在这个动画中,我们想要做一个元素淡出的效果,动画执行的很好,但是执行完毕后,元素又出现在了屏幕上。 如果我们要绘制元素的不透明度随时间的变化示意图,它看起来像这样: 为什么元素会变回完全可见?那是因为from和to块中的声明只在动画运行时应用。在1000毫秒之后,动画将自己取消应用,to块中的声明会消失,让元素应用其他地方定义的CSS声明。因为我们没有在其他地方设置这个元素的不透明度,所以它恢复到默认值(1)。 第一种解决这个问题的方法是:在box选择器中添加一个不透明度声明。 在动画执行时,元素会从不透明渐变成透明,然后元素会一直保持透明状态(因为我们在CSS选择器中声明了)。但我们仔细想想,这真的合适吗?有可能我们一开始的时候元素一直需要保持不透明状态呢? 这个时候CCS就提供了animation-fill-mode属性供我们来选择。 1. forwardsanimation-fill-mode: forwards 能够让我们保留动画的最终值:
当动画结束时,animation-fill-mode: forwards 将复制/粘贴最后一个块中的声明,并及时将其持久化。 有时候,我们并不希望动画立即启动,与过渡一样,我们可以使用animation-delay属性声明延迟时间。但是这个可能又引发一些小问题:
在示例的前半秒中,元素是完全可见的,这造成了动画的不协调。 from和to块中的CSS只在动画运行时应用,动画延迟期并不算在内。所以在前半秒,from块中的CSS没有生效。animation-fill-mode还有一个值可以帮助我们:backward。这将应用帧动画第一个块中的CSS。 forwards 和 backwards可能有点让人困惑,但这里有一个类比可能会有所帮助理解:想象一下,如果我们从页面加载的那一刻开始录像用户界面,我们可以在录像中前进后退。backwards 相当于录像的后退,forwards 就相当于录像的前进。 下面的示例就是使用animation-fill-mode: backwards的效果,我们可以和前一个例子进行对比:
如果我们想要保持动画forwards和backwards呢?我们可以使用第三个值both,它在两个方向上都生效: 本文中已经详细讲解了许多关于帧动画的知识,如果结合CSS变量来定义帧动画,这将是一个更高级的用法。 首先让我们来创建一个弹跳球动画:
CSS动画一般是通用的,但这个动画总是让元素移动20px。如果不同的元素需要不同的移动距离,这样声明肯定是不简洁明了的。但是结合CSS变量,就可以实现:
现在我们重写了Keyframes帧动画的定义,它不是写死移动-20px,而是访问--bounce-offset属性的值,由于该属性在每个CSS选择器中都有不同的值,所以它们的动画也将移动不同的值。这种声明策略让CSS帧动画的复用性有了更大的提升,就类似react中的组件一样。 九、总结CSS帧动画是一项强大而有趣的能力,让前端应用变得更丰富多彩,交互性更高。本文详细介绍了关于帧动画的相关知识,希望能够对各位有所帮助。 文中如有错误,敬请指正! |
今日新闻 |
推荐新闻 |
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 |