依照指定的時間執行動作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: 用不一樣的方法來執行動作,在指定動作的時間間隔較短時可能會發生作用,在來不及執行動作時就不執行,直接執行下一個動作。這個方法我還沒做很詳細的驗證。