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

    DOM management

    Core DOM element discovery and management functionality

    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 { artefact, entitynames, entity } from "./library.js";
    
    import { pushUnique, Ωempty } from "../helper/utilities.js";
    
    import { getPixelRatio, getIgnorePixelRatio } from "./user-interaction.js";
    
    import { releaseArray, requestArray } from '../helper/array-pool.js';
  • §

    Shared constants

    import { _keys, AUTO, BLOCK, FONT_USERS, NONE, T_CANVAS, ZERO_STR } from '../helper/shared-vars.js';
  • §

    Local constants

    const ignoredCssProperties = ['bottom', 'boxSizing', 'display', 'height', 'left', 'perspective', 'perspectiveOrigin', 'position', 'right', 'top', 'transform', 'transformOrigin', 'width', 'zIndex'];
  • §

    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 = [];
    let domShowRequired = false;
  • §

    Exported function (to modules).

    export const setDomShowRequired = (val = true) => domShowRequired = val;
  • §

    Exported function (to modules).

    export const addDomShowElement = function (item = ZERO_STR) {
    
        if (item && item.substring) {
    
            pushUnique(domShowElements, item);
        }
    };
  • §

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

    export const domShow = function (singleArtefact = ZERO_STR) {
    
        if (domShowRequired || singleArtefact) {
    
            const myartefacts = requestArray();
    
            if (singleArtefact && singleArtefact.substring) myartefacts.push(singleArtefact);
            else {
    
                domShowRequired = false;
                myartefacts.push(...domShowElements);
                domShowElements.length = 0;
            }
    
            let i, iz, art, el, style,
                p, dims, w, h,
                j, jz, items, keys, key, value;
    
            const ignoreDpr = getIgnorePixelRatio();
            const dpr = getPixelRatio();
    
            for (i = 0, iz = myartefacts.length; i < iz; i++) {
    
                art = artefact[myartefacts[i]];
    
                if (art) {
    
                    el = art.domElement;
    
                    if (el) {
  • §

    update element classes

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

    update non-controlled CSS changes

                            if (art.dirtyCss) {
    
                                art.dirtyCss = false;
    
                                items = art.css || Ωempty;
                                keys = _keys(items);
    
                                for (j = 0, jz = keys.length; j < jz; j++) {
    
                                    key = keys[j];
                                    value = items[key];
  • §

    SC no longer cares about browser-specific prefixes

                                    if (!ignoredCssProperties.includes(key)) style[key] = value;
                                }
                            }
  • §

    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 === T_CANVAS) {
    
                                    if (ignoreDpr) {
    
                                        el.width = w;
                                        el.height = h;
                                    }
                                    else {
    
                                        if (!art.ignoreCanvasCssDimensions) {
    
                                            style.width = `${w}px`;
                                            style.height = `${h}px`;
                                        }
    
                                        el.width = w * dpr;
                                        el.height = h * dpr;
                                    }
                                    if (art.renderOnResize) art.render();
                                }
                                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 stampOrder

                            if (art.dirtyStampOrder) {
    
                                art.dirtyStampOrder = false;
                                style.zIndex = art.stampOrder;
                            }
                        }
                    }
                }
            }
            releaseArray(myartefacts);
        }
    };
    
    export const recalculateFonts = (delay = 100) => {
    
        setTimeout(() => {
    
            entitynames.forEach(name => {
    
                const ent = entity[name];
    
                if (FONT_USERS.includes(ent.type)) ent.recalculateFont();
            });
        }, delay);
    };