标签:动画 canvas animation gpu css3
一、背景:
合适的动画不仅更能吸引人们的眼球,也能让你的应用体验更为流畅,而将动画的效果做到极致,才能让用户感到使用你的应用是一种享受,而不是觉得生硬和枯燥。
二、动画技术分类:
按技术类型来进行分类,分为三类:JS动画,CSS3动画,html5动画,接下来分别对三类动画进行讲解。
1)JS动画
通过一个定时器setInterval间隔来改变元素样式,动画结束时clearInterval即可。(早期类库:jquery、prototype、mootools)
优缺点:
优点:可控性很强,兼容性较好
缺点:
1、性能不佳:因为需要不断获取和修改dom布局,所以导致了大量页面重排(repaint);
2、缺乏标准:不同的库使用了不同的API,导致即使是简单的动画也有各不相同的实现方式,调整起来比较耗时;
3、带宽消耗:相对丰富的动画库代码量都很大,结果就是增加了http请求的大小,降低了页面的载入时间。
2)css3动画
css3两种动画实现方式:一种是transition,一种是animation,animation相比transition使用起来更为复杂。
transition包含4种属性:transition-delay、transition-duration、transition-property、transition-timing-function,对应动画的4种属性:延迟、持续时间、对应CSS属性和缓动函数。
transform包含7种属性:animation-name、animation-duration、animation-timing-function、animation-delay、animation-direction、animation-iteration-count、animation-fill-mode、animation-play-state,对应动画名称、持续时间、缓动函数、动画延迟、动画方向、重复次数、填充模式。
优点:
1、css3动画相比JS更轻量,性能更好,更易于实现。
2、不必担心缺乏标准和增加带宽消耗的问题。
3、不依赖于主线程,采用硬件加速(GPU)
4、move.js是一个封装了css3动画效果的轻量级js动画库。
缺点:
1、不能动态的修改或定义动画内容
2、不同的动画无法实现同步
3、多个动画彼此无法堆叠
示例:2-1 Transitions动画 (过渡动画)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
.animate {
width: 200px;
height: 200px;
margin: 0 auto;
border-radius: 50%;
background-color: #f00;
line-height: 200px;
border-radius: 50%;
text-align: center;
color: #fff;
font-size: 20px;
}
.animate-transition {
transition: transform 2s linear;
-moz-transition: -moz-transform 2s linear;
-webkit-transition: -webkit-transform 2s linear;
-o-transition: -o-transform 2s linear;
}
.animate-transition:hover {
cursor: pointer;
transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
}
</style>
</head>
<body>
<div class="animate animate-transition">Transition Animation</div>
</body>
</html>
示例2-2:keyframes animation(关键帧动画)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
.animate {
width: 200px;
height: 200px;
margin: 0 auto;
border-radius: 50%;
background-color: #f00;
line-height: 200px;
border-radius: 50%;
text-align: center;
color: #fff;
font-size: 20px;
}
.animate-keyframes {
-webkit-animation: none;
}
.animate-keyframes:hover {
cursor: pointer;
-webkit-animation: frames 2s linear infinite;
}
@-webkit-keyframes frames {
0% {
background-color: #f00;
-webkit-transform: rotate(0deg);
}
100% {
background-color: #f00;
-webkit-transform: rotate(360deg);
}
}
</style>
</head>
<body>
<div class="animate animate-keyframes">Transition Animation</div>
</body>
</html>
3)html5动画
html5定义了三种绘图的方式,canvas,svg,webGL,其中svg作为一种可缩放矢量图形的实现是基于xml标签定义的,它有专门的animate标签来定义动画。而为canvas或者webGL实现动画则需要通过requestAnimationFrame(简称raf)来定期刷新画布。尽管raf的方式会让代码变得复杂,但是因为不需要那么多的文档对象(通常浏览器只需要管理一个画布),它的性能也好很多,尤其是在内存吃紧的移动端上面。
3-1 svg动画:
示例:3-1
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
.animate-svg {
width: 200px;
margin: 0 auto;
}
</style>
</head>
<body>
<div class="animate-svg">
<svg id="svgAnimation" ns="http://www.w3.org/2000/svg" version="1.1" width="200" height="200">
<g transform="translate(100, 100)">
<g>
<rect width="200" height="200" rx="100" ry="100" fill="red" transform="translate(-100, -100)"></rect>
<text x="-60" y="-0" font-size="20" fill="white">SVG Animation</text>
<animateTransform attributeName="transform" attributeType="xml" type="rotate" from="0" to="360" dur="3s" repeatCount="indefinite">SVG Animation</animateTransform>
</g>
</g>
</svg>
</div>
</body>
</html>
svn动画优缺点:
优点:
1) 矢量图形,不受像素影响,这个特性在不同的平台或者媒体下表现良好;
2) SVG对动画支持较好,其DOM结构可以被其特定语法或者js控制
3) SVG的结构是XML,其可访问性、可操作性、可编程性、可被CSS样式化完胜Canvas。另外,其支持ARIA属性
缺点:
1) DOM比正常的图形慢,而且如果其节点多而杂,就更慢。
2) 不能动态修改动画内容
3)不能与HTML内容集成,整个SVG作为一个动画
3-2:requestAnimationFrame(简称raf)接口改进手段+结合js来实现高性能的动画。主要手段如下:
优点:
1、在每次浏览器更新页面时,能获取通知并执行应用,简单理解为RAF能在每个16.7ms间执行一次咱们的函数。
2、最小化的消耗资源,RAF在页面被切换或浏览器最小化时,会暂停执行,等页面再次关注时,继续执行动画。
3、在移动设备上使用3d硬件加速,最简单办法就是添加-webkit-transform: translateZ(0),原因是移动端的显卡有很强的图形渲染能力,而每个应用的webview内存却是极其有限的。
4、js配合h5可控性好,这方面做的最全面的有Velocity.js,不过tween.js也很棒(从flash算法移植过来的,专注与动画的数值计算)。
缺点:
1、无法控制执行时间,执行时间由系统根据屏幕刷新时间决定
2、浏览器兼容问题,低版本浏览器降级处理,使用setInterval或setTimeout
示例3-2:requestAnimationFrame制作旋转特效
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
.animate {
width: 200px;
height: 200px;
margin: 0 auto;
border-radius: 50%;
background-color: #f00;
line-height: 200px;
border-radius: 50%;
text-align: center;
color: #fff;
font-size: 20px;
}
.animate-input {
margin-top: 10px;
text-align: center;
}
</style>
</head>
<body>
<div id="animate-RAF" class="animate animate-RAF">RAF Animation</div>
<div class="animate-input"><input type="button" id="btn_start" value="Start" style="width:100px;height:30px;" /></div>
<script type="text/javascript">
var animate_raf = document.getElementById("animate-RAF"),
btn_start = document.getElementById("btn_start"),
frameid = null;
function frame(time) {
animate_raf.style[‘-webkit-transform‘] = ‘rotate(‘ + Math.cos(time/1000) * 360 + ‘deg)‘;
frameid = requestAnimationFrame(frame);
}
// 绑定事件
btn_start.addEventListener("click", function(event) {
var val = this.value;
if (val == "Start") {
frameid = requestAnimationFrame(frame);
this.value = "Pause";
} else {
this.value = "Start";
cancelAnimationFrame(frameid);
}
}, false);
</script>
</body>
</html>
3-3:Canvas动画
优点:
1)画2D图形中,页面渲染性能比较高,页面渲染性能受图形复杂度影响小,渲染性能只受图像的分辨率的影响
2)画出来的图形可以直接保存为.png或者.jpg的图形
3)最适合于画光栅图像(如游戏和不规则集合图形等)
缺点:
1)整个一张图,没有dom节点可供操作;
2)没有实现动画的API,你必须依靠定时器和其他事件来更新Canvas
3)对文本的渲染支持是比较差
4)对要求有高可访问性(盲文、声音朗读等)页面,比较困难
3-4:WebGL
WebGL是一种3D绘图标准,这种绘图技术标准允许把JavaScript和OpenGL ES2.0结合在一起,通过增加OpenGL ES2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型, 还能创建复杂的导航和数据视觉化。
3-5 问题思考:
1、不必要维护来支持多种方式实现同样的事情;
2、Web开发人员需要学习多种实现技术;
3、js不容易设置声明式动画。
4、flash动画(已慢慢过时)
三、动画基本属性
相关概念:绘制频率、屏幕刷新频率、硬件加速、60fps
绘制频率:页面每一帧变化都是系统绘制出来的(GPU或者CPU)。
它的最高绘制频率受限于显示器的刷新频率(而非显卡),所以大多数情况下最高的绘制频率只能是每秒60帧(frame per second,简称fps),对应于显示器的60Hz。
刷新频率:图像在屏幕上更新的速度,也就是屏幕上的图像每秒出现的次数,单位是Hz,刷新频率越高,屏幕上图片闪烁感就越小,稳定性也就越高。人的眼睛不容易察觉75Hz以上刷新频率带来的闪烁感。
硬件加速:
硬件有三个处理器:CPU、GPU和APU(声音处理器)。他们通过PCI/AGP/PCIE总线交换数据。
GPU在浮点运算、并行计算等部分计算方面,明显高于CPU的性能。
60Hz和60fps关系:
fps代表GPU渲染画面的频率,Hz代表显示器刷新屏幕的频率。游戏里谈到掉帧,是指GPU渲染画面频率降低。比如跌落到30fps甚至20fps,但因为视觉暂留原理,我们看到的画面仍然是运动和连贯的。
四、web Animations 1.0 通用动画模型
web Animations API为css和svg动画提供了单一接口。旨在通过提供更好的性能、更好的控制时间线和播放、灵活、统一的JavaScript编程接口。
示例:4-1:点击旋转效果
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
.animate {
width: 200px;
height: 200px;
margin: 0 auto;
border-radius: 50%;
background-color: #f00;
line-height: 200px;
border-radius: 50%;
text-align: center;
color: #fff;
font-size: 20px;
cursor: pointer;
}
.web-animation-1 {
-webkit-transform: rotate(360deg);
}
</style>
</head>
<body>
<div id="web_animation_1" class="animate web-animation-1">Web Animation-1</div>
<script src="web-animations.js"></script>
<script type="text/javascript">
var web_animation_1 = document.getElementById("web_animation_1");
web_animation_1.addEventListener(‘click‘, function() {
web_animation_1.animate([{
transform: ‘rotate(0deg)‘
}, {
transform: ‘rotate(360deg)‘
}],{
duration: 2
});
}, false);
</script>
</body>
</html>
示例:4-2:更复杂时序(正负旋转)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
.animate {
width: 200px;
height: 200px;
margin: 0 auto;
border-radius: 50%;
background-color: #f00;
line-height: 200px;
border-radius: 50%;
text-align: center;
color: #fff;
font-size: 20px;
cursor: pointer;
}
.web-animation-2 {
-webkit-transform: rotate(360deg);
}
</style>
</head>
<body>
<div id="web_animation_2" class="animate web-animation-2">Web Animation-2</div>
<script src="web-animations.js"></script>
<script type="text/javascript">
var web_animation_2 = document.getElementById("web_animation_2");
web_animation_2.addEventListener(‘click‘, function() {
web_animation_2.animate([{
transform: ‘rotate(0deg)‘
}, {
transform: ‘rotate(360deg)‘
}],{
// 旋转方向
direction: "alternate",
// 旋转值
duration: 1,
// 迭代
iterations: Infinity,
// 缓解过渡
easing: ‘ease-in-out‘,
// 播放速率
playbackRate: 2
});
}, false);
</script>
</body>
</html>
示例:4-3 并行动画
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
.web_animation_4 {
width: 700px;
margin: 0 auto;
padding: 10px;
background-color: #ccc;
cursor: pointer;
}
.web_animation_4 .par-timing-box {
background-color: #00f;
height: 20px;
margin: 10px;
}
</style>
</head>
<body>
<div id="web_animation_4" class="web_animation_4">
<div id="parItem1" class="par-timing-box" style="width: 500px;"></div>
<div id="parItem2" class="par-timing-box" style="width: 700px;"></div>
<div id="parItem3" class="par-timing-box" style="width: 200px;"></div>
</div>
<script src="web-animations.js"></script>
<script type="text/javascript">
var web_animation_4 = document.getElementById("web_animation_4"),
parItem1 = document.getElementById("parItem1"),
parItem2 = document.getElementById("parItem2"),
parItem3 = document.getElementById("parItem3");
web_animation_4.addEventListener(‘click‘, function() {
var obj = new ParGroup([
new Animation(parItem1, [{width: ‘0px‘}, {width: ‘500px‘}], 1),
new Animation(parItem2, [{width: ‘0px‘}, {width: ‘700px‘}], 1),
new Animation(parItem3, [{width: ‘0px‘}, {width: ‘200px‘}], 1)
]);
document.timeline.play(obj);
}, false);
</script>
</body>
</html>
还有很多的例子..大家可以多尝试
五、现行动画实现方案:
1)页面增强动画建议使用CSS动画
2)复杂动画交互建议使用RAF及setInterval或setTimeout优雅降级处理
3)业界主流动画库:
Velocity.js是一款动画切换的jQuery插件,包含(颜色切换、转换(transform)、循环缓动、CSS切换、Scroll功能),支持Android和ios,内部使用jQuery的$.queue方法,如果能将Velocity.js依赖jQuery插件变为js原生来实现,在移动端的作用将更加明显。
4)Swipe JS 一款移动端触摸滑块幻灯片插件,不但能够使用于各种操作系统的手机,还能够利用H5的硬件加速功能来完成滑块的切换效果,其效果以及实用性非常强。
六、css动画比JS流畅度对比:
根据Google Developer Chromium项目,渲染线程分为main thread和compositor thread。
如果CSS动画只是改变transforms和opacity,这时整个CSS动画得以在compositor thread完成(而js动画则会在main thread执行,然后触发compositor进行下一步操作)
在JS执行一些昂贵的任务时,main thread繁忙,CSS动画由于使用了compositor thread可以保持流畅。
在主线程中,维护了一棵Layer树(LayerTreeHost),管理了TiledLayer,在compositor thread,维护了同样一颗LayerTreeHostImpl,管理了LayerImpl,这两棵树的内容是拷贝关系。因此可以彼此不干扰,当JavaScript在main thread操作LayerTreeHost的同时,compositor thread可以用LayerTreeHostImpl做渲染。当JavaScript繁忙导致主线程卡住时,合成到屏幕的过程也是流畅的。为了实现防假死,鼠标键盘消息会被首先分发到compositor
thread,然后再到main thread。这样,当main thread繁忙时,compositor thread还是能够响应一部分消息,例如,鼠标滚动时,加入main thread繁忙,compositor thread也会处理滚动消息,滚动已经被提交的页面部分。
CSS动画比JS流畅的前提:
1)在Chromium基础上的浏览器中
2)JS在执行一些昂贵的任务
3)同时CSS动画不触发layout或paint
在CSS动画或JS动画触发了paint或layout时,需要main thread进行Layer树的重计算,这时CSS动画或JS动画都会阻塞后续操作。
根据CSS Triggers,只有如下属性的修改才符合“仅触发Composite,不触发layout或paint”:
backface-visibility: 指定当元素背面朝向观察者时是否可见。
opacity: 透明度
perspective: 定于3D元素距视图的距离
perspective-origin: 定义3D元素所基于的X轴和Y轴
transform: 设置元素变形、旋转、缩放、倾斜。
所以只有用上了3D加速活修改opacity时,才有机会用得上CSS动画的这一优势。
因此,在大部分应用场景下,效率角度更值得关注还是下列问题。
是否导致layout
repaint的面积
是否有高消耗的属性(css shadow等)
是否启用硬件加速。
css动画和JS动画主要的不同点是
功能涵盖面,JS比CSS3大
定义动画过程的@keyframes不支持递归定义,如果有多种类似的动画过程,需要调节多个参数来生成的话,将会有很大的冗余
时间尺度上,@keyframes动画粒度粗,而JS的动画粒度控制可以很细
CSS3动画里被支持的时间函数非常少,不够灵活
以现有的接口,CSS3动画无法做到支持两个以上的状态转化
实现重构难度不一,CSS3比JS更简单,性能调优方向固定
对于帧速表现不好的低版本浏览器,CSS3可以做到自然降级,而JS则需要撰写额外代码
css3有兼容性问题,而JS大多时候没有兼容性问题。
七、常见动画效果分类
公司内部常见活动页动画库:
1、modPageSlide组件:H5活动页整屏滑动切换功能,提供多种切换方式;
2、H5FullscreenPage组件:全屏滚动效果组件
3、iSlider:高性能H5滑屏组件
4、css3的滑屏组件
5、WebApp手机活动页模板
6、ELego.js:CSS3动画流水式编程框架
7、smartclick:移动设备HTML5点击高亮组件
业界常使用的一些动画库:
1、css3动画:move.js
2、动画切换的jQuery插件:velocity.js
3、移动web内容滑块类库:swipe.js
4、提供CSS、SVG动画的单一接口:Web Animations API
5、基于H5高性能js动画库:Collie
八、号称DOM动画的四大神器
位移:transform: translate(npx, npx);
缩放:transform: scale(n);
旋转:transform: rotate(ndeg);
透明:opacity: 0 ~ 1;
前端能力模型-动画类型及动画库的介绍
标签:动画 canvas animation gpu css3
原文地址:http://blog.csdn.net/zqjflash/article/details/44903859