本文来源于:财付通TID    原作者:bboy90


总结都浓缩在这个工具里了,想知道工具的地址或想窥探工具诞生的趣事请往下看 。

—————————————————————–     华丽丽的开篇     —————————————————————-

本篇文章来自腾讯内部饭卡充值改版项目的CSS3动画经验总结。虽然你们访问不到我们的饭卡站点,不过可以小窥一下我们的动画示例哟。

(请使用chrome、safari或firefox浏览器看效果,效果地址

比如这个动画:

我曾经,这么干过

还这么干过

step1, 动作1在0%上,动作停留20帧

 @keyframes anim-name{
     0%, 20%{ /* 动作1 */ }
     ...
 }

step2,  动作之间过渡5帧,动作1结束帧在20%,20+5=25, 动作2在25%帧,动作停留20帧

 @keyframes anim-name{
     0%, 20%{ /* 动作1 */ }
     25%, 45%{ /* 动作2 */ }
     ...
 }

······

经过一番计算后

 @keyframes anim-name{
     0%, 20%{ /* 动作1 */ }
     25%, 45%{ /* 动作2 */ }
     50%, 70%{ /* 动作3 */ }
     75%, 95%{ /* 动作4 */ }
     100%, 120%{ /* 动作5 */ }
 }

艾玛,帧数超出100%了>_<

重新计算了一番,动作数5,动作过渡帧数5%,动作停留帧数16%

 @-webkit-keyframes anim-name{
     0%, 16%{  /* 动作1 */  }
     21%, 37%{  /* 动作2 */  }
     42%, 58%{  /* 动作3 */  }
     63%, 79%{  /* 动作4 */  }
     84%, 100%{  /* 动作5 */  }
 }

感谢人民感谢党,最后一帧加起来刚好100%

刷新页面看效果之后……(动作过渡有点快,动作停留有点长)

效果不对,重算!

······

就这样被折腾地体无完肤,深刻感悟我们是用生命在做动画,啊…..多么痛的领悟悟悟~~(有共鸣的,请默默的点个赞,谢谢)

所以,我们今天来探讨如何更科学的计算帧数?

文章主要研究循环动画,各个动作之间的过渡有规律性

比如嘀卡萌跳舞动画

走路动画

还有跑步动画

(该动画的实现,可 查看 白树同学的分享)

动作过渡有规律性,从代码层面也可理解为各动作之间的过渡帧数是一样的。

如上面白树同学实现的跑步动画,各动作之间的过渡帧约14.3帧,代码为

 @keyframes anim-name{
     0% {background-position: 0 0;}
     14.3% {background-position: -180px 0;}
     28.6% {background-position: -360px 0;}
     42.9% {background-position: -540px 0;}
     57.2% {background-position: -720px 0;}
     71.5% {background-position: -900px 0;}
     85.8% {background-position: -1080px 0;}
     100% {background-position: 0 0;}
 }

好,下面让我们愉快的进入主题吧

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

用CSS代码的方式表示,就是:

单向循环:  animation-iteration-count: infinite; animation-direction: normal;

双向循环:  animation-iteration-count: infinite; animation-direction: alternate;

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

总帧数: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,于是得出我们的帧数代码

 .demo{animation:anim-name 1s infinite;}  /* 单向循环 */

 @keyframes anim-name{
     0%, 20%{  /* 动作1 */  }
     40%, 60%{  /* 动作2 */  }
     80%, 100%{  /* 动作3 */  }
 }

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

双向循环动画

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

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

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

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

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

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

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

通过线段图分析

2x + 2y = 100

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

设动作个数为n,则

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

然后,我们可以得出一个公式

(n-1)(x+y) = 100

接下来我们还是尝试让每个动作停留20帧,通过公式求得动作过渡帧数y等于30,于是得出我们的帧数代码

 .demo{animation:anim-name 1s infinite alternate;} /* 双向循环 */

 @keyframes anim-name{
     0%, 10%{  /* 动作1 */  }
     40%, 60%{  /* 动作2 */  }
     90%, 100%{  /* 动作3 */  }
 }

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

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

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

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

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

模拟双向循环动画

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

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

有点绕,上线段图

通过线段图分析

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,于是得出我们的帧数代码

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

 @-webkit-keyframes anim-name{
     0%{  /* 动作1 */  }
     20%{  /* 动作1 */  }
     25%{  /* 动作2 */  }
     45%{  /* 动作2 */  }
     50%{  /* 动作3 */  }
     70%{  /* 动作3 */  }
     75%{  /* 动作2 */  }
     95%{  /* 动作2 */  }
     100%{  /* 动作1 */  }
 }

缩写版代码

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

 @keyframes anim-name{
     0%, 20%, 100%{  /* 动作1 */  }
     25%, 45%, 75%, 95%{  /* 动作2 */  }
     50%, 70%{  /* 动作3 */  }
 }

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

提到延迟播放,跟时间有关系,这个延迟时长该怎么定?如果以上方案,每个动作我们要固定它的过渡时间,比如动作之间过渡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帧

于是得出我们的帧数代码

 .demo{animation:anim-name 2s infinite;}  /* 单向循环 */

 @keyframes anim-name{
     0%, 20%{  /* 动作1 */  }
     40%, 60%{  /* 动作2 */  }
     80%, 100%{  /* 动作3 */  }
 }

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

CSS3动画帧数计算器:http://tid.tenpay.com/labs/css3_keyframes_calculator.html

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

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

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

【转】CSS3动画帧数科学计算法的更多相关文章

  1. css3动画帧

    动画帧实现: css3使用steps来实现逐帧动画,动画过程中可能出现抖动,实乃精度偏差问题. 通常在动画里用到百分比单位时会出现抖动或位移现象,解决方法就是转换成具体的rem或px长度单位. 动画一 ...

  2. CSS3动画几个平时没注意的属性

    一.timing-function: steps() 一开始在使用CSS3的时候并没有太注意这个timing-function,只是注意到自定义贝塞尔曲线. 1)一个项目中的实例 先来看看左边加了st ...

  3. 深入理解CSS3 Animation 帧动画

    CSS3我在5年之前就有用了,包括公司项目都一直在很前沿的技术. 最近在写慕课网的七夕主题,用了大量的CSS3动画,但是真的沉淀下来仔细的去深入CSS3动画的各个属性发现还是很深的,这里就写下关于帧动 ...

  4. CSS3的自定义动画帧

    CSS3新增的动画帧非常绚丽,可以简单实现一些动画效果,目前除IE外各大主流浏览器都支持 本文演示三个:transform: scale3d(x, y, z)-缩放;.transform: trans ...

  5. 深入理解CSS3 Animation 帧动画 ( steps )

    作者:Aaron的博客 网址:http://www.cnblogs.com/aaronjs/p/4642015.html --------------------------------------- ...

  6. 深入理解CSS3 Animation 帧动画(转)

    CSS3我在5年之前就有用了,包括公司项目都一直在很前沿的技术. 最近在写慕课网的七夕主题,用了大量的CSS3动画,但是真的沉淀下来仔细的去深入CSS3动画的各个属性发现还是很深的,这里就写下关于帧动 ...

  7. SASS使用CSS3动画并使动画暂停和停止在最后一帧的简单例子

    今天在手机上试了试这个 css3 动画效果,可以把动画效果停留在最后一帧上,以及鼠标 :hover 暂停动画,比较实用的功能,不用 JS 也能实现这些效果了. 不过测试体验感觉手机上没有 jQuery ...

  8. css3的帧动画

    概述 前几天刚好看到一个用了CSS3帧动画的页面,对它非常感兴趣,就研究了一下,记录在下面,供以后开发时参考,相信对其他人也有用. PS:以后别人问我用过什么CSS3属性的时候,我也可以不用说常见的a ...

  9. css3逐帧动画

    写css3动画的时候,我们经常用到animation来实现,默认情况下,animation是属于连贯性的ease动画.我们熟悉的animation动画有ease.ease-in.ease-out.li ...

