.2013/01/22 新增CSS Animation + steps()
Sprite是一種經常被用於遊戲開發的技巧,如:Super Mario、Rockman,另一方面也常被用於網頁優化(Web Optimization)之中,將許多小圖檔組合成一張大圖,以減少這些小圖HTTP的請求次數,不過本文並非針對該議題,而是要探討如何透過CSS Animations結合Sprite來達成動畫效果,藉由Browser原生支援的方式,以減少JavaScript的程式運算來提升效率,下述例子將利用Google衣夾人(Google Street View 心得)來示範:
P.S. 目前W3C CSS Animations規格仍在Working Draft狀態。
JavaScript
var offsetX = [0, 49, 98, 147, 196, 245, 294, 343, 392, 441, 490, 539, 588, 637, 686, 735];
var olen = offsetX.length;
s.style.width = "49px";
s.style.height = "51px";
s.style.backgroundImage = "url(img/panda_001.png)";
s.style.backgroundSize = "1029px 51px";
s.style.backgroundPosition = "0px 0px";
s._ox = 0;
_main.appendChild(s);
(function animate(){
s.style.backgroundPosition = '-'+offsetX[s._ox++%olen]+"px 0px";
setTimeout(animate,33);
})();
Demo
這是一般透過JavaScript的方式,若從效率上的觀點來看它並不是最佳的解法。
CSS Animation
CSS
@-webkit-keyframes panda
{
0% { background-position: 0px 0px; }
6.25% { background-position: 0px 0px; }
6.26% { background-position: -49px 0px; }
12.5% { background-position: -49px 0px; }
12.51% { background-position: -98px 0px; }
18.75% { background-position: -98px 0px; }
18.76% { background-position: -147px 0px; }
25% { background-position: -147px 0px; }
25.01% { background-position: -196px 0px; }
31.25% { background-position: -196px 0px; }
31.26% { background-position: -245px 0px; }
37.5% { background-position: -245px 0px; }
37.51% { background-position: -294px 0px; }
43.75% { background-position: -294px 0px; }
43.76% { background-position: -343px 0px; }
50% { background-position: -343px 0px; }
50.01% { background-position: -392px 0px; }
56.25% { background-position: -392px 0px; }
56.26% { background-position: -441px 0px; }
62.5% { background-position: -441px 0px; }
62.51% { background-position: -490px 0px; }
68.75% { background-position: -490px 0px; }
68.76% { background-position: -539px 0px; }
75% { background-position: -539px 0px; }
75.01% { background-position: -588px 0px; }
81.25% { background-position: -588px 0px; }
81.26% { background-position: -637px 0px; }
87.5% { background-position: -637px 0px; }
87.51% { background-position: -686px 0px; }
93.75% { background-position: -686px 0px; }
93.76% { background-position: -735px 0px; }
99.99% { background-position: -735px 0px; }
100% { background-position: 0px 0px; }
}
JavaScript
s.style.width = "49px";
s.style.height = "51px";
s.style.backgroundImage = "url(img/panda_001.png)";
s.style.backgroundSize = "1029px 51px";
s.style.backgroundPosition = "0px 0px";
s.style.webkitAnimation = 'panda 500ms linear infinite';
純粹透過CSS Animation的方式看起來有點冗長,不過這並不是啥大問題,因為上述的CSS Animation可以寫個function來產生,但這也不是最好的解決方式,因為上述這種方式會有spurt的問題(Demo),尤其在效率較差的Mobile平台上更顯而易見。
CSS Animation + Transform
CSS
@-webkit-keyframes panda
{
0% { background-position: -0px 0px; }
100% { background-position: -15px 0px; }
}
JavaScript
s.style.width = "1px";
s.style.height = "1px";
s.style.webkitTransform = "scaleX(49) scaleY(51)";
s.style.backgroundImage = "url(img/panda_001.png)";
s.style.backgroundSize = "21px 1px";
s.style.webkitAnimation = 'panda 500ms linear infinite';
Demo
透過CSS Animation + Transform似乎是個不錯的方式,但若從Mobile平台來看~ 目前iOS 6.0 Safari、Android Chrome Browser支援度都還不好,僅有最近才剛上架的Chrome beta for Android(2013/01/10)有支援。
CSS Animation + steps()
CSS
@-webkit-keyframes panda
{
from { background-position: 0px; }
to { background-position: -784px; }
}
JavaScript
s.style.width = "49px";
s.style.height = "51px";
s.style.backgroundImage = "url(img/panda_001.png)";
s.style.webkitAnimation = 'panda 500ms steps(16,end) infinite';
Demo
最後「CSS Animation + steps()」此方式才是目前針對Sprite Animation最佳的解法,尤其是iOS/Android平台均支援此方法。
參考資料
.Sprite animation in CSS3
.Taking steps() with CSS animations