@meganetaaan/mouse-follower
Version:
TypeScript library for creating animated sprites that smoothly follow mouse cursor or other targets using physics-based movement
87 lines (86 loc) • 2.51 kB
JavaScript
export class Animation {
name = "";
index = 0;
isPlaying = false;
#timer;
#config;
#frameInterval;
#frameWidth;
#frameHeight;
constructor(config, frameWidth, frameHeight, defaultInterval = 125) {
this.#config = config;
this.#frameWidth = frameWidth;
this.#frameHeight = frameHeight;
this.#frameInterval = defaultInterval;
}
play(name) {
const animation = this.#config[name];
if (!animation) {
console.warn(`Animation "${name}" not found`);
return;
}
// Stop current animation if playing
if (this.isPlaying) {
this.pause();
}
// Set up new animation
this.name = name;
this.index = 0;
this.isPlaying = true;
// Single frame animations don't need interval and are not considered "playing"
if (animation.numFrames === 1) {
this.isPlaying = false;
return;
}
// Start animation interval
const interval = animation.interval || this.#frameInterval;
this.#timer = window.setInterval(() => {
this.#updateFrame();
}, interval);
}
pause() {
if (this.#timer !== undefined) {
clearInterval(this.#timer);
this.#timer = undefined;
}
this.isPlaying = false;
}
getCurrentFrame() {
const animation = this.#config[this.name];
if (!animation) {
// Return default frame if no animation is set
return {
sourceX: 0,
sourceY: 0,
width: this.#frameWidth,
height: this.#frameHeight,
};
}
const x = animation.start[0] + this.index * this.#frameWidth;
const y = animation.start[1];
return {
sourceX: x,
sourceY: y,
width: this.#frameWidth,
height: this.#frameHeight,
};
}
#updateFrame() {
const animation = this.#config[this.name];
if (!animation) {
this.pause();
return;
}
this.index++;
if (this.index >= animation.numFrames) {
if (animation.repeat) {
this.index = 0;
}
else {
// Animation finished
this.pause();
this.index = animation.numFrames - 1; // Keep showing last frame
}
}
}
}