util_gradient_number_gradient.js

import Util from "../misc/util.js";

/**
 * @module NumberGradient
 * @fileoverview Contains NumberGradient class.
 */

/**
 * @class
 * Gradient for single values.
 */
class NumberGradient {
    /**
     * Create a new number gradient.
     * @param {Object.<number, number>} values Values at time intervals
     * @param {boolean} smooth Whether the track should start and end smoothly/gradually
     * @constructor
     */
    constructor(values = {}, smooth = false) {
        const keys = Object.keys(values).map(Number).sort((a, b) => a - b);

        this._points = [];
        this._values = [];

        for (const key of keys) {
            this._points.push(key);
            this._values.push(values[key.toString()]);
        }

        this.smooth = smooth;
    }


    //
    // Calculations
    //

    /**
     * Get the value at a specified point.
     * @param {number} progress Overall animation progress (0 - 1)
     * @returns {number} Number at current point
     */
    get(progress) {
        if (this._points.length === 0)
            return 0;
        if (this._points.length === 1 || progress <= this._points[0])
            return this._values[0];
        if (progress >= this._points[this._points.length - 1])
            return this._values[this._points.length - 1];

        let i = 0;
        while (progress > this._points[i]) i++;

        const pointA = this._points[i - 1];
        const pointB = this._points[i];

        const a = this._values[i - 1];
        const b = this._values[i];

        const alpha = (progress - pointA) / (pointB - pointA);

        if (this.smooth)
            return Util.smoothLerp(a, b, alpha);
        else
            return Util.lerp(a, b, alpha);
    }
}

export default NumberGradient;