• 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
  • §

    Cascade mixin

    This mixin sets up the Scrawl-canvas functionality required to perform its Display cycle.

    • The Display cycle is initiated by Stack and DOM-related Cell wrappers (generally Canvas wrappers) - controller objects
    • The cycle cascades from the wrappers to all artefact objects associated with them, as mediated by Group objects.

    The mixin also includes code to assist drag-and-drop functionality.

  • §

    Imports

    import { group } from '../core/library.js';
    
    import { mergeOver, pushUnique, removeItem, xtGet, Ωempty } from '../helper/utilities.js';
    
    import { releaseArray, requestArray } from '../helper/array-pool.js';
  • §

    Shared constants

    import { _floor, REVERSE_BY_DELTA, UPDATE_BY_DELTA } from '../helper/shared-vars.js';
  • §

    Local constants

    const ADD_ARTEFACT_CLASSES = 'addArtefactClasses',
        REMOVE_ARTEFACT_CLASSES = 'removeArtefactClasses',
        SET_ARTEFACTS = 'setArtefacts',
        UPDATE_ARTEFACTS = 'updateArtefacts';
  • §

    Export function

    export default function (P = Ωempty) {
  • §

    Shared attributes

        const defaultAttributes = {
  • §

    The groups attribute holds the String names of all the Group objects associated with the controller object.

            groups: null,
  • §

    The groupBuckets attribute holds a reference to each Group object, in a set of arrays grouping Groups according to their order values.

            groupBuckets: null,
  • §

    The batchResort Boolean flag determines whether the Groups will be sorted by their order value before instructions get passed to each in sequence. Best to leave this flag alone to do its job.

            batchResort: true,
        };
        P.defs = mergeOver(P.defs, defaultAttributes);
  • §

    Packet management

    No additional packet functionality required

  • §

    Clone management

    No additional clone functionality required

  • §

    Kill management

    No additional kill functionality required

  • §

    Get, Set, deltaSet

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

    groups

        G.groups = function () {
    
            return [].concat(this.groups);
        };
  • §

    Passes the first argument to the addGroups function. Not recommended

        S.groups = function (item) {
    
            this.groups.length = 0;
            this.addGroups(item);
        };
  • §

    Prototype functions

  • §

    sortGroups - internal function - Groups are sorted from the groups Array into the groupBuckets array using a bespoke bucket sort algorithm, based on each Group object’s order attribute

        P.sortGroups = function () {
    
            if (this.batchResort) {
    
                this.batchResort = false;
    
                const {groups, groupBuckets} = this;
                const buckets = requestArray();
    
                let i, iz, obj, name, order, arr;
    
                for (i = 0, iz = groups.length; i < iz; i++) {
    
                    name = groups[i];
                    obj = group[name];
    
                    if (obj) {
    
                        order = _floor(obj.order) || 0;
    
                        if (!buckets[order]) buckets[order] = requestArray();
    
                        buckets[order].push(obj);
                    }
                }
                groupBuckets.length = 0;
    
                for (i = 0, iz = buckets.length; i < iz; i++) {
    
                    arr = buckets[i];
    
                    if (arr) {
    
                        groupBuckets.push(...arr);
                        releaseArray(arr);
                    }
                }
                releaseArray(buckets);
            }
        };
  • §

    initializeCascade - internal function used by factory constructors

        P.initializeCascade = function () {
    
            this.groups = [];
            this.groupBuckets = [];
        };
  • §
    Group management

    Groups should be added to, and removed from, the controller object using the addGroups and removeGroups functions. The argument can be one or more Group object’s name attribute, or the Group object(s) itself.

  • §

    addGroups

        P.addGroups = function (...args) {
    
            const groups = this.groups;
    
            args.forEach(item => {
    
                if (item.substring) pushUnique(groups, item);
                else if (group[item]) pushUnique(groups, item.name);
    
            }, this);
    
            this.batchResort = true;
            return this;
        };
  • §

    removeGroups

        P.removeGroups = function (...args) {
    
            const groups = this.groups;
    
            args.forEach( item => {
    
                if (item.substring) removeItem(groups, item);
                else if (group[item]) removeItem(groups, item.name);
    
            }, this);
    
            this.batchResort = true;
            return this;
        };
  • §

    cascadeAction - internal helper function used by the functions below

        P.cascadeAction = function (items, action) {
    
            let g;
    
            this.groups.forEach(name => {
    
                g = group[name];
    
                if (g) g[action](items);
    
            }, this);
    
            return this;
        };
  • §

    updateArtefacts - Update all artefact objects in all the controller object’s Groups. The supplied argument will be passed on to each artefact’s setDelta function.

        P.updateArtefacts = function (items) {
    
            this.cascadeAction(items, UPDATE_ARTEFACTS);
            return this;
        };
  • §

    updateArtefacts - Set all artefact objects in all the controller object’s Groups. The supplied argument will be passed on to each artefact’s set functions

        P.setArtefacts = function (items) {
    
            this.cascadeAction(items, SET_ARTEFACTS);
            return this;
        };
  • §

    addArtefactClasses - specific to DOM-related artefacts (Stack, Canvas, Element)

        P.addArtefactClasses = function (items) {
    
            this.cascadeAction(items, ADD_ARTEFACT_CLASSES);
            return this;
        };
  • §

    removeArtefactClasses - specific to DOM-related artefacts (Stack, Canvas, Element)

        P.removeArtefactClasses = function (items) {
    
            this.cascadeAction(items, REMOVE_ARTEFACT_CLASSES);
            return this;
        };
  • §

    updateByDelta - triggers the related artefact function, to update (add) its attributes by values held in its delta object attribute

        P.updateByDelta = function () {
    
            this.cascadeAction(false, UPDATE_BY_DELTA);
            return this;
        };
  • §

    reverseByDelta - triggers the related artefact function, to reverse (subtract) its attributes by values held in its delta object attribute

        P.reverseByDelta = function () {
    
            this.cascadeAction(false, REVERSE_BY_DELTA);
            return this;
        };
  • §
    Collision detection

    The getArtefactAt function checks to see if any of the controller object’s Groups’ artefacts are located at the supplied coordinates in the argument object.

    • The first artefact to report back as being at that coordinate will be returned by the function
    • Where no artefacts are present at that coordinate the function returns false.
    • The artefact with the highest order attribute value will be returned first.
    • This function forms part of the Scrawl-canvas drag-and-drop functionality.
        P.getArtefactAt = function (items) {
    
            items = xtGet(items, this.here, false);
    
            if (items) {
    
                let g, res;
    
                for (let i = this.groups.length - 1; i >= 0; i--) {
    
                    g = group[this.groups[i]];
    
                    if (g) {
    
                        res = g.getArtefactAt(items);
    
                        if (res) return res;
                    }
                }
            }
            return false;
        };
  • §

    The getAllArtefactsAt function returns all of the controller object’s Groups’ artefacts located at the supplied coordinates in the argument object.

    • The artefact with the highest order attribute value will be returned first.
    • The function will always return an array of artefact objects, or an empty Array
        P.getAllArtefactsAt = function (items) {
    
            items = xtGet(items, this.here, false);
    
            const results = [];
    
            if (items) {
    
                let g, res;
    
                for (let i = this.groups.length - 1; i >= 0; i--) {
    
                    g = group[this.groups[i]];
    
                    if (g) {
    
                        res = g.getAllArtefactsAt(items);
    
                        if (res) results.push(...res);
                    }
                }
            }
            return results;
        };
    }