• Jump To … +
    ./source/core/animationloop.js ./source/core/component.js ./source/core/document.js ./source/core/events.js ./source/core/init.js ./source/core/library.js ./source/core/userInteraction.js ./source/core/utilities.js ./source/factory/action.js ./source/factory/anchor.js ./source/factory/animation.js ./source/factory/bezier.js ./source/factory/block.js ./source/factory/canvas.js ./source/factory/cell.js ./source/factory/cog.js ./source/factory/color.js ./source/factory/coordinate.js ./source/factory/element.js ./source/factory/emitter.js ./source/factory/filter.js ./source/factory/fontAttributes.js ./source/factory/gradient.js ./source/factory/grid.js ./source/factory/group.js ./source/factory/imageAsset.js ./source/factory/line.js ./source/factory/loom.js ./source/factory/mesh.js ./source/factory/net.js ./source/factory/noise.js ./source/factory/oval.js ./source/factory/palette.js ./source/factory/particle.js ./source/factory/particleForce.js ./source/factory/particleHistory.js ./source/factory/particleSpring.js ./source/factory/particleWorld.js ./source/factory/pattern.js ./source/factory/phrase.js ./source/factory/picture.js ./source/factory/polygon.js ./source/factory/polyline.js ./source/factory/quadratic.js ./source/factory/quaternion.js ./source/factory/radialGradient.js ./source/factory/rectangle.js ./source/factory/renderAnimation.js ./source/factory/shape.js ./source/factory/spiral.js ./source/factory/spriteAsset.js ./source/factory/stack.js ./source/factory/star.js ./source/factory/state.js ./source/factory/tetragon.js ./source/factory/ticker.js ./source/factory/tracer.js ./source/factory/tween.js ./source/factory/unstackedElement.js ./source/factory/vector.js ./source/factory/videoAsset.js ./source/factory/wheel.js ./source/mixin/anchor.js ./source/mixin/asset.js ./source/mixin/assetConsumer.js ./source/mixin/base.js ./source/mixin/cascade.js ./source/mixin/delta.js ./source/mixin/displayShape.js ./source/mixin/dom.js ./source/mixin/entity.js ./source/mixin/filter.js ./source/mixin/mimic.js ./source/mixin/path.js ./source/mixin/pattern.js ./source/mixin/pivot.js ./source/mixin/position.js ./source/mixin/shapeBasic.js ./source/mixin/shapeCurve.js ./source/mixin/shapePathCalculation.js ./source/mixin/styles.js ./source/mixin/tween.js ./source/worker/filter-string.js ./source/worker/filter.js
  • ¶

    DOM management

    Core DOM element discovery and management functionality, and the Scrawl-canvas Display cycle.

    Scrawl-canvas breaks down the display cycle into three parts: clear; compile; and show. These can be triggered either as a single, combined render operation, or separately as-and-when needed.

    The order in which DOM stack and canvas elements are processed during the display cycle can be changed by setting that element’s controller’s order attribute to a higher or lower integer value; elements are processed (in batches) from lowest to highest order value

  • ¶

    Imports

    import { isa_canvas, generateUniqueString, isa_dom, pushUnique, removeItem, xt } from "./utilities.js";
    import { artefact, canvas, group, stack, css, xcss } from "./library.js";
    
    import { makeStack } from "../factory/stack.js";
    import { makeElement } from "../factory/element.js";
    import { makeCanvas } from "../factory/canvas.js";
  • ¶

    Root elements

    Exported array and function (to modules). Root elements are the boxes whose dimensions define the dimensions and positioning of all that they contain. All <canvas> elements are root elements. Scrawl-canvas also allows other DOM elements (typically <div> elements) to be defined as root elements called stacks, whose child elements can then be positioned and dimensioned just like entity objects in a canvas.

    Stacks can be nested within each other, and canvases can also be nested inside a stack. (Nothing can nest inside a canvas element). Only the top level stack will be included in the rootElements array.

    The Scrawl-canvas Display cycle - a cascade of Promise-based functionality for updating canvas and stack displays - can start at the rootElements array, with each member of the array processed in turn.

    The rootElements array keeps track of all ‘root’ stack artefacts, and also includes all canvas artefacts, whether they’re part of a stack or not. setRootElementSort forces the root

    let rootElements = [],
        setRootElementsSort = () => {rootElementsSort = true};
  • ¶

    Local variables

    let rootElements_sorted = [],
        rootElementsSort = true;
  • ¶

    Scrawl-canvas rootElements sorter uses a ‘bucket sort’ algorithm

    const sortRootElements = function () {
    
        let floor = Math.floor;
    
        if (rootElementsSort) {
    
            rootElementsSort = false;
    
            let buckets = [],
                art, order;
    
            rootElements.forEach((item) => {
    
                art = artefact[item];
    
                if (art) {
    
                    order = floor(art.order) || 0;
    
                    if (!buckets[order]) buckets[order] = [];
                    
                    buckets[order].push(art.name);
                }
            });
    
            rootElements_sorted = buckets.reduce((a, v) => a.concat(v), []);
        }
    };
  • ¶

    Stack discovery

    Exported function (to modules). Parse the DOM, looking for all elements that have been given a data-stack attribute; then create Stack artefact wrappers for each of them.

    This function will also create wrappers for all direct child elements (one level down) within the stack, and create appropriate wrappers (Stack, Canvas, Element) for them.

    const getStacks = function () {
            
        document.querySelectorAll('[data-stack]').forEach(el => addInitialStackElement(el));
    };
  • ¶

    Create a stack artefact wrapper for a given stack element.

    const addInitialStackElement = function (el) {
    
        let mygroup = el.getAttribute('data-group'),
            myname = el.id || el.getAttribute('name'),
            position = 'absolute';
    
        if (!mygroup) {
    
            el.setAttribute('data-group', 'root');
            mygroup = 'root';
            position = 'relative';
        }
    
        if (!myname) {
    
            myname = generateUniqueString();
            el.id = myname;
        }
    
        let mystack = makeStack({
            name: myname,
            domElement: el,
            group: mygroup,
            host: mygroup,
            position: position,
            setInitialDimensions: true
        });
    
        processNewStackChildren(el, myname);
    
        return mystack;
    };
  • ¶

    Helper function for addInitialStackElement()

    const processNewStackChildren = function (el, name) {
    
        let hostDims = el.getBoundingClientRect(),
            y = 0;
  • ¶

    Only go down one level of hierarchy here; stacks don’t do hierarchies, only interested in knowing about immediate child elements

        Array.from(el.children).forEach(child => {
        
            if (child.getAttribute('data-stack') == null && !isa_canvas(child) && child.tagName !== 'SCRIPT') {
    
                let dims = child.getBoundingClientRect(),
                    computed = window.getComputedStyle(child);
    
                let yHeight = parseFloat(computed.marginTop) + parseFloat(computed.borderTopWidth) + parseFloat(computed.paddingTop) + parseFloat(computed.paddingBottom) + parseFloat(computed.borderBottomWidth) + parseFloat(computed.marginBottom);
    
                y = (!y) ? dims.top - hostDims.top : y;
    
                let args = {
                    name: child.id || child.getAttribute('name'),
                    domElement: child,
                    group: name,
                    host: name,
                    position: 'absolute',
                    width: dims.width,
                    height: dims.height,
                    startX: dims.left - hostDims.left,
                    startY: y,
                    classes: (child.className) ? child.className : '',
                };
    
                y += yHeight + dims.height;
    
                makeElement(args);
            }
  • ¶

    No need to worry about processing child stacks - they’ll already be in the list of stacks to be processed

            else child.setAttribute('data-group', name);
        });
    };
  • ¶

    Exported function (to modules and scrawl object). Use addStack to add a Scrawl-canvas stack element to a web page, or transform an existing element into a stack element. The items argument can include

    • element - the DOM element to be the stack - if not present, will autogenerate a div element
    • host - the host element, either as the DOM element itself, or some sort of CSS search string; if not present, will create the stack at the stack element’s current place or, failing all else, add the stack to the end of the document body
    • name - String identifier for the stack; if not included the function will attempt to use the element’s existing id or name attribute or, failing that, generate a random name for the stack.
    • any other regular stack attribute
    const addStack = function (items = {}) {
  • ¶

    define variables

        let el, host, hostinscrawl, mystack, mygroup, name,
            position = 'absolute',
            newElement = false;
  • ¶

    get, or generate a new, stack-to-be element

        if (items.element && items.element.substring) el = document.querySelector(items.element);
        else if (isa_dom(items.element)) el = items.element;
        else {
    
            newElement = true;
            el = document.createElement('div');
        }
  • ¶

    get element’s host (parent-to-be) element

        if (items.host && items.host.substring) {
    
            host = document.querySelector(items.host);
            if (!host) host = document.body;
        }
        else if (isa_dom(items.host)) host = items.host;
        else if (xt(el.parentElement)) host = el.parentElement;
        else host = document.body;
  • ¶

    if dimensions have been set in the argument, apply them to the stack-to-be element

        if (xt(items.width)) el.style.width = (items.width.toFixed) ? `${items.width}px` : items.width;
        if (xt(items.height)) el.style.height = (items.height.toFixed) ? `${items.height}px` : items.height;
  • ¶

    make sure the stack-to-be element has an id attribute

        name = items.name || el.id || el.getAttribute('name') || '';
        if (!name) name = generateUniqueString();
        el.id = name;
  • ¶

    set the ‘data-stack’ attribute on the stack-to-be element

        el.setAttribute('data-stack', 'data-stack');
  • ¶

    determine whether the parent element is already known to Scrawl-canvas - affects the stack-to-be element’s group

        if (host && host.getAttribute('data-stack') != null) {
    
            hostinscrawl = artefact[host.id];
    
            mygroup = (hostinscrawl) ? hostinscrawl.name : 'root';
        }
        else mygroup = 'root';
  • ¶

    set the ‘data-group’ attribute on the stack-to-be element

        el.setAttribute('data-group', mygroup);
  • ¶

    determine what the stack-to-be element’s position style attribute will be

        if (mygroup === 'root') position = 'relative';
  • ¶

    add (or move) the stack-to-be element to/in the DOM

        if (!el.parentElement || host.id !== el.parentElement.id) host.appendChild(el);
  • ¶

    create the Scrawl-canvas Stack artefact

        mystack = makeStack({
            name: name,
            domElement: el,
            group: mygroup,
            host: mygroup,
            position: position,
            setInitialDimensions: true
        });
    
        processNewStackChildren(el, name);
  • ¶

    in case any of the child elements were already a Scrawl-canvas stack, un-root them (if required)

        Array.from(el.childNodes).forEach(child => {
    
            if (child.id && rootElements.indexOf(child.id) >= 0) removeItem(rootElements, child.id);
        });
  • ¶

    set the new Stack’s remaining attributes, clearing out any attributes already handled

        delete items.name;
        delete items.element;
        delete items.host;
        delete items.width;
        delete items.height;
        mystack.set(items);
  • ¶

    tidy up and complete

        rootElementsSort = true;
        return mystack;
    };
  • ¶

    Canvas discovery

    Exported function (to modules). Parse the DOM, looking for <canvas> elements; then create Canvas artefact and Cell asset wrappers for each canvas found. Canvas elements do not need to be part of a stack and can appear anywhere in the HTML body.

    const getCanvases = function () {
    
        let item;
    
        document.querySelectorAll('canvas').forEach((el, index) => {
    
            item = addInitialCanvasElement(el);
    
            if (!index) setCurrentCanvas(item);
        });
    };
  • ¶

    Create a canvas artefact wrapper for a given canvas element.

    const addInitialCanvasElement = function (el) {
    
        let mygroup = el.getAttribute('data-group'),
            myname = el.id || el.getAttribute('name'),
            position = 'absolute';
    
        if (!mygroup) {
    
            el.setAttribute('data-group', 'root');
            mygroup = 'root';
            position = el.style.position;
        }
    
        if (!myname) {
    
            myname = generateUniqueString();
            el.id = myname;
        }
    
        return makeCanvas({
            name: myname,
            domElement: el,
            group: mygroup,
            host: mygroup,
            position: position,
            setInitialDimensions: true
        });
    };
  • ¶

    Exported function (to modules and scrawl object). Parse the DOM, looking for a specific <canvas> element; then create a Canvas artefact and Cell asset wrapper for it.

    const getCanvas = function (search) {
    
        let el = document.querySelector(search),
            canvas = false;
    
        if (el) canvas = addInitialCanvasElement(el);
    
        setCurrentCanvas(canvas);
        return canvas;
    };
  • ¶

    Exported function (to modules and scrawl object). Parse the DOM, looking for a specific element; then create a Stack artefact wrapper for it.

    const getStack = function (search) {
    
        let el = document.querySelector(search),
            stack;
    
        if (el) stack = addInitialStackElement(el);
        return stack;
    };
  • ¶

    Scrawl-canvas expects one canvas element (if any canvases are present) to act as the ‘current’ canvas on which other factory functions - such as adding new entitys - can act. The current canvas can be changed at any time using scrawl.setCurrentCanvas

  • ¶

    Exported variables (to modules).

    let currentCanvas = null,
        currentGroup = null;
  • ¶

    Exported function (to modules and scrawl object).

    const setCurrentCanvas = function (item) {
    
        let changeFlag = false;
    
        if (item) {
    
            if (item.substring) {
    
                let mycanvas = canvas[item];
    
                if (mycanvas) {
                    currentCanvas = mycanvas;
                    changeFlag = true;    
                }
            }
            else if (item.type === 'Canvas') {
    
                currentCanvas = item;    
                changeFlag = true;    
            } 
        }
    
        if (changeFlag && currentCanvas.base) {
    
            let mygroup = group[currentCanvas.base.name];
    
            if (mygroup) currentGroup = mygroup;
        }
    };
  • ¶

    Exported function (to modules and scrawl object). Use addCanvas to add a Scrawl-canvas canvas element to a web page. The items argument should include

    • host - the host element, either as the DOM element itself, or some sort of CSS search string, or a Scrawl-canvas Stack entity. If no host is supplied, Scrawl-canvas will add the new canvas element to the DOM document body; in all cases, the new canvas element is appended at the end of the host element (or DOM document)
    • name - String identifier for the element; will generate a random name for the canvas if no name is supplied.
    • any other regular Scrawl-canvas Canvas artefact attribute

    By default, Scrawl-canvas will setup the new Canvas as the ‘current canvas’, and will add mouse/pointer tracking functionality to it. If no dimensions are supplied then the Canvas will default to 300px wide and 150px high.

    const addCanvas = function (items = {}) {
    
        let el = document.createElement('canvas'),
            myname = (items.name) ? items.name : generateUniqueString(),
            host = items.host,
            mygroup = 'root',
            width = items.width || 300,
            height = items.height || 150,
            position = 'relative';
    
        if (host.substring) {
    
            let temphost = artefact[host];
    
            if (!temphost && host) {
    
                host = document.querySelector(host);
    
                if (host) mygroup = host.id;
            }
            else host = temphost;
        }
    
        if (host) {
    
            if (host.type === 'Stack') {
    
                mygroup = host.name;
                position = 'absolute';
                host = host.domElement;
            }
            else if (!isa_dom(host)) host = document.body;
        }
        else host = document.body;
    
        el.id = myname;
        el.setAttribute('data-group', mygroup);
        el.width = width;
        el.height = height;
        el.style.position = position;
    
        host.appendChild(el);
    
        let mycanvas = makeCanvas({
            name: myname,
            domElement: el,
            group: mygroup,
            host: mygroup,
            position: position,
            setInitialDimensions: false,
            setAsCurrentCanvas: (xt(items.setAsCurrentCanvas)) ? items.setAsCurrentCanvas : true,
            trackHere: (xt(items.trackHere)) ? items.trackHere : 'subscribe',
        });
    
        delete items.group;
        delete items.host;
        delete items.name;
        delete items.element;
        delete items.position;
        delete items.setInitialDimensions;
        delete items.setAsCurrentCanvas;
        delete items.trackHere;
    
        mycanvas.set(items);
    
        return mycanvas;
    };
  • ¶

    The Display cycle

    Scrawl-canvas breaks down the Display cycle into three parts: clear; compile; and show. These can be triggered either as a single, combined render operation, or separately as-and-when needed.

    The order in which DOM stack and canvas elements are processed during the display cycle can be changed by setting that element’s controller’s order attribute to a higher or lower integer value; elements are processed (in batches) from lowest to highest order value

    Each display cycle function returns a Promise object which will resolve as true if the function completes successfully; false otherwise. These promises will never reject

    Note that Scrawl-canvas supplies a convenience function - makeRender() - for automating the process of creating an animation object to handle the Display cycle

  • ¶
    Clear
    • For canvas artefacts, clear its Cell assets’ display (reset all pixels to 0, or the designated background color) ready for them to be redrawn
    • For stack artefacts - no action required
  • ¶

    Exported function (to modules and scrawl object).

    const clear = function (...items) {
    
        displayCycleHelper(items);
        return displayCycleBatchProcess('clear');
    };
  • ¶
    Compile
    • For both canvas and stack artefacts, perform necessary entity/element positional calculations
    • Additionally for canvas artefacts, stamp associated entitys onto the canvas’s constituent cell assets
  • ¶

    Exported function (to modules and scrawl object).

    const compile = function (...items) {
    
        displayCycleHelper(items);
        return displayCycleBatchProcess('compile');
    };
  • ¶
    Show
    • For canvas artefacts, stamp additional ‘layer’ canvases onto the base canvas, then copy the base canvas onto the display canvas
    • For stack artefacts - invoke the domShow function, if any of its constituent elements require DOM-related updating
  • ¶

    Exported function (to modules and scrawl object).

    const show = function (...items) {
    
        displayCycleHelper(items);
        return displayCycleBatchProcess('show');
    };
  • ¶
    Render
    • Orchestrate the clear, compile and show actions on each stack and canvas DOM element
  • ¶

    Exported function (to modules and scrawl object).

    const render = function (...items) {
    
        displayCycleHelper(items);
        return displayCycleBatchProcess('render');
    };
  • ¶

    Helper functions coordinate the actions required to complete a display cycle

    const displayCycleHelper = function (items) {
    
        if (items.length) rootElements_sorted = items;
        else if (rootElementsSort) sortRootElements();
    };
    
    const displayCycleBatchProcess = function (method) {
    
        return new Promise((resolve, reject) => {
    
            let promises = [],
                item;
    
            rootElements_sorted.forEach(name => {
    
                item = artefact[name];
    
                if (item && item[method]) promises.push(item[method]());
            })
    
            Promise.all(promises)
            .then(() => resolve(true))
            .catch(err => reject(err));
        })
    };
  • ¶

    DOM element updates

    Scrawl-canvas will batch process all DOM element updates, to minimize disruptive impacts on web page performance. We don’t maintain a full/comprehensive ‘shadow’ or ‘virtual’ DOM, but Scrawl-canvas does maintain a record of element (absolute) position and dimension data, alongside details of scaling, perspective and any other CSS related data (including CSS classes) which we tell it about, on a per-element basis.

    The decision on whether to update a DOM element is mediated through a suite of ‘dirty’ flags assigned on the Scrawl-canvas artefact object which wraps each DOM element. As part of the compile component of the Scrawl-canvas Display cycle, the code will take a decision on whether the DOM element needs to be updated and insert the artefact’s name in the domShowElements array, and set the domShowRequired flag to true, which will then trigger the domShow() function to run at the end of each Display cycle.

    The domShow() function is exported, and can be triggered for any DOM-related artefact at any time by invoking it with the artefact’s name as the function’s argument.

    The order in which DOM elements get updated is determined by the order attributes set on the Stack artefact, on Group objects, and (least important) on the element artefact.

  • ¶

    Local variable

    const domShowElements = [];
  • ¶

    Exported function (to modules).

    const addDomShowElement = function (item = '') {
    
        if (!item) throw new Error(`core/document addDomShowElement() error - false argument supplied: ${item}`);
        if (!item.substring) throw new Error(`core/document addDomShowElement() error - argument not a string: ${item}`);
    
        pushUnique(domShowElements, item);
    };
    
    let domShowRequired = false;
  • ¶

    Exported function (to modules).

    const setDomShowRequired = function (val = true) {
    
        domShowRequired = val;
    };
  • ¶

    Exported function (to modules). This is the main DOM manipulation function which will be triggered once during each Display cycle.

    const domShow = function (singleArtefact = '') {
    
        if (domShowRequired || singleArtefact) {
    
            let myartefacts;
    
            if (singleArtefact) myartefacts = [singleArtefact];
            else {
    
                domShowRequired = false;
                myartefacts = [].concat(domShowElements);
                domShowElements.length = 0;
            }
  • ¶

    given the critical nature of these loops, using ‘for’ instead of ‘forEach’

            let i, iz, name, art, el, style,
                p, dims, w, h,
                j, jz, items, keys, key, keyName, value;
    
            for (i = 0, iz = myartefacts.length; i < iz; i++) {
    
                name = myartefacts[i];
    
                art = artefact[name];
                if (!art) throw new Error(`core/document domShow() error - artefact missing: ${name}`);
    
                el = art.domElement;
                if (!el) throw new Error(`core/document domShow() error - DOM element missing: ${name}`);
    
                style = el.style;
  • ¶

    update perspective

                if (art.dirtyPerspective) {
    
                    art.dirtyPerspective = false;
    
                    p = art.perspective;
    
                    style.perspectiveOrigin = `${p.x} ${p.y}`;
                    style.perspective = `${p.z}px`;
                }
  • ¶

    update position

                if (art.dirtyPosition) {
    
                    art.dirtyPosition = false;
                    style.position = art.position;
                }
  • ¶

    update dimensions

                if (art.dirtyDomDimensions) {
    
                    art.dirtyDomDimensions = false;
    
                    dims = art.currentDimensions;
                    w = dims[0];
                    h = dims[1];
    
                    if (art.type === 'Canvas') {
    
                        el.width = w;
                        el.height = h;
    
                        if (art.renderOnResize) art.render().catch(err => console.log(err));
                    }
                    else {
    
                        style.width = `${w}px`;
                        style.height = (h) ? `${h}px` : 'auto';
                    }
                }
  • ¶

    update handle/transformOrigin

                if (art.dirtyTransformOrigin) {
    
                    art.dirtyTransformOrigin = false;
                    style.transformOrigin = art.currentTransformOriginString;
                }
  • ¶

    update transform

                if (art.dirtyTransform) {
    
                    art.dirtyTransform = false;
                    style.transform = art.currentTransformString;
                }
  • ¶

    update visibility

                if (art.dirtyVisibility) {
    
                    art.dirtyVisibility = false;
                    style.display = (art.visibility) ? 'block' : 'none';
                }
  • ¶

    update other CSS changes

                if (art.dirtyCss) {
    
                    art.dirtyCss = false;
    
                    items = art.css || {};
                    keys = Object.keys(items);
    
                    for (j = 0, jz = keys.length; j < jz; j++) {
    
                        key = keys[j];
                        value = items[key];
    
                        if (xcss.has(key)) {
    
                            keyName = `${key[0].toUpperCase}${key.substr(1)}`;
    
                            style[`webkit${keyName}`] = value;
                            style[`moz${keyName}`] = value;
                            style[`ms${keyName}`] = value;
                            style[`o${keyName}`] = value;
                            style[key] = value;
                        }
                        else if (css.has(key)) style[key] = value;
                    }
                }
  • ¶

    update element classes

                if (art.dirtyClasses) {
    
                    art.dirtyClasses = false;
                    if (el.className.substring) el.className = art.classes;
                }
            }
        }
    };
  • ¶

    DOM Holding areas

    Exported handles (to modules). During its initialization phase, Scrawl-canvas will add two hidden ‘hold’ elements at the top and bottom of the document body where it can add additional elements as-and-when required.

  • ¶

    Mainly for ARIA content. ARIA labels and descriptions are used by Scrawl-canvas <canvas> elements to inform non-visual website visitors about content in the canvas.

    let scrawlCanvasHold = document.createElement('div');
    scrawlCanvasHold.style.padding = 0;
    scrawlCanvasHold.style.border = 0;
    scrawlCanvasHold.style.margin = 0;
    scrawlCanvasHold.style.width = '4500px';
    scrawlCanvasHold.style.boxSizing = 'border-box';
    scrawlCanvasHold.style.position = 'absolute';
    scrawlCanvasHold.style.top = '-5000px';
    scrawlCanvasHold.style.left = '-5000px';
    scrawlCanvasHold.id = 'Scrawl-ARIA-default-hold';
    document.body.appendChild(scrawlCanvasHold);
  • ¶

    Navigation area - canvas anchor links. Canvases create their own (hidden) <nav> elements that directly follow them in the DOM. These are used to store <a> links for clickable entitys in the canvas display, making them accessible to non-visual users (for example: screen readers)

    let scrawlNavigationHold = document.createElement('nav');
    scrawlNavigationHold.style.position = 'absolute';
    scrawlNavigationHold.style.top = '-5000px';
    scrawlNavigationHold.style.left = '-5000px';
    scrawlNavigationHold.id = 'Scrawl-navigation-default-hold';
    document.body.prepend(scrawlNavigationHold);
  • ¶

    Exports

    export {
        getCanvases,
        getCanvas,
        getStacks,
        getStack,
    
        addCanvas,
        addStack,
        setCurrentCanvas,
    
        currentCanvas,
        currentGroup,
    
        rootElements,
        setRootElementsSort,
    
        clear,
        compile,
        show,
        render,
    
        addDomShowElement,
        setDomShowRequired,
        domShow,
    
        scrawlCanvasHold,
        scrawlNavigationHold,
    };