untitled-rhythm-game/js/libtransition.js
2025-04-22 23:02:39 +08:00

118 lines
3.7 KiB
JavaScript

(function() {
if(typeof libutil!="object") {
if(typeof loadfail=="function") {
loadfail("libtransition.js: libutil(type of "+(typeof libutil)+") is not an object");
} else {
window.alert("libtransition.js: libutil(type of "+(typeof libutil)+") is not an object");
}
return;
}
if(typeof Bezier!="function") {
if(typeof loadfail=="function") {
loadfail("libtransition.js: Bezier(type of "+(typeof Bezier)+") is not a function");
} else {
window.alert("libtransition.js: Bezier(type of "+(typeof Bezier)+") is not a function");
}
return;
}
if(typeof requestAnimationFrame!="function") {
if(typeof loadfail=="function") {
loadfail("libtransition.js: requestAnimationFrame(type of "+(typeof requestAnimationFrame)+") is not a function");
} else {
window.alert("libtransition.js: requestAnimationFrame(type of "+(typeof requestAnimationFrame)+") is not a function");
}
return;
}
class Transition {
static linear=new Bezier(0, 0, 1, 1);
constructor() {
// static fields (set by user)
this.obj = null;
this.key = null;
this.startval = 0.0;
this.endval = 0.0;
this.duration = 0;
this.animfunc = Transition.linear;
this.stoponend=true;
this.onend = null;
// dynamic fields (set by this program)
this.elapsed = 0;
this.carryover = 0;
}
start() {
this.stop();
transition_update_list.push(this);
}
stop() {
var index=-1;
do {
index = transition_update_list.indexOf(this);
if(index > -1) {
transition_update_list.splice(index, 1);
}
} while(index!=-1);
}
update(et) {
if(!(this.key in this.obj)) {
this.stop();
console.error("the key", this.key, "is not in the obj", this.obj);
return;
}
if(typeof this.animfunc!="function") {
this.stop();
console.error("(a instance of transition).animfunc is not a function");
return;
}
if(!libutil.isNumber(et)) {
et=0;
}
// this.carryover is for this.onend() only, not for the animation itself
this.carryover=0;
this.elapsed+=et;
if(this.elapsed>=this.duration) {
this.carryover=this.elapsed-this.duration;
this.elapsed=this.duration;
this.obj[this.key]=this.endval;
if(this.onend!==null&&typeof this.onend=="function") {
try {
this.onend();
} catch(e) {
console.error(e);
}
}
if(this.stoponend) {
this.stop();
}
return;
}
this.obj[this.key]=this.startval+(this.endval-this.startval)*libutil.clamp(this.animfunc(this.elapsed/this.duration), 0, 1);
}
}
var transition_update_list=[];
var ticker_lasttime=Date.now();
var run_ticker=function(ts) {
requestAnimationFrame(run_ticker);
var et = ts - ticker_lasttime;
ticker_lasttime = ts;
transition_update_list.forEach(function(elem) {
elem.update(et);
});
};
run_ticker(ticker_lasttime);
window.Transition=Transition;
})();