依照指定的時間執行動作or動畫效果
Tue, 13 Jan 2009 15:53:50 +0800期末報告的季節又到了...
看到有人在論壇上求助,html的作業要求做出配合音樂節拍播放圖片......(嗯嗯,對於初學者來說,恐怕有點難),有一點好奇,所以手動試了一下,怎麼做出依照給定時間執行動作的效果。
以下是程式:
<html> <body> <div id="panel"><img src="bg/char1.gif"></div> <script> (function(){ var component = { target: null, init: function(x) {this.target = x; return this;}, click: function(f) {this.target.onclick = f; return this;}, html: function(t) {this.target.innerHTML = t; return this;}, actionSequencer: function(t) { var target = this.target; var duration = t.duration|0; var action = t.action|[]; action = t.action.sort(function(a,b){return a[0]-b[0];}); var drop = t.drop|false; var start; var curr = start = new Date().getTime(); var timer = true; var currTimeUpdater = window.setInterval(function(){ if(timer) { curr = new Date().getTime(); } else { window.clearInterval(currTimeUpdater); } },1); var timerStop = window.setInterval(function(){ if ((curr - start) > duration) { timer = false; window.clearInterval(timerStop); } },1); var actionHandler = window.setInterval(function(){ if(timer) { if(action.length>0&&(curr-start) > action[0][0]) { if(!drop) { var a = window.setTimeout(function(){ window.clearTimeout(a); action[0][1](target); action.shift(); }, 1); } else { for(var i=0; i<action.length; i++) { if(action[i][0] > curr-start) { var b = window.setTimeout((function(j){ window.clearTimeout(b); return function(){ action[j][1](target); };})(i),1); return; } } } } } else { window.clearInterval(actionHandler); } },1); return this; } }; $ = function(x) { return component.init(x); }; })(); $(document.getElementById("panel")).click(function(){ $(this).actionSequencer( { duration: 1000, action: [ [100, function(target){$(target).html('<img src="bg/char1.gif">');}], [200, function(target){$(target).html('<img src="bg/char2.gif">');}], [300, function(target){$(target).html('<img src="bg/char3.gif">');}], [400, function(target){$(target).html('<img src="bg/char5.gif">');}], [500, function(target){$(target).html('<img src="bg/char4.gif">');}], [600, function(target){$(target).html('<img src="bg/char6.gif">');}], [700, function(target){$(target).html('<img src="bg/char7.gif">');}], [800, function(target){$(target).html('<img src="bg/char8.gif">');}], [900, function(target){$(target).html('<img src="bg/char1.gif">');}] ], drop: false }); }); </script> </body> </html>
有興趣的話,可以到這裡看一下效果,另外還有高速版(動作比較快,測試瀏覽器可以動作的時間最小單位的極限),請看這裡。
有一點懶得解釋程式,簡單地說,就是盡量用setInterval跟setTimeout來讓執行的動作不影響計時與控制,所以可以在比較精確的時間執行動作。另外,也用最簡單的方式模仿jQuery的coding style,哈哈。(當然,沒有selector)
另外,稍微解釋傳給actionSequencer的參數:
- duration: 總共時間
- action:陣列,每個元素還是一個陣列,指定要執行動作的時間及執行的動作。系統會傳給動作函數一個target的參數用來指定效果要在哪個元素上執行。
- drop: 用不一樣的方法來執行動作,在指定動作的時間間隔較短時可能會發生作用,在來不及執行動作時就不執行,直接執行下一個動作。這個方法我還沒做很詳細的驗證。