过渡与动画 - 逐帧动画&steps调速函数
写在前面
上一篇中我们熟悉五种内置的缓动曲线和(三次)贝塞尔曲线,并且基于此完成了缓动效果.
但是如果我们想要实现逐帧动画,基于贝塞尔曲线的调速函数就显得有些无能为力了,因为我们并不需要帧与帧之间的过渡状态,就像上篇中所看到的,所有基于贝塞尔曲线的调速函数都会在关键帧之间进行插值运算,从而产生平滑的过渡效果。
这个特性显然很棒,平滑的效果确实是我们使用css过渡和动画所追求的。
但是在逐帧动画的场景下,这种平滑的特性恰恰毁掉了我们想要实现的逐帧动画的效果.
逐帧动画
我们经常会看到一段卡通影片、一个复杂进度的提示框、一个小loading,
我们不会单纯的选择一张GIF动画胜任,因为它的局限性和短板表现的很明显.
- GIF图片所能使用的颜色数量被限制在256色
- GIF不具有Alpha透明的特性,
- GIF动画一旦生成,参数就固定在文件内部,只能通过图像处理软件去重新生成.
在某些场景下,基于图片的逐帧动画成了不错的选择。

steps()调速函数
写在前面中提到,我们不能基于贝塞尔曲线的调速函数完成我们所需要的逐帧动画,那么采用什么调速函数呢?
对,答案就是steps()调速函数,与贝塞尔曲线迥然不同的是,steps()会根据你指定的步进数量,把动画分为很多帧,而且整个动画会在帧与帧之间硬切,不会像贝塞尔曲线那样做插值处理。

通过上图我们可以很明显看出steps(8)、linear和ease的区别.
其实这种硬切效果是我们极力避免的,因此我们也很少听到关于steps()的讨论。在CSS调速函数的世界里,基于贝塞尔曲线的调速函数就像是被人追捧的白天鹅,而steps()则是旁人唯恐不及的丑小鸭。