随机推荐

  1. POJ2796 Feel Good 单调栈

    题意:给定一个序列,需要找出某个子序列S使得Min(a[i])*Σa[i] (i属于S序列)最大 正解:单调栈 这题的暴力还是很好想的,只需3分钟的事就可以码完,以每个点拓展即可,但这样的复杂度是O( ...

  2. 根据html容器大小和显示文字多少调节字体大小

    在做html相关的东西的时候经常会遇到这样的问题,容器大小(长x宽)固定,容器包含内容(特指文字)多少不固定,这个时候就让人很苦恼了,将字体大小设置成多少才合适呢?下面看看我的解决思路: 首先要知道网 ...

  3. tomcat 和servlet之间的关系

    http://tomcat.apache.org/whichversion.html pache Tomcat Versions Apache Tomcat® is an open source so ...

  4. python序列化模块json和pickle

    序列化相关 1. json 应用场景: json模块主要用于处理json格式的数据,可以将json格式的数据转化为python的字典,便于python处理,同时也可以将python的字典或列表等对象转 ...

  5. tar.xz文件如何解压

    1. tar.xz介绍 XZ压缩最新压缩率之王 xz这个压缩可能很多都很陌生,不过您可知道xz是绝大数linux默认就带的一个压缩工具. 之前xz使用一直很少,所以几乎没有什么提起. 2. 压缩 ta ...

  6. UVa 437 The Tower of Babylon(经典动态规划)

    传送门 Description Perhaps you have heard of the legend of the Tower of Babylon. Nowadays many details ...

  7. Code笔记之:CSS+HTML display 属性

    display属性值:none 此元素不会被显示. block 此元素将显示为块级元素,此元素前后会带有换行符. inline 默认.此元素会被显示为内联元素,元素前后没有换行符. inline-bl ...

  8. 导入.pch文件

    Xcode5中创建一个工程的时候,系统会自动创建一个以以工程名为名字的pch(Precompile Prefix Header)文件,开发的过程中可以将广泛使用的头文件以及宏包含在该文件下,编译器就会 ...

  9. bootstrap学习总结-04 常用标签2

    1 表格 Bootstrap为表格设计了漂亮的样式. 1)表格基本实例 任意 <table> 标签添加 .table. <table class="table"& ...

  10. what's the CRSF ??

    What's CSRF attack ? CSRF(" Cross-site request forgery!" 跨站请求伪造)    用实例讲原理: 我们假设一个银行网站A,一个 ...