css3中創建動畫的三種方式詳解

一、介紹

創建動畫有多種方式,除了傳統的利用setInterval來不斷改變元素的屬性值,和最新canvas中requestAnimationFrame以外,此處介紹三種創建動畫的方式。總的來說,這三種都可以歸爲css3的動畫方式,但是,不同的方式伸展拳腳的地方也就不一樣。(注意,此處三種方式均基於JQuery)

二、創建動畫的三種方式

1、css() + transform

這是最簡單的一種方式,利用$(id).css()方法添加一個transform屬性即可(同理可添加animation屬性)。
$div.css({
  "transition-timing-function" : "linear",
  "transition-duration" : "3000ms",
  "transform" : "translateX(300px)"
});

2、addClass() + animation

這是利用了JQuery的addClass()方法,及css3的animation動畫屬性。
此處必須先定義好一個animation,然後再定義一個有該animation的class類,在addClass()方法中將該class類添加到元素中。代碼如下:
定義animation和class
.ani_class {
  animation: div3_ani 3s linear forwards;
}
@keyframes div3_ani {
  0% {
    transform: none;
  }
  100% {
    transform: translate(300px, 0);
  }
}
添加到元素中
$div2.addClass("ani_class");

3、JQuery transit插件

這是jQuery引入的一種新的方式,需要引入jquery.transit.js,詳細教程請自行查資料。這裏只是簡單介紹:
$div3.transition({
  transform : "translateX(300px)"
},3000,"linear");

三、三種方式的結束事件捕捉

在這裏,除了第一種css + transform無法捕捉到結束事件以外(也可能我未發現),其他兩種都能捕捉到,代碼如下:

1、addClass() + animation

//可捕捉結束事件
$div2.addClass("ani_class").on(animationEnd(),function(){
  alert("addClass() + transform animation end");
});

此處的animationEnd()根據不同瀏覽器返回animationend事件的字符串,代碼如下:

function animationEnd(){
  var explorer = navigator.userAgent;
  if( ~explorer.indexOf("WebKit") ){
    return 'webkitAnimationEnd';
  }
  return 'animationend';
}

2、JQuery transit

//可捕捉結束事件
$div3.transition({
    transform : "translateX(300px)"
},3000,"linear", function(){
    alert("transition end");
});

四、利用結束事件進行動畫鏈式嵌套編程

有些時候我們需要讓動畫按順序播放,同時又能在各個關鍵點有效控制它,那麼就要進行動畫的鏈式編程。由於我們可以捕捉到動畫的結束事件,那麼直接在結束事件加入下一步動畫即可。代碼如下:

1、addClass() + animation

$div1.addClass("ani_class").on("webkitAnimationEnd",function(){
    $div2.addClass("ani_class").on("webkitAnimationEnd",function(){
        $div3.addClass("ani_class").on("webkitAnimationEnd",function(){
            alert("addClass animation end!");
        });
    });
});

2、JQuery transit

$div1.transition({
    transform : "translateX(300px)"
},3000,"linear", function(){
    $div2.transition({
        transform : "translateX(300px)"
    },3000,"linear", function(){
        $div3.transition({
            transform : "translateX(300px)"
        },3000,"linear", function(){
            alert("transition end");
        });
    });
});

五、非嵌套式鏈式動畫

相信你也看出來了,嵌套式鏈式動畫對開發人員來說很不友好,稍微一個小小的動畫就有可能嵌套上百行,對於維護和修改極爲不利。
所以此處我們引入JQuery的Deferred對象。Deferred對象最早是爲AJAX異步加載所建立的,用於AJAX請求的回調,讓開發人員從多個AJAX請求的回調嵌套方法中解脫出來。
而在這裏,我們也可以將其引入到動畫中,以增強動畫的鏈式編程效果,簡化開發。
(有關Deferred對象的詳細資料請自行學習,由於脫離本文主題,不在此做詳細介紹)
此處我們先定義兩個方法,這兩個方法的原理分別用到了前面所說的addClass()和JQuery transit,但是它們都有一個共同點,在事件結束時都修改了defer屬性,並將其返回。
//addClass + animation
function addClassAni(element){
    var defer = $.Deferred();
    element.addClass("ani_class").on(animationEnd(),function(){
        defer.resolve();
    });
    return defer;
}
//JQuery transit
function addTransitAni(element){
    var defer = $.Deferred();
    element.transition({
        transform : "translateX(300px)"
    },3000,"linear", function(){
        defer.resolve();
    });
    return defer;
}
然後就可以愉快的利用Deferred進行鏈式編程啦!
addClassAni($div1).then(function(){
    return addClassAni($div2);
}).then(function(){
    return addTransitAni($div3);
}).then(function(){
    return addTransitAni($div4);
}).then(function(){
    alert("animation end!");
});
此處每一步都會返回一個Deferred對象,下一步操作做什麼要視該Deferred對象的狀態。
同時,如果某些動畫並非要等上一個動畫執行完才執行,那麼只需讓上一步動畫不返回Deferred對象即可。如下:
addClassAni($div1).then(function(){
    return addClassAni($div2);
}).then(function(){
    addTransitAni($div3);
}).then(function(){
    return addTransitAni($div4);
}).then(function(){
    alert("animation end!");
});
此處的$div3會與$div4會等$div2動畫完成後共同移動。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章