skinview3d/src/animation.js

72 lines
1.8 KiB
JavaScript

function invokeAnimation(animation, player, time) {
if (animation instanceof CompositeAnimation) {
animation.play(player, time);
} else if (animation instanceof Function) {
animation(player, time);
} else {
throw `Not an animation: ${animation}`;
}
}
class AnimationHandle {
constructor(animation) {
this.animation = animation;
this.paused = this._paused = false;
this.speed = this._speed = 1.0;
this._lastChange = null;
this._lastChangeX = null;
}
play(player, time) {
if (this._lastChange === null) {
this._lastChange = time;
this._lastChangeX = 0;
} else if (this.paused !== this._paused || this.speed !== this._speed) {
let dt = time - this._lastChange;
if (this._paused === false) {
this._lastChangeX += dt * this._speed;
}
this._paused = this.paused;
this._speed = this.speed;
this._lastChange = time;
}
if (this.paused === false) {
let dt = time - this._lastChange;
let x = this._lastChangeX + this.speed * dt;
invokeAnimation(this.animation, player, x);
}
}
reset(){
this._lastChange = null;
}
}
class CompositeAnimation {
constructor() {
this.handles = new Set();
}
add(animation) {
let handle = new AnimationHandle(animation);
handle.remove = () => this.handles.delete(handle);
this.handles.add(handle);
return handle;
}
play(player, time) {
this.handles.forEach(handle => handle.play(player, time));
}
}
let WalkAnimation = (player, time) => {
let skin = player.skin;
let angleRot = time + Math.PI / 2;
// Leg Swing
skin.leftLeg.rotation.x = Math.cos(angleRot);
skin.rightLeg.rotation.x = Math.cos(angleRot + (Math.PI));
// Arm Swing
skin.leftArm.rotation.x = Math.cos(angleRot + (Math.PI));
skin.rightArm.rotation.x = Math.cos(angleRot);
};
export { CompositeAnimation, WalkAnimation, invokeAnimation };