CSS3动画帧数科学计算法

循环动画按循环方式可以分为:

9.jpg


用CSS代码的方式表示,就是:
单向循环: animation-iteration-count: infinite; animation-direction: normal;
双向循环:   animation-iteration-count: infinite; animation-direction: alternate;

先看看做一个动画需要哪些条件

10.jpg

总帧数:100 (已知参数)
CSS3帧动画的帧数设置是从0%~100%,数值可以带小数位,0%可以用from关键词替代,100%可以用to关键词替代

动作数:n (已知参数)
动画中的几个关键动作

动作停留帧数:x (未知参数)
在当前动作停留的帧数

动作过渡帧数:y (未知参数)
上一个动作过渡到下一个动作需要用的帧数

我们用示例来说明它们之间的关系。

单向循环动画
示例要求:实现一个3个动作的单向循环动画

为了方便理解,以 线段图示法来展示

Step1,满帧100%
0%                           100%
└─────────────────────────────────────────┘

Step2,添加动作节点(总节点数 = 动作数)
0%             ?%            100%
过渡y帧           过渡y帧
└────────────────────┴────────────────────┘
动作1            动作2            动作3

这个时候,我们很轻易的算出动作2的keyframes帧数是50%


实际上,很多时候我们需要让每个动作停顿一会,而不会闪动太快。如“嘀卡萌风骚乱舞”的动画,每个动作都需要定格一会,这个时候我们需要给每个动作分配一些停留帧数。

Step3,添加停留帧 (总节点数 = 动作数 * 2)
0%    ?%     ?%     ?%     ?%    100%

停留x帧  过渡y帧   停留x帧  过渡y帧   停留x帧
└───────┴────────┴────────┴───────┴───────┘
动作1          动作2          动作3

这下就复杂了,不过我们仔细分析,会发现它们之间有一定的规律。
3x + 2y = 100

动作个数 = 3       停留帧个数 = 3      过渡帧个数 = 2

设动作个数为n,则
动作个数 = n       停留帧个数 = n      过渡帧个数 = n-1

然后,我们可以得出一个公式
nx + (n-1)y = 100
接下来我们可以有规则性的尝试动画参数了,我们尝试让每个动作停留20帧,通过公式求得动作过渡帧数y也等于20,于是得出我们的帧数代码
  1. .demo{animation:anim-name 1s infinite;}  /* 单向循环 */

  2. @keyframes anim-name{
  3.     0%, 20%{  /* 动作1 */  }
  4.     40%, 60%{  /* 动作2 */  }
  5.     80%, 100%{  /* 动作3 */  }
  6. }
复制代码

有了公式,我们就不用瞎尝试啦,可以少死点脑细胞了

双向循环动画
示例要求:实现一个3个动作的双向循环动画

复制上面的动画代码,加个 animation-direction: alternate; 属性不就好了?

(哦,不对,按照心理学反推论,如果这么简单,作者有必要另起篇幅吗?肯定有阴谋!)

不用猜了,我就是有阴谋!

继续 线段图示,当我们加入 animation-direction: alternate; 属性之后的效果是
11.png

问题:首尾动作从第二遍播放开始会重复停留时间!

这个并不是我们期望看到的效果,不过解决方法也很简单

12.png

通过线段图分析
2x + 2y = 100
动作个数 = 3       停留帧个数 = 2         过渡帧个数 = 2

设动作个数为n,则
动作个数 = n       停留帧个数 = n-1     过渡帧个数 = n-1

然后,我们可以得出一个公式
(n-1)(x+y) = 100

接下来我们还是尝试让每个动作停留20帧,通过公式求得动作过渡帧数y等于30,于是得出我们的帧数代码
  1. .demo{animation:anim-name 1s infinite alternate;} /* 双向循环 */

  2. @keyframes anim-name{
  3.     0%, 10%{  /* 动作1 */  }
  4.     40%, 60%{  /* 动作2 */  }
  5.     90%, 100%{  /* 动作3 */  }
  6. }
复制代码

注意:双向循环动画,首尾动作停留帧要各减一半,示例的首尾动作停留帧为10 (20/2=10)

细心的同学会发现,其实这里还有点小瑕疵,那就是

问题:第一次播放的第一个动作只停了一半时间!

有时我们做动作衔接,一定要所有动作时间都保持一致。解决办法也不是没有,可以给动画加个延迟时间 animation-delay 属性,时长等于动作停留时间的一半,如何计算时长后面会讲到。

除了加延时解决这个问题之外,还有一个伪方法,请继续往下看

模拟双向循环动画
示例要求:实现一个3个动作的双向循环动画

