KilledByAPixel / LittleJS

LittleJS is a fast HTML5 game engine with many features and no dependencies. 🚂 Choo-Choo!
Other
3.21k stars 160 forks source link

Tweens #112

Open Baegus opened 13 hours ago

Baegus commented 13 hours ago

Is there something like a tween system planned? Something that could modify values in time, with easings etc.?

EthanSuperior commented 6 hours ago

You can add Tweens by hooking into the new Plugin system with something like this

 * Tween - A class for creating tweens for animations and other properties.
 * 
 * This class allows you to interpolate values over a specified duration,
 * executing a callback function with the interpolated value at each step.
 * 
 * @example
 * // Create a tween that logs from 0 to 1 over 1200 frames (20 seconds)
 * const tween1 = new Tween(value => console.log(value), 1200);
 * 
 * // Create a tween from 0 to 10 over 300 frames (5 seconds)
 * const tween2 = new Tween(value => console.log(value), 10, 300);
 * 
 * // Create a tween that animates from 5 to 15 300 frames (5 seconds)
 * const tween3 = new Tween(value => console.log(value), 5, 15, 300);
 */

class Tween {
    static children = new Set();

    static {
        engineAddPlugin(() =>
            Tween.children.forEach((tween) =>
                --tween.life
                    ? tween.fn((tween.life * tween.diff) / tween.duration + tween.end)
                    : Tween.children.delete(tween) && tween.fn(tween.end)
            )
        );
    }

    /**
     * Creates a new Tween instance. The fn and duration arguments are required.
     * 
     * @param {function} fn - The function to call with the interpolated value.
     * @param {number} [start] - The starting value of the tween.
     * @param {number} [end] - The ending value of the tween.
     * @param {number} [duration] - The duration of the tween in frames.
     */
    constructor(fn, start, end, duration) {
        end ?? ([duration, end, start] = [start, 1, 0]);
        duration ?? ([duration, end, start] = [end, start, 0]);
        this.fn = fn;
        this.end = end;
        this.diff = start - end;
        this.life = this.duration = duration;
        Tween.children.add(this);
        this.fn(start);
    }
}
KilledByAPixel commented 6 hours ago

Very cool, I am definitely planning on adding something like this either as a plugin or directly to the engine. Will use yours to help me get started when I do it.