学习css3之animation

作者 likaiqiang 日期 2019-07-09
css
学习css3之animation

animation的简介

animation的官方解释

animation的组成

一个完整animation动画由三部分组成:动画开始前(before)、动画进行中(being)、动画结束后(after)。

这个红色方块从左到右移动了100px,动画总时长1s(being),延时1s(before)执行,动画结束后(after)红色方块回到初始状态。

上面的例子方块的初始状态与动画的第一帧一样(transform),我们来个不一样的。

看到没有变了,动画初始状态的位移为40px,动画开始前在这个位置停1s(before),1s后动画从位移为0的地方移动到100px的位置(being),动画结束后(after),回到位移为40px的地方(初始状态)。

animation的分类

动画按是否连续分为连续动画与非连续动画。(名字是我瞎起的。。。)

区分一个动画是否连续关键在于它的 animation-timing-function 是不是连续的

连续动画

animation-timing-function 取值为贝塞尔曲线,或者它的任意关键字。

非连续动画

animation-timing-function 取值为steps()函数。

animation各属性介绍

animation-name

这条属性是用的最多的,没什么好说的。

animation-timing-function

顾名思义,动画时间函数,它的值有两种,分别对应连续动画与非连续动画。在解释它之前有必要说一下什么是时间函数,像时间这种看不见摸不着的“东西”,竟然还能封装成函数,真是让人难以理解。

其实仔细想一下就会发现它虽然叫做动画时间函数,但是它封装的并不仅仅是时间,它封装的是时间与状态之间的关系。它的值有两种,贝塞尔曲线与steps函数,前者表示连续动画,后者表示非连续动画。它们都作用于两个关键帧之间。

贝塞尔曲线

贝塞尔曲线描述了动画时间与状态的关系,是连续的。有四个参数,分别定义两个手柄的位置。在css中,手柄从0,0和1,1两个点延伸出来。前两个参数定义曲线上第一点(或手柄)的x坐标和y坐标。x坐标的值必须在0到1之间,否则得不到贝塞尔曲线。y坐标的值不受限制。

animation-timing-function提供了五种贝塞尔曲线关键字,它们分别是:

  1. ease cubic-bezier(0.25, 0.1, 0.25, 1)
  2. linear cubic-bezier(0, 0, 1, 1)
  3. ease-in cubic-bezier(0.42, 0, 1, 1)
  4. ease-out cubic-bezier(0, 0, 0.58, 1)
  5. ease-in-out cubic-bezier(0.42, 0, 0.58, 1)

如果需要自定义贝塞尔曲线,可以使用贝塞尔曲线可视化工具

steps函数

steps函数描述的是运动的不连续性,它有两个参数:

  1. 两个关键帧之间从起点到终点需要的步数
  2. 在每一步的开始或者结束发生跳跃

比如说有这样一个动画

.test{
animation: play 10s steps(4,end);
}
@keyframs play{
0% {
transform:translateX(0);
}
40% {
transform:translateX(20px);
}
100% {
transform:translateX(100px);
}
}

有三个关键帧,每两个关键帧之间分4步走。前4s从0移动到20px,后6s从20px移动到100px。前4s需要分4步(steps函数第一个参数),每一步都有开始(start)与结束(end),而steps函数的第二个参数表示的就是值的变化(跳跃)是发生在start还是end。动画开始后,test元素会先静止不动,1s后(第一步的end)移动5px,然后重复这一过程3次。后6s同理。

steps函数模拟连续动画

从另一角度我们可以认为间隔很短的许多非联系动画可以组成“连续”动画。

animation-timing-function的作用范围

引用MDN上的一句话:对于关键帧动画来说,timing function作用于一个关键帧周期而非整个动画周期,即从关键帧开始开始,到关键帧结束结束。

什么叫做“对于关键帧动画来说”,那是不是意味着还有别的动画。答案是有的,没错,就是我们经常使用的transition,专业名称叫做过渡动画。

回到animation上,animation-timing-function的值作用于两个关键帧之间。那它某两帧之间可不可以自定义时间函数,答案是可以的。

正常的动画:匀速运动,width从50到150,translateX从0到400

我们来改变它的关键帧时间函数

神奇吧,来个更神奇的

含笑半步颠。。。

所以综上,帧与帧之间的时间函数默认使用该动画的时间函数,当某个选择符有自己的时间函数时,从这一帧开始到下一帧开始使用该帧的时间函数。那么问题又来了,自定义时间函数的作用范围是该选择符内的所有属性还是动画范围内的所有属性,答案是前者。

第一个含笑半步颠是translateX与width同时颠,而第二个只有translateX颠,width的时间函数是linear。

animation-duration

动画从第一帧到最后一帧的总时长,单位为秒。

animation-delay

动画开始前(before阶段)的总时长,单位为秒,可以为负值。

animation-delay的值为负值挺有意思。一个完整的动画有两个时间:

  1. being的时长 = animation-duration
  2. (before + being)的时长 = animation-duration + animation-delay

animation-delay值为负值,可以实现时间加速效果,用语言好难描述,看代码

animation-iteration-count

动画重复的次数,值为任意正数或者infinite(表示正无穷)

animation-play-state

动画当前的状态,有两个值paused与running,顾名思义,暂停与正在进行,可以用JavaScript改变这个属性来改变动画的状态。

animation-fill-mode

这个属性有点诡异。通常我们认为一个动画只有being状态,从第一帧到最后一帧就完事了,其实一个完整的动画包含三部分:before + being + after ,animation-fill-mode控制的就是before与after的行为,它的值有四个,none、forwards、backwards与both。

none是默认值,默认的before与after阶段元素的状态都为元素的原始值。

backwrads 表示before阶段元素的状态为动画的第一帧。

forwrads 表示after阶段元素的状态为动画的最后一帧。

both兼顾backwrads与forwrads效果。

animation-direction

这个值其实很简单,从字面意思上理解,动画播放方向,其实它表示的并不是时间的方向,它表示的是timing-function的方向,变化的方向。

animation的简写

animation的简写跟background差不多,animation: name duration delay count timing-function fill-mode play-state direction

delay必须位于duration的后面,其他属性没有位置要求,个人习惯将name写在最前面。

多动画

与background一样,animation还支持多动画,动画之间用逗号分隔。