• Jump To … +
    ./source/asset-management/image-asset.js ./source/asset-management/noise-asset.js ./source/asset-management/raw-asset.js ./source/asset-management/reaction-diffusion-asset.js ./source/asset-management/sprite-asset.js ./source/asset-management/video-asset.js ./source/core/animation-loop.js ./source/core/display-cycle.js ./source/core/document.js ./source/core/events.js ./source/core/init.js ./source/core/library.js ./source/core/snippets.js ./source/core/user-interaction.js ./source/factory/action.js ./source/factory/anchor.js ./source/factory/animation.js ./source/factory/bezier.js ./source/factory/block.js ./source/factory/button.js ./source/factory/canvas.js ./source/factory/cell.js ./source/factory/cog.js ./source/factory/color.js ./source/factory/conic-gradient.js ./source/factory/crescent.js ./source/factory/element.js ./source/factory/emitter.js ./source/factory/enhanced-label.js ./source/factory/filter.js ./source/factory/gradient.js ./source/factory/grid.js ./source/factory/group.js ./source/factory/label.js ./source/factory/line-spiral.js ./source/factory/line.js ./source/factory/loom.js ./source/factory/mesh.js ./source/factory/net.js ./source/factory/oval.js ./source/factory/particle-force.js ./source/factory/particle-spring.js ./source/factory/particle-world.js ./source/factory/particle.js ./source/factory/pattern.js ./source/factory/picture.js ./source/factory/polygon.js ./source/factory/polyline.js ./source/factory/quadratic.js ./source/factory/radial-gradient.js ./source/factory/rectangle.js ./source/factory/render-animation.js ./source/factory/shape.js ./source/factory/spiral.js ./source/factory/stack.js ./source/factory/star.js ./source/factory/tetragon.js ./source/factory/ticker.js ./source/factory/tracer.js ./source/factory/tween.js ./source/factory/unstacked-element.js ./source/factory/wheel.js ./source/helper/array-pool.js ./source/helper/color-engine.js ./source/helper/document-root-elements.js ./source/helper/filter-engine-bluenoise-data.js ./source/helper/filter-engine.js ./source/helper/random-seed.js ./source/helper/shape-path-calculation.js ./source/helper/shared-vars.js ./source/helper/system-flags.js ./source/helper/utilities.js ./source/helper/workstore.js ./source/mixin/anchor.js ./source/mixin/asset-advanced-functionality.js ./source/mixin/asset-consumer.js ./source/mixin/asset.js ./source/mixin/base.js ./source/mixin/button.js ./source/mixin/cascade.js ./source/mixin/cell-key-functions.js ./source/mixin/delta.js ./source/mixin/display-shape.js ./source/mixin/dom.js ./source/mixin/entity.js ./source/mixin/filter.js ./source/mixin/hidden-dom-elements.js ./source/mixin/mimic.js ./source/mixin/path.js ./source/mixin/pattern.js ./source/mixin/pivot.js ./source/mixin/position.js ./source/mixin/shape-basic.js ./source/mixin/shape-curve.js ./source/mixin/styles.js ./source/mixin/text.js ./source/mixin/tween.js ./source/scrawl.js ./source/untracked-factory/cell-fragment.js ./source/untracked-factory/coordinate.js ./source/untracked-factory/drag-zone.js ./source/untracked-factory/keyboard-zone.js ./source/untracked-factory/observe-update.js ./source/untracked-factory/palette.js ./source/untracked-factory/particle-history.js ./source/untracked-factory/quaternion.js ./source/untracked-factory/state.js ./source/untracked-factory/text-style.js ./source/untracked-factory/vector.js
  • §

    Ticker factory

    Ticker objects represent a timeline against which Tween and Action objects will run.

  • §

    Imports

    import { animation, animationtickers, constructors, tween } from '../core/library.js';
    
    import { convertTime, doCreate, isa_obj, mergeOver, pushUnique, removeItem, xt, Ωempty } from '../helper/utilities.js';
    
    import { makeAnimation } from './animation.js';
    
    import { releaseArray, requestArray } from '../helper/array-pool.js';
    
    import baseMix from '../mixin/base.js';
  • §

    Shared constants

    import { _floor, _now, FUNCTION, PC, T_ACTION, T_RENDER_ANIMATION, T_TICKER, T_TWEEN, ZERO_STR } from '../helper/shared-vars.js';
  • §

    Local constants

    const ANIMATIONTICKERS = 'animationtickers'
  • §

    Ticker constructor

    const Ticker = function (items = Ωempty) {
    
        this.makeName(items.name);
        this.register();
    
        this.subscribers = [];
        this.subscriberObjects = [];
    
        this.set(this.defs);
        this.set(items);
    
        this.cycleCount = 0;
        this.active = false;
        this.effectiveDuration = 0;
        this.startTime = 0;
        this.currentTime = 0;
        this.tick = 0;
    
        if (items.subscribers) this.subscribe(items.subscribers);
    
        this.setEffectiveDuration();
        return this;
    };
  • §

    Ticker prototype

    const P = Ticker.prototype = doCreate();
    P.type = T_TICKER;
    P.lib = ANIMATIONTICKERS;
    P.isArtefact = false;
    P.isAsset = false;
  • §

    Mixins

    baseMix(P);
  • §

    Ticker attributes

    const defaultAttributes = {
  • §

    order - positive integer Number - determines the order in which each Ticker animation object will be actioned before the Display cycle starts.

    • Higher order Tickers will be processed after lower order Tickers.
    • Tickers with the same order value will be processed in the order in which they were defined in code.
        order: 1,
  • §

    duration - can accept a variety of values:

    • Number, representing milliseconds.
    • String time value, for example '500ms', '0.5s'.
    • (% String values cannot be used with Ticker objects - they have nothing to measure such a relative value against).
        duration: 0,
  • §

    subscribers - Array of Tween and Action name-Strings. Use subscribe and unsubscribe functions rather than the set function to add/remove Tweens and/or Actions to/from the Ticker

        subscribers: null,
  • §

    killOnComplete - Boolean flag. When set, the Ticker will kill both itself and all Tweens and Actions associated with it at the end of its run

        killOnComplete: false,
  • §

    cycles - positive integer Number representing the number of cycles the Ticker will run before it completes.

    • A value of 0 indicates that the Ticker should repeat itself forever, until its halt, seekTo, seekFor, complete or reset functions are triggered.
    • Note that Tween and Action animation direction is determined by those objects (via their reverseOnCycleEnd and reversed flags). Tickers always repeat in a forwards direction - they loop back to their start; they never reverse time.
        cycles: 1,
  • §

    observer - String name of a RenderAnimation object, or the object itself - halt/resume the ticker based on the running state of the animation object

        observer: null,
  • §

    The Ticker object supports some hook functions:

    • onRun - triggers each time the Ticker’s run function is invoked
    • onHalt - triggers each time the Ticker’s halt function is invoked
    • onReverse - triggers each time the Ticker’s reverse function is invoked
    • onResume - triggers each time the Ticker’s resume function is invoked
    • onSeekTo - triggers each time the Ticker’s seekTo function is invoked
    • onSeekFor - triggers each time the Ticker’s seekFor function is invoked
    • onComplete - triggers each time the Ticker’s complete function is invoked
    • onReset - triggers each time the Ticker’s reset function is invoked
        onRun: null,
        onHalt: null,
        onReverse: null,
        onResume: null,
        onSeekTo: null,
        onSeekFor: null,
        onComplete: null,
        onReset: null,
    };
    P.defs = mergeOver(P.defs, defaultAttributes);
  • §

    Packet management

    P.packetExclusions = pushUnique(P.packetExclusions, ['subscribers']);
    P.packetFunctions = pushUnique(P.packetFunctions, ['onRun', 'onHalt', 'onReverse', 'onResume', 'onSeekTo', 'onSeekFor', 'onComplete', 'onReset']);
  • §

    Clone management

    No additional clone functionality required.

  • §

    Kill management

    kill - remove Ticker from Scrawl-canvas system.

    P.kill = function (killTweens = true, autokill = true) {
    
        if (killTweens) {
    
            const subs = [...this.subscribers];
    
            for (let i = 0, iz = subs.length; i < iz; i++) {
    
                const sub = tween[subs[i]];
    
                if (sub) {
    
                    sub.completeAction();
                    sub.kill();
                }
            }
        }
    
        if (autokill) {
    
            if (this.active) this.halt();
    
            removeItem(tickerAnimations, this.name);
            tickerAnimationsFlag = true;
    
            this.deregister();
    
            return true;
        }
        return this;
    };
  • §

    killTweens - remove a Ticker’s subscribed Tweens from Scrawl-canvas system.

    • If the function is invoked with a truthy argument, the Ticker will also be removed from the system.
    P.killTweens = function(autokill = false) {
    
        return this.kill(true, autokill);
    };
  • §

    Get, Set, deltaSet

    const G = P.getters,
        S = P.setters;
  • §

    subscribers - see also the subscribe and unsubscribe functions below

    • getter returns a copy of the subscribers Array, containing Tween and Action object name-Strings.
    • setter accepts a Tween or Action name-String, or an Array of such Strings. Will replace the existing subscribers Array with this new data.
    G.subscribers = function () {
    
        return [...this.subscribers];
    };
    S.subscribers = function (item) {
    
        this.subscribe(item);
    };
  • §

    order

    S.order = function (item) {
    
        this.order = item;
    
        if (this.active) tickerAnimationsFlag = true;
    };
  • §

    cycles

    S.cycles = function (item) {
    
        this.cycles = item;
    
        if (!this.cycles) this.cycleCount = 0;
    };
  • §

    duration - changes to the duration (and as a consequence effectiveDuration) attributes will be cascaded down to subscribed Tweens and Actions immediately.

    S.duration = function (item) {
    
        let i, iz, target;
    
        const subscribers = this.subscribers;
    
        this.duration = item;
        this.setEffectiveDuration();
    
        if(xt(subscribers)){
    
            for (i = 0, iz = subscribers.length; i < iz; i++) {
    
                target = tween[subscribers[i]];
    
                if (target) {
    
                    target.calculateEffectiveTime();
    
                    if (target.type === T_TWEEN) target.calculateEffectiveDuration();
                }
            }
        }
    };
  • §

    Subscription management

  • §

    subscribe - can accept one or more arguments, each of which can be:

    • a Tween or Action name-String, or the Tween or Action objects themselves
    • an Array of such name-Strings or objects
    P.subscribe = function (...args) {
    
        const items = args.flat(Infinity);
    
        if (items.length) {
    
            items.forEach(item => {
    
                let obj;
    
                if (item.substring) obj = tween[item];
                else if (isa_obj(item) && (item.type === T_ACTION || item.type === T_TWEEN)) obj = item;
    
                if (obj) {
    
                    pushUnique(this.subscribers, obj.name);
                    obj.ticker = this.name;
                    obj.calculateEffectiveTime();
                }
            });
    
            this.sortSubscribers();
            this.recalculateEffectiveDuration();
        }
        return this;
    };
  • §

    unsubscribe - can accept one or more arguments, each of which can be:

    • a Tween or Action name-String, or the Tween or Action objects themselves
    • an Array of such name-Strings or objects
    P.unsubscribe = function (...args) {
    
        const items = args.flat(Infinity);
    
        if (items.length) {
    
            items.forEach(item => {
    
                let obj;
    
                if (item.substring) obj = tween[item];
                else if (isa_obj(item) && (item.type === T_ACTION || item.type === T_TWEEN)) obj = item;
    
                if (obj) {
    
                    removeItem(this.subscribers, obj.name);
                    obj.ticker = ZERO_STR;
                }
            });
    
            this.sortSubscribers();
            this.recalculateEffectiveDuration();
        }
        return this;
    };
  • §

    repopulateSubscriberObjects

    P.repopulateSubscriberObjects = function () {
    
        const arr = this.subscriberObjects,
            subs = this.subscribers;
    
        let t;
    
        arr.length = 0;
    
        subs.forEach(sub => {
    
            t = tween[sub];
            if (t) arr.push(t);
        });
    };
  • §

    getSubscriberObjects

    P.getSubscriberObjects = function () {
    
        if (this.subscribers.length && !this.subscriberObjects.length) this.repopulateSubscriberObjects();
    
        return this.subscriberObjects;
    };
  • §

    sortSubscribers - internal Helper function called by subscribe and unsubscribe

    P.sortSubscribers = function () {
    
        const subs = this.subscribers,
            len = subs.length;
    
        if(len > 1) {
    
            const buckets = requestArray();
    
            let i, sub;
    
            for (i = 0; i < len; i++) {
    
                sub = tween[subs[i]];
    
                if (sub) buckets.push(sub);
            }
    
            if (buckets.length > 1) buckets.sort((a, b) => a.effectiveTime - b.effectiveTime);
    
            subs.length = 0;
    
            for (i = 0; i < buckets.length; i++) {
    
                subs.push(buckets[i].name);
            }
    
            releaseArray(buckets);
        }
        this.repopulateSubscriberObjects();
    };
  • §

    updateSubscribers - internal function called by the run, reset and complete functions below.

    • First argument is an object that gets applied as the argument to each Tween/Action object’s set function.
    • Second argument is a Boolean; when set, subscribed Tween/Actions will be told to reverse their current direction.
    P.updateSubscribers = function(items, reversed) {
    
        reversed = (xt(reversed)) ? reversed : false;
    
        const subs = this.getSubscriberObjects();
    
        let i, iz;
    
        if (reversed) {
    
            for (i = subs.length - 1; i >= 0; i--) {
    
                subs[i].set(items);
            }
        }
        else{
    
            for (i = 0, iz = subs.length; i < iz; i++) {
    
                subs[i].set(items);
            }
        }
        return this;
    };
  • §

    changeSubscriberDirection - internal function - when invoked, Tween/Actions will be told to reverse their current direction.

    P.changeSubscriberDirection = function () {
    
        const subs = this.getSubscriberObjects();
    
        subs.forEach(sub => sub.reversed = !sub.reversed);
    
        return this;
    };
  • §

    Animation

  • §

    recalculateEffectiveDuration - where a Ticker has not been given a duration value, it needs to consult its subscribed Tween/Action objects to calculate an effectiveDuration value with sufficient time allocated for each Tween to run to completion, and each Action to trigger.

    • Tween/Actions with a relative time attribute - eg: 30% - will not be included in the calculation.
    • Tweens can overlap - they do not all have to start and end at the same time, nor do they need to run sequentially.
    P.recalculateEffectiveDuration = function() {
    
        const subs = this.getSubscriberObjects();
    
        let durationValue,
            duration = 0;
    
        if (!this.duration) {
    
            subs.forEach(sub => {
    
                durationValue = sub.getEndTime();
    
                if (durationValue > duration) duration = durationValue;
            });
            this.effectiveDuration = duration;
        }
  • §

    Shouldn’t cause an infinite loop …

        else this.setEffectiveDuration();
    
        return this;
    };
  • §

    setEffectiveDuration - internal helper function - convert duration value into effectiveDuration value.

    P.setEffectiveDuration = function() {
    
        let temp;
    
        if (this.duration) {
    
            temp = convertTime(this.duration);
  • §

    Cannot use %-String values for Ticker duration attribute

            if (temp[0] === PC) {
    
                this.duration = 0
                this.recalculateEffectiveDuration();
            }
            else this.effectiveDuration = temp[1];
        }
        return this;
    };
  • §

    checkObserverRunningState - internal helper function

    P.checkObserverRunningState = function () {
    
        let observer = this.observer;
    
        if (observer) {
    
            if (observer.substring) {
    
                const anim = animation[observer];
    
                if (anim && anim.type === T_RENDER_ANIMATION) {
    
                    observer = this.observer = anim;
                }
                else return true;
            }
            if (observer.type === T_RENDER_ANIMATION) {
    
                return observer.isRunning();
            }
        }
        return true;
    };
  • §

    fn - internal - the animation function will trigger once per RequestAnimationFrame (RAF) tick - approximately 60 times a second, depending on other calculation work.

    • Only triggers when the Ticker is running in a qualifying state.
    • reverseOrder argument is a Boolean value; when set, subscribed Tween/Action objects will be processed in reverse order.
    P.fn = function (reverseOrder) {
  • §

    Determine the order in which subscribed objects will be processed

        reverseOrder = xt(reverseOrder) ? reverseOrder : false;
  • §

    Request a result object from the pool.

        const result = requestResultObject();
    
        const startTime = this.startTime,
            cycles = this.cycles,
            effectiveDuration = this.effectiveDuration;
    
        let i, iz, subs,
            currentTime, tick,
            active = this.active,
            cycleCount = this.cycleCount;
  • §

    Process only if the Ticker is currently active and has a startTime value assigned to it.

        if (active && startTime) {
  • §

    Process only if the Ticker’s cycles attribute has been set to 0, or if the Ticker has not yet completed all its cycles.

            if (!cycles || cycleCount < cycles) {
    
                currentTime = this.currentTime = _now();
                tick = this.tick = currentTime - startTime;
  • §

    Update the results object

    • Functionality performed if the Tween is not on its final cycle.
                if (!cycles || cycleCount + 1 < cycles) {
    
                    if (tick >= effectiveDuration) {
    
                        tick = this.tick = 0;
                        this.startTime = this.currentTime;
                        result.tick = effectiveDuration;
                        result.reverseTick = 0;
                        result.willLoop = true;
    
                        if (cycles) {
    
                            cycleCount++;
                            this.cycleCount = cycleCount;
                        }
                    }
                    else {
    
                        result.tick = tick;
                        result.reverseTick = effectiveDuration - tick;
                    }
                    result.next = true;
                }
  • §
    • Functionality performed only when the Tween is on its final cycle.
                else {
    
                    if (tick >= effectiveDuration) {
    
                        result.tick = effectiveDuration;
                        result.reverseTick = 0;
                        active = this.active = false;
    
                        if (cycles) {
    
                            cycleCount++
                            this.cycleCount = cycleCount;
                        }
                    }
                    else {
    
                        result.tick = tick;
                        result.reverseTick = effectiveDuration - tick;
                        result.next = true;
                    }
                }
  • §

    Invoke the update function on each subscribed Tween/Action

                subs = this.getSubscriberObjects();
    
                if (reverseOrder) {
    
                    for (i = subs.length - 1; i >= 0; i--) {
    
                        subs[i].update(result);
                    }
                }
                else{
    
                    for (i = 0, iz = subs.length; i < iz; i++) {
    
                        subs[i].update(result);
                    }
                }
  • §

    If this invocation of the function has completed the Ticker’s run, switch it off.

                if (!active) this.halt();
  • §

    If the Ticker’s run is completed and the killOnComplete flag is set, kill everything.

                if (this.killOnComplete && cycleCount >= cycles) this.killTweens(true);
            }
        }
  • §

    Release the result object back to the pool.

        releaseResultObject(result);
    };
  • §

    Animation control

  • §

    run

    • Start the Ticker from time 0.
    • Trigger the object’s onRun function.
    P.run = function () {
    
        if (!this.active) {
    
            this.startTime = this.currentTime = _now();
            this.cycleCount = 0;
    
            this.updateSubscribers({
                reversed: false
            });
    
            this.active = true;
    
            pushUnique(tickerAnimations, this.name);
            tickerAnimationsFlag = true;
    
            if (typeof this.onRun === FUNCTION) this.onRun();
        }
        return this;
    };
  • §

    isRunning - check to see if Ticker is in a running state.

    P.isRunning = function () {
    
        return this.active;
    };
  • §

    reset

    • Halt the Ticker, if it is running.
    • Set all attributes to their initial values.
    • Update subscribed Tween/Actions.
    • Trigger the object’s onReset function.
    P.reset = function () {
    
        if (this.active) this.halt();
    
        this.startTime = this.currentTime = _now();
        this.cycleCount = 0;
    
        this.updateSubscribers({
            reversed: false
        });
    
        this.active = true;
    
        this.fn(true);
        this.active = false;
    
        if (typeof this.onReset === FUNCTION) this.onReset();
    
        return this;
    };
  • §

    complete

    • Halt the Ticker, if it is running.
    • Set all attributes to their initial values.
    • Update subscribed Tween/Actions.
    • Trigger the object’s onComplete function.
    P.complete = function () {
    
        if (this.active) this.halt();
    
        this.startTime = this.currentTime = _now();
        this.cycleCount = 0;
    
        this.updateSubscribers({
            reversed: true
        });
    
        this.active = true;
    
        this.fn();
        this.active = false;
    
        if (typeof this.onComplete === FUNCTION) this.onComplete();
    
        return this;
    };
  • §

    reverse - simulates a reversal in the Ticker’s animation.

    • Halt the Ticker, if it is running.
    • Trigger the object’s onReverse function.
    • after recalculation, resume the Ticker - if required.
    • Function accepts a Boolean argument - if true, Ticker will start playing “in reverse”.
    • Directionality is determined by Tween/Action object attribute settings, not the Ticker.
    P.reverse = function (resume = false) {
    
        if (this.active) this.halt();
    
        const timePlayed = this.currentTime - this.startTime;
        this.startTime = this.currentTime - (this.effectiveDuration - timePlayed);
        this.changeSubscriberDirection();
        this.active = true;
    
        this.fn();
        this.active = false;
    
        if (typeof this.onReverse === FUNCTION) this.onReverse();
    
        if (resume) this.resume();
    
        return this;
    };
  • §

    halt

    • Stop the Ticker at its current point in time
    • Trigger the object’s onHalt function.
    P.halt = function () {
    
        this.active = false;
        removeItem(tickerAnimations, this.name);
        tickerAnimationsFlag = true;
    
        if (typeof this.onHalt === FUNCTION) this.onHalt();
    
        return this;
    };
  • §

    resume - this function can also be triggered by the reverse, seekTo and seekFor functions

    • Start the Ticker from its current point in time
    • Trigger the object’s onResume function.
    P.resume = function () {
    
        let now, current, start;
    
        if (!this.active) {
    
            now = _now();
            current = this.currentTime;
            start = this.startTime;
            this.startTime = now - (current - start);
            this.currentTime = now;
            this.active = true;
            pushUnique(tickerAnimations, this.name);
            tickerAnimationsFlag = true;
    
            if (typeof this.onResume === FUNCTION) this.onResume();
    
        }
        return this;
    };
  • §

    seekTo

    • First argument - Number representing the millisecond time to move to on the Ticker’s timeline
    • Second argument - Boolean - if true, Ticker will resume playing from new point
    • Halt the Ticker, if it is running.
    • Update the Ticker’s currentTime, startTime attributes
    • Trigger the object’s onSeekTo function.
    • Resume the Ticker - if required.
    P.seekTo = function (milliseconds = 0, resume = false) {
    
        let backwards = false;
    
        if (this.active) this.halt();
    
        if (this.cycles && this.cycleCount >= this.cycles) this.cycleCount = this.cycles - 1;
    
        if (milliseconds < this.tick) backwards = true;
    
        this.currentTime = _now();
        this.startTime = this.currentTime - milliseconds;
        this.active = true;
    
        this.fn(backwards);
        this.active = false;
    
        if (typeof this.onSeekTo === FUNCTION) this.onSeekTo();
    
        if (resume) this.resume();
    
        return this;
    };
  • §

    seekFor

    • First argument - Number representing the number of milliseconds to move along the Ticker’s timeline (forwards or backwards)
    • Second argument - Boolean - if true, Ticker will resume playing from new point
    • Halt the Ticker, if it is running.
    • Update the Ticker’s currentTime, startTime attributes
    • Trigger the object’s onSeekFor function.
    • Resume the Ticker - if required.
    P.seekFor = function (milliseconds = 0, resume = false) {
    
        let backwards = false;
    
        if (this.active) this.halt();
    
        if (this.cycles && this.cycleCount >= this.cycles) this.cycleCount = this.cycles - 1;
    
        this.startTime -= milliseconds;
    
        if (milliseconds < 0) backwards = true;
    
        this.active = true;
    
        this.fn(backwards);
        this.active = false;
    
        if (typeof this.onSeekFor === FUNCTION) this.onSeekFor();
    
        if (resume) this.resume();
    
        return this;
    };
  • §

    Ticker animation controller

    const tickerAnimations = [];
    let tickerAnimationsFlag = true;
  • §

    coreTickersAnimation

    makeAnimation({
    
        name: 'SC-core-tickers-animation',
        order: 0,
        fn: function () {
  • §

    We only sort active Ticker objects when absolutely necessary.

    • Sorted using a bucket sort algorithm.
            let arr, obj, order, i, iz, name;
    
            if (tickerAnimationsFlag) {
    
                tickerAnimationsFlag = false;
    
                const buckets = requestArray();
    
                for (i = 0, iz = tickerAnimations.length; i < iz; i++) {
    
                    obj = animationtickers[tickerAnimations[i]];
    
                    if (obj) {
    
                        order = _floor(obj.order) || 0;
    
                        if (!buckets[order]) buckets[order] = requestArray();
    
                        buckets[order].push(obj.name);
                    }
                }
                tickerAnimations.length = 0;
    
                for (i = 0, iz = buckets.length; i < iz; i++) {
    
                    arr = buckets[i];
    
                    if (arr) {
    
                        tickerAnimations.push(...arr);
                        releaseArray(arr);
                    }
                }
                releaseArray(buckets);
            }
  • §

    Invoke each Ticker’s fn function.

    • It’s up to the Ticker object to decide whether it’s active
            for (i = 0, iz = tickerAnimations.length; i < iz; i++) {
    
                name = tickerAnimations[i];
                obj= animationtickers[name];
    
                if (obj && obj.fn && obj.checkObserverRunningState()) obj.fn();
            }
        }
    });
  • §

    ResultObject pool

    TODO: do we need a pool for this?

    • To use a pool result object, request it using requestResultObject function.
    • It is imperative that requested result objects are released - releaseResultObject - once work with them completes.
    const resultObjectPool = [];
  • §

    requestResultObject

    const requestResultObject = function () {
    
        if (!resultObjectPool.length) {
    
            resultObjectPool.push({
                tick: 0,
                reverseTick: 0,
                willLoop: false,
                next: false
            });
        }
    
        return resultObjectPool.pop();
    };
  • §

    releaseResultObject

    const releaseResultObject = function (r) {
    
        if (r) {
    
            r.tick = 0;
            r.reverseTick = 0;
            r.willLoop = false;
            r.next = false;
            resultObjectPool.push(r);
        }
    };
  • §

    Factory

    export const makeTicker = function (items) {
    
        if (!items) return false;
        return new Ticker(items);
    };
    
    constructors.Ticker = Ticker;