[关闭]
@Sakura-W 2016-09-25T12:43:29.000000Z 字数 4781 阅读 1801

Web Animation

网络


一、简介

有两种方式可以用于创建Web动画:CSS和JavaScript。选择哪一种方式取决于项目的其他依赖以及想要达到的效果。
选择原则如下:

1)当UI元素发生较小的独立状态改变时,使用CSS。比如导航菜单或者文字提示等。虽然最终可以使用JavaScript来控制状态切换,但动画本身采用CSS。
2)当需要对动画进行大量的控制的时候,使用JavaScript。动态跟踪触摸位置的动画或需要停止、暂停、减速或倒退的动画一般需要使用JavaScript。
3)当要重新手动绘制整个画面的时候,采用requestAnimationFrame。比如创建一个游戏或者HTML canvas应用

二、CSS 动画

1、使用transition属性

HTML:

  1. <div class="box"></div>

CSS:

  1. .box{
  2. width: 200px;
  3. height: 200px;
  4. margin-left: 20px;
  5. margin-top: 20px;
  6. box-shadow: 0px 0px 5px #444;
  7. transform: translate(0,0);
  8. transition: transform .5s;
  9. -webkit-transform: translate(0,0);
  10. -webkit-transition: transform .5s;
  11. }
  12. .box.move{
  13. transform: translate(200px,200px);
  14. -webkit-transform: translate(200px,200px);
  15. }

JavaScript:

  1. (function(){
  2. var box = document.querySelector(".box");
  3. box.addEventListener("click", function(){
  4. if(this.classList.value.indexOf("move") != -1){//表示classList里面有move
  5. this.classList.remove("move");
  6. }else{
  7. this.classList.add("move");
  8. }
  9. }, false);
  10. }());

所以,常见的用法就是用JavaScript来控制状态,即为动画元素添加类名,用CSS来实现动画。也可以监听transitionend事件(transition结束事件),但IE,只有IE10及以上版本才支持,其他浏览器都在某些版本支持:

  1. box.addEventListener("transitionend", function(){
  2. if(this.style.backgroundColor === ""){
  3. this.style.backgroundColor = "red";
  4. }else{
  5. this.style.backgroundColor = "";
  6. }
  7. }, false);

以上代码在动画结束后改变box盒子的颜色。

2、使用animation属性

HTML:

  1. <div class="box"></div>

CSS:

  1. .box{
  2. width: 200px;
  3. height: 200px;
  4. margin-left: 20px;
  5. margin-top: 20px;
  6. box-shadow: 0px 0px 5px #444;
  7. animation-name: movingBox;
  8. animation-duration: 1s;
  9. animation-fill-mode: farwards;
  10. animation-iteration-count: infinite;;
  11. }
  12. @keyframes movingBox {
  13. 0%{
  14. transform: translate(0,0);
  15. }
  16. 25%{
  17. transform: translate(100px,0);
  18. }
  19. 50%{
  20. transform: translate(100px,100px);
  21. }
  22. 75%{
  23. transform: translate(0,100px);
  24. }
  25. 100%{
  26. transform: translate(0,0);
  27. }
  28. }

利用animation属性可以在不用JavaScript的情况下实现动画的各种状态的切换。

二、JavaScript动画

1、使用Web动画API创建动画

HTML:

  1. <div class="box"></div>

JavaScript:

  1. (function(){
  2. var box = document.querySelector(".box");
  3. var player = box.animate([
  4. {transform: "translate(0)"},
  5. {transform: "translate(100px, 100px)"}
  6. ], 500);
  7. player.addEventListener("finish", function(){
  8. box.style.transform = "translate(100px, 100px)";
  9. });
  10. }());

目前Chrome和Opera已经支持动画API,Firefox正在开发,对于其他浏览器则可以采用兼容工具:web-animations.
Web动画API参考:Web Animations

2、使用setTimeout和setInterval实现动画

我们通常使用定时器来循环改变目标物体的状态,从而实现动画。一般而言,用setTimeout做动画比setInterval性能更高:
HTML:

  1. <div class="box"></div>

CSS:

  1. .box{
  2. position: absolute;//要求绝对定位
  3. left: 0;
  4. top: 0;
  5. width: 200px;
  6. height: 200px;
  7. box-shadow: 0px 0px 5px #444;
  8. }

JavaScript:

  1. (function(){
  2. var box = document.querySelector(".box");
  3. function move(){
  4. box.style.left = box.offsetLeft + 5 + "px";
  5. if(box.offsetLeft <= 300){
  6. setTimeout(move, 30);
  7. }
  8. }
  9. setTimeout(move, 0);
  10. }());

用以上方式模拟setInterval,性能更高!!

3、使用requestAnimationFrame实现动画

语法:requestAnimationFrame()函数与setTimeout类似,该函数接收一个函数作为参数,该函数通常会在1秒内调用60次,这样动画呈现更加流畅。该函数接收一个参数,表示当前时间,即调用该函数的时间点。

var animate = window.requestAnimationFrame(callback);

该函数返回一个长整型数值,便于取消动画(类似定时器):

window.cancelAnimationFrame(animate);

例子:

  1. (function(){
  2. var box = document.querySelector(".box");//该元素也需要绝对定位
  3. var start = null;
  4. function step(timestamp){
  5. if(!start){
  6. start = timestamp;
  7. }
  8. console.log(start);
  9. console.log(timestamp);
  10. var progress = timestamp - start;
  11. box.style.left = Math.min(progress/10, 200) + "px";
  12. if(progress < 2000){//终止条件是box.offsetLeft < 200,这样就不用实时检测了
  13. window.requestAnimationFrame(step);
  14. }
  15. }
  16. window.requestAnimationFrame(step);
  17. }());

简单兼容写法:

  1. window.requestAnimFrame = (function(){
  2. return window.requestAnimationFrame ||
  3. window.webkitRequestAnimationFrame ||
  4. window.mozRequestAnimationFrame ||
  5. function( callback ){
  6. window.setTimeout(callback, 1000 / 60);
  7. };
  8. }());

Paul Irish及其他贡献者放在GitHub Gist上的代码片段,用于在浏览器不支持requestAnimationFrame情况下的回退:

  1. // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
  2. // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
  3. // requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
  4. // MIT license
  5. (function() {
  6. var lastTime = 0;
  7. var vendors = ['ms', 'moz', 'webkit', 'o'];
  8. for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
  9. window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
  10. window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
  11. }
  12. if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback, element) {
  13. var currTime = new Date().getTime();
  14. var timeToCall = Math.max(0, 16 - (currTime - lastTime));
  15. var id = window.setTimeout(function() {
  16. callback(currTime + timeToCall);
  17. }, timeToCall);
  18. lastTime = currTime + timeToCall;
  19. return id;
  20. };
  21. if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) {
  22. clearTimeout(id);
  23. };
  24. }());

requestAnimationFrame()函数是针对动画效果的API。采用这个API,浏览器可以优化并行的动画动作,更合理的重新排列动作序列,并把能够合并动作放在一个渲染周期内完成,从而呈现更流畅的动画效果。通过requestAnimationFrame(),JS动画能够和CSS动画或SVG SMIL动画同步发生。另外,如果在一个浏览器标签页内运行一个动画,当这个标签不可见时,浏览器会暂停它,节省资源。

参考:
CSS vs JavaScript animations
window.requestAnimationFrame()
Web动画的几种实现方法

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注