.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); })();
這是一般透過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';
透過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';
最後「CSS Animation + steps()」此方式才是目前針對Sprite Animation最佳的解法,尤其是iOS/Android平台均支援此方法。
參考資料