模拟双向循环动画就是不使用 animation-direction: alternate; 属性实现双向循环的效果。

有点绕,上线段图

13.png

通过线段图分析
4x + 4y = 100
动作个数 = 5       停留帧个数 = 4         过渡帧个数 = 4

设动作个数为n,则

动作个数 = n       停留帧个数 = n-1     过渡帧个数 = n-1

然后,我们可以得出一个公式
(n-1)(x+y) = 100

但动作个数5包含了重复动作,不符合我们的计算习惯,不包含重复动作个数3才符合我们的计算习惯。那么设

(不含重复)动作个数为 m

(含重复)动作个数为 n,则 n = 2m-1,将 2m-1 带入上面的公式得出公式
(2m-1-1)(x+y) = 100

将m统一换成n表示,再简化公式后得到最终公式
(2n-2)(x+y) = 100

接下来我们再次尝试让每个动作停留20帧,通过公式求得动作过渡帧数y等于5,于是得出我们的帧数代码
  1. .demo{animation:anim-name 1s infinite;} /* 模拟双向循环 */

  2. @-webkit-keyframes anim-name{
  3.     0%{  /* 动作1 */  }
  4.     20%{  /* 动作1 */  }
  5.     25%{  /* 动作2 */  }
  6.     45%{  /* 动作2 */  }
  7.     50%{  /* 动作3 */  }
  8.     70%{  /* 动作3 */  }
  9.     75%{  /* 动作2 */  }
  10.     95%{  /* 动作2 */  }
  11.     100%{  /* 动作1 */  }
  12. }
复制代码

缩写版代码
  1. .demo{animation:anim-name 1s infinite;} /* 模拟双向循环 */

  2. @keyframes anim-name{
  3.     0%, 20%, 100%{  /* 动作1 */  }
  4.     25%, 45%, 75%, 95%{  /* 动作2 */  }
  5.     50%, 70%{  /* 动作3 */  }
  6. }
复制代码

模拟双向循环的方法可以让所有动作的停留时间都保持一致,缺点就是代码比较多,帧数也算得麻烦,不过也不失为一种解决方法。一般情况下,还是建议大家使用双向循环+延迟播放的方案。

提到延迟播放,跟时间有关系,这个延迟时长该怎么定?如果以上方案,每个动作我们要固定它的过渡时间,比如动作之间过渡0.4秒,那过渡帧数又该怎么定?接下来我们再挖掘一下,帧数如何跟时间结合。

时间模式计算帧数
我们在做动画的时候需要设置一个 animation-duration 动画持续时间的属性,知道持续播放时间我们就可以很轻易的计算出播放速度,还记得我们小学学的速度公式吗?

设,总帧数为s(100帧),播放时间为t,播放速度为v,得出公式
v = s / t

继续用示例来加深理解。

示例要求:实现一个3个动作的单向循环动画,播放时间2秒,每个动作的过渡时间为0.4秒

通过播放速度公式,我们可以计算出过渡帧数。

播放速度:  100帧 / 2秒 = 50帧/秒

过渡帧数:  50帧/秒 * 0.4秒 = 20帧

得出过渡帧数,接下来套用单向循环动画的帧数公式,计算出停留帧数,参考上面总结的公式  nx + (n-1)y = 100  ,推导公式得出停留帧数 x = (100-(n-1)y) / n

动作个数(n):  3
过渡帧数(y): 20

停留帧数:  (100-(3-1)*20)/3 = 20帧

于是得出我们的帧数代码
  1. .demo{animation:anim-name 2s infinite;}  /* 单向循环 */

  2. @keyframes anim-name{
  3.     0%, 20%{  /* 动作1 */  }
  4.     40%, 60%{  /* 动作2 */  }
  5.     80%, 100%{  /* 动作3 */  }
  6. }
复制代码

这么多公式,眼都花了更别说记了。别着急,公式是给机器记的,这种破事就交给我们的机器去算。下面是一个简易的CSS3动画帧数计算器,可以帮我们省去一些计算的烦恼。
CSS3动画帧数计算器: http://tid.tenpay.com/labs/css3_keyframes_calculator.html

16.jpg


以白树同学的跑步动画为示例

8.gif

15.png

动画是单向循环,有7个关键动作,动作需要使用逐帧过渡效果 animation-timing-function:step-start 实现,所以动作个数需要额外加1,即有8个动作。使用 step-start 后会自动平分动作停留时间,所以keyframes我们就不用加动作停留帧数了。

打开工具页面,选择 [单向循环动画] -> [不停顿] -> [动作个数8] -> [生成代码]
16.jpg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值