其实无所谓好与不好,更多的是适合与不适合,我们都崇拜的贝塞尔曲线在像小"loading"这样的逐帧动画中失败了,而steps()却展示出我们想要的效果.
这个想法最初是Simurai在他的博客中推出http://simurai.com/blog/2012/12/03/step-animation,他使用steps()实现拼合图片的动画效果.让人印象深刻
See the Pen Steps Animation by simurai (@simurai) on CodePen.
ch单位 - css值与单位第三版
有时候,我们希望一段为本字符逐个显示,模拟出一种打字的效果。这种效果在技术类网站中尤为常见,用等宽字体可以营造出一种终端命令行的感觉.
<h1>CSS is amazing!</h1>
@keyframes typing{
from{width:0}
}
h1{
width:7.7em;
white-space:nowrap;
overflow:hidden;
animation:typing 8s;
}
我们想要模拟出一种打字效果,但是
- 整个动画是平滑连贯的,而不是逐字显示
- 目前我们已经使用em指定宽度是7.7,虽然他比像素单位好一些,但是仍然不够理想,这个宽度为什么是7.7em.
我们很自然的想到了使用steps()来修复第一个问题,但是不幸的是,我们所需要的步进数量是由字符的数量来决定的
CSS值与单位(第三版)规范引入了一个新的单位,表示"0"字形的宽度。大多数场景下,我们不必关心"0"字形的宽度到底有多宽,因为在等宽字体中,"0"字形的宽度和其他所有字形的宽度是一样的。因此,我们如果使用ch单位来表示h1的宽度,那取值实际上就是字符的数量:在上面的例子中就是15
@keyframes typing{
from{ width:0 }
}
@keyframes caret{
50%{ border-color:transparent }
}
h1{
width:15ch;
overflow:hidden;
white-space:nowrap;
border-right:0.5em solid;
animation:typing 6s steps(15),caret 1s steps(1) infinite;
}
但是我们还是有些疑问:
- 这样的代码是不易维护的,当更新标题的时候,我们总是需要根据字符的数量来指定不同的宽度样式和
steps()函数,这时候正是JavaScript的用武之地
function $$(selector,context){
context = context||document;
var elements = context.querySelector(selector);
return Array.prototype.slice.call(elements);
}
$$('h1').forEach(function(h1){
var len = h1.textContent.length,s = h1.style;
s.width = len + 'ch';
s.animationTimingFunction = "steps(" + len + "),steps(1)"
})
- 如果浏览器不支持ch单位,我们该怎么办?这时候就需要实现样式的回退,如果不希望字体出现异常,会选择补一行em作为单位的回退样式
写在最后
这一篇主要基于steps()函数和ch单位,详细的比较了steps()调速函数和基于贝塞尔曲线调速函数的区别,虽然steps()调速函数像是旁人唯恐不及的丑小鸭,但是它亦有其独特的魅力。
参考资料
- 《CSS Secrets》
- http://simurai.com
- http://w3.org/TR/css3-values
过渡与动画 - 逐帧动画&steps调速函数的更多相关文章
- 过渡与动画 - steps调速函数&CSS值与单位之ch
写在前面 上一篇中我们熟悉五种内置的缓动曲线和(三次)贝塞尔曲线,并且基于此完成了缓动效果. 但是如果我们想要实现逐帧动画,基于贝塞尔曲线的调速函数就显得有些无能为力了,因为我们并不需要帧与帧之间的过 ...
- Android笔记(六十三) android中的动画——逐帧动画( frame-by-frame animation)
就好像演电影一样,播放实现准备好的图片,来实现动画效果. 逐帧动画需要用到AnimationDrawable类,该类主要用于创建一个逐帧动画,然后我们把这个动画设置为view的背景即可. androi ...
- Android简单逐帧动画Frame的实现(三)
android之动画(三)通过AnimationDrawable控制逐帧动画 android与逐帧动画: 效果图: 当我们点击按钮时,该图片会不停的旋转,当再次点击按钮时,会停止在当前的状态. ...
- 过渡与动画 - 缓动效果&基于贝塞尔曲线的调速函数
难题 给过渡和动画加上缓动效果是一种常见的手法(比如具有回弹效果的过渡过程)是一种流行的表现手法,可以让界面显得更加生动和真实:在现实世界中,物体A点到B点往往也是不完全匀速的 以纯技术的角度来看,回 ...
- animation中的steps()逐帧动画
在我们平时做宽高确定,需要背景图片切换的效果时,我如果用的是一张大的png图片.而且恰好是所有小图都是从左向右排列的,那么 我们只需测量出某一个小图距左侧有多少像素(x),然后我们banckgroun ...
- CSS3 animation属性中的steps实现GIF动图(逐帧动画)
相信 animation 大家都用过很多,知道是 CSS3做动画用的.而我自己就只会在 X/Y轴 上做位移旋转,使用 animation-timing-function 规定动画的速度曲线,常用到的 ...
- css3 animation实现逐帧动画
css3里面的animation属性非常强大,但是自己用的比较少,最近有次面试就刚好被问到了,趁现在有时间就对animation做一个小总结.同时实现一个逐帧动画的demo作为练习 animation ...
- css3 实现逐帧动画
css3 实现逐帧动画 实现逐帧动画需要使用到的是Animation动画,该CSS3的Animation有八个属性:分别是如下:1: animation-name2: animation-durati ...
- Esfog_UnityShader教程_逐帧动画
有段日子没出这个系列的新文章了,今天就拿一个比较常见也比较基础的利用改变Shader来改变不断调整UV实现播放逐帧动画的小功能.很久没写了就当练练手了.在新版本的Unity中早就已经集成了Sprite ...
随机推荐
- Linux主机定期打补丁修复漏洞
1.如图扫描出来的漏洞 不看不知道,一看吓一跳 2.Linux主机如何扫描漏洞 参照:Linux操作系统下查找漏洞的几种必备兵器 3.linux操作系统怎么样打补丁?linux系统升级软件 使用yu ...
- C#语言————第四章 常用Convert类的类型转换方法
方法 说明Convert.ToInt32() 转换为整型(int 型)Convert.ToStringle() 转换为单精度浮点型(float 型)Convert.ToDouble() 转换为双精度 ...
- 系统运维|SqlServer2008|数据库日志文件过大需要清理的操作攻略
摘要: 1.执行SQL语句改成“简单模式” 2.收缩数据库 3.执行SQL语句改回“完全模式” 原文链接: http://www.lookdaima.com/WebForms/WebPages/B ...
- 【阿里八八】团队Alpha博客链接目录
团队Alpha冲刺博客 阿里八八Alpha阶段Scrum(1/12) 阿里八八Alpha阶段Scrum(2/12) 阿里八八Alpha阶段Scrum(3/12) 阿里八八Alpha阶段Scrum(4/ ...
- jsp 一点点
jsp学习 jsp -处理 作为正常的页面,你的浏览器发送一个http请求道web服务器. web 服务器承认一个JSP页面的HTTP请求,并将其转发给一个JSP引擎. JSP引擎从磁盘加载JSP页面 ...
- Axios发送请求时params和data的区别
在使用axios时,注意到配置选项中包含params和data两者,以为他们是相同的,实则不然. 因为params是添加到url的请求字符串中的,用于get请求. 而data是添加到请求体(body) ...
- web笔试
类型判断用到哪些方法? typeof和instanceof 值类型和引用类型的区别? 根据 JavaScript中的变量类型传递方式,又分为值类型和引用类型,在参数传递方式上,值类型是按值传递,引用类 ...
- 2018-2019-2 网络对抗技术 20165318 Exp3 免杀原理与实践
2018-2019-2 网络对抗技术 20165318 Exp3 免杀原理与实践 免杀原理及基础问题回答 实验内容 任务一:正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil- ...
- Difference Between InnoDb and MyISAM(个人觉着是好文章,简单易懂,推荐看)
原文地址:http://acmeextension.com/difference-between-innodb-and-myisam/ MyISAM and InnoDB are the most c ...
- Idea设置快捷键以及修改Eclipse的debug快捷键
Idea强大不多说了,用久了都可以习惯,但是感觉Idea的debug真是不如eclipse好用,Idea的快捷键都是组合键,用着繁琐.两种方法可以设置eclipse的快捷键: 1:直接全局都使用ecl ...