dmx-flok/anim.js
2018-12-27 21:51:25 +00:00

83 lines
1.7 KiB
JavaScript

const ease = require('./easing.js').ease;
const resolution = 25;
class Anim {
constructor() {
this.fxStack = [];
this.interval = null;
}
add(to, duration = resolution, options = {}) {
options.easing = options.easing || 'linear';
this.fxStack.push({ 'to': to, 'duration': duration, 'options': options });
return this;
}
delay(duration) {
this.add({}, duration);
return this;
}
stop() {
if (this.interval) {
clearInterval(this.interval);
}
this.fxStack = [];
}
run(universe, onFinish) {
let config = {};
let ticks = 0;
let duration = 0;
let animationStep;
let iid = null;
const stack = [ ...this.fxStack ];
const aniSetup = () => {
animationStep = stack.shift();
ticks = 0;
duration = animationStep.duration;
config = {};
for (const k in animationStep.to) {
config[k] = {
'start': universe.get(k),
'end': animationStep.to[k],
'options': animationStep.options,
};
}
};
const aniStep = () => {
const newValues = {};
for (const k in config) {
const entry = config[k];
const easing = ease[entry.options.easing];
newValues[k] = Math.round(entry.start + easing(ticks, 0, 1, duration) * (entry.end - entry.start));
}
ticks = ticks + resolution;
universe.update(newValues);
if (ticks > duration) {
if (stack.length > 0) {
aniSetup();
} else {
clearInterval(iid);
if (onFinish) {
onFinish();
}
}
}
};
aniSetup();
iid = this.interval = setInterval(aniStep, resolution);
return this;
}
}
module.exports = Anim;