Source: animate/AnimatorTimeline.js

animate/AnimatorTimeline.js

const pool = [];
import { Animator } from './Animator';
/**
 * Represents a single animation play.
 * @class AnimatorTimeline
 * @memberof PIXI.animate
 */
class AnimatorTimeline {
    constructor() {
        this._update = this.update.bind(this);
        this.init(null, 0, 0, false, null);
    }

    /**
     * The pool of timelines to use
     * @method PIXI.animate.AnimatorTimeline#init
     * @param {PIXI.animate.MovieClip} instance
     * @param {Number} start
     * @param {Number} end
     * @param {Boolean} loop
     * @param {Function} callback
     * @private
     */
    init(instance, start, end, loop, callback) {

        /**
         * Instance of clip to play.
         * @name PIXI.animate.AnimatorTimeline#instance
         * @type {PIXI.animate.MovieClip}
         * @readOnly
         */
        this.instance = instance;

        /**
         * `true` if the timeline is suppose to loop.
         * @name PIXI.animate.AnimatorTimeline#loop
         * @type {Boolean}
         * @readOnly
         */
        this.loop = loop;

        /**
         * Frame number of the starting farme.
         * @name PIXI.animate.AnimatorTimeline#start
         * @type {int}
         * @readOnly
         */
        this.start = start;

        /**
         * Frame number of the ending frame.
         * @name PIXI.animate.AnimatorTimeline#end
         * @type {int}
         * @readOnly
         */
        this.end = end;

        /**
         * Callback called when completed (non-looping animation).
         * @name PIXI.animate.AnimatorTimeline#callback
         * @type {Function}
         * @readOnly
         */
        this.callback = callback;

        if (instance) {
            //Prevent overshooting the end frame and looping back around:
            instance.loop = false;
            instance.gotoAndStop(start);
            instance._beforeUpdate = this._update;
        }
    }

    /**
     * Don't use after this
     * @method PIXI.animate.AnimatorTimeline#destroy
     * @private
     */
    destroy() {
        this.instance._beforeUpdate = null;
        this.init(null, 0, 0, false, null);
        AnimatorTimeline._pool.push(this);
    }

    /**
     * Is the animation complete
     * @method PIXI.animate.AnimatorTimeline#update
     * @param {PIXI.animate.MovieClip} instance
     * @return {Function} Callback to do after updateTimeline
     * @private
     */
    update(instance) {
        let completed;
        if (instance.currentFrame >= this.end) {

            // In case we over-shoot the current frame becuase of low FPS
            instance.currentFrame = this.end;

            if (this.loop) {
                // Update timeline so we get actions at the end frame
                instance._updateTimeline();
                instance.gotoAndPlay(this.start);
            } else {
                instance.stop();
                if (this.callback) {
                    completed = this.callback;
                }
                this.stop(); // cleanup timeline
            }
        }
        return completed;
    }

    /**
     * Stop the animation, cannot be reused.
     * @method PIXI.animate.AnimatorTimeline#stop
     */
    stop() {
        // PIXI.animate.Animator._internalStop(this);
        Animator._internalStop(this);
    }

    /**
     * The progress from 0 to 1 of the playback.
     * @name PIXI.animate.AnimatorTimeline#progress
     * @type {Number}
     * @readOnly
     */
    get progress() {
        const progress = (this.instance.currentFrame - this.start) / (this.end - this.start);
        return Math.max(0, Math.min(1, progress)); // clamp
    }

    /**
     * The pool of timelines to use
     * @name PIXI.animate.AnimatorTimeline._pool
     * @type {Array<PIXI.animate.AnimatorTimeline>}
     * @static
     * @private
     */
    static get _pool() {
        return pool;
    }

    /**
     * Create a new timeline
     * @method PIXI.animate.AnimatorTimeline.create
     * @static
     * @param {PIXI.animate.MovieClip} instance
     * @param {Number} start
     * @param {Number} end
     * @param {Boolean} loop
     * @param {Function} callback
     * @return {PIXI.animate.AnimatorTimeline}
     */
    static create(instance, start, end, loop, callback) {
        var timeline;
        if (this._pool.length) {
            timeline = this._pool.pop();
        } else {
            timeline = new AnimatorTimeline();
        }
        timeline.init(instance, start, end, loop, callback);
        return timeline;
    }
}

module.exports = AnimatorTimeline;