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

    Element factory

    The Scrawl-canvas Stack/Element system is an attempt to supplement DOM elements with Scrawl-canvas entity positioning and dimensioning functionality.

    • Entitys exist in a Cell environment
    • They can position themselves within that Cell either absolutely (px coordinates), or relatively (% coordinates, with values relative to the Cell’s dimensions), or by reference (using other entity’s coordinates to calculate their own coordinates - pivot, mimic, path)
    • They can also base their dimensions on absolute (px) or relative (%) values
    • They can be animated directly (set, deltaSet), or through automation (delta object), or through the Scrawl-canvas tween functionality
    • They can be stored and retrieved (‘packet’ functionality), cloned (‘clone’, based on packets) and killed (‘kill’ functions)

    A Stack is a wrapper object around a DOM element, whose direct children are given Scrawl-canvas Element wrappers:

    Stack    ~~> Canvas/Cell  
    Element  ~~> Entity (eg Block)  

    During initialization Scrawl-canvas will search the DOM tree and automatically create Stack wrappers for any element which has been given a data-stack attribute which resolves to true. Every direct (first level) child inside the stack element will have Element wrappers created for them (except for <canvas> elements). As part of this work, Scrawl-canvas will modify the affected elements’ position CSS style:

    • Stack elements have relative positioning within the DOM
    • Element elements have absolute positioning within the Stack

    The makeElement function is not exported by the scrawl object. To create a new Element within a Stack, use mystack.addNewElement({}).

    Element wrapper objects use the base, position, anchor and dom mixins. Thus Element wrappers are also artefact objects. As such, Elements can be used (almost) like any other artefact; in particular, other artefacts - including any canvas-based entity - can use Elements as their pivot or mimic targets.

    Element wrappers are included in the Scrawl-canvas packet system; they can be saved and cloned. Killing an Element wrapper will remove its DOM element from the document.

  • ¶

    Demos:

    • All stack demos include examples of using Elements. In particular:
    • DOM-002 - Element mouse, pivot and mimic functionality
    • DOM-003 - Dynamically create and clone Element artefacts; drag and drop elements (including SVG elements) around a Stack
    • DOM-004 - Limitless rockets (clone and destroy elements, tweens, tickers)
    • DOM-006 - Tween actions on a DOM element; tracking tween and ticker activity (analytics)
    • DOM-015 - Use stacked DOM artefact corners as pivot points
    • Component-002 - Scrawl-canvas stack element components
  • ¶

    Imports

    import { element, elementnames, artefact, artefactnames, constructors } from '../core/library.js';
    import { pushUnique, removeItem, isa_dom } from '../core/utilities.js';
    import { uiSubscribedElements } from '../core/userInteraction.js';
    
    import { makeCanvas } from './canvas.js';
    
    import baseMix from '../mixin/base.js';
    import domMix from '../mixin/dom.js';
  • ¶

    Element constructor

    const Element = function (items = {}) {
        
        let el = items.domElement;
    
        this.makeName(items.name);
        this.register();
    
        if (el) {
  • ¶

    Scrawl-canvas does not retain an Element’s textContent or innerHTML values internally. However these can be set on initialization, and subsequently, by using the attributes text (for textContent, which automatically escapes all HTML-related tags and entities) and content (which should respect HTML tags and entities)

            if (items.text) el.textContent = items.text;
            else if (items.content) el.innerHTML = items.content;
        }
    
        this.initializePositions();
        this.dimensions[0] = this.dimensions[1] = 100;
    
        this.pathCorners = [];
        this.css = {};
        this.here = {};
    
        this.initializeDomLayout(items);
    
        this.set(this.defs);
        this.set(items);
    
        el = this.domElement;
    
        if (el) el.id = this.name;
    
        this.apply();
        
        return this;
    };
  • ¶

    Element prototype

    let P = Element.prototype = Object.create(Object.prototype);
    P.type = 'Element';
    P.lib = 'element';
    P.isArtefact = true;
    P.isAsset = false;
  • ¶

    Mixins

    • base
    • dom
    P = baseMix(P);
    P = domMix(P);
  • ¶

    Element attributes

    • Attributes defined in the base mixin: name.
    • Attributes defined in the position mixin: group, visibility, order, start, startX, startY, handle, handleX, handleY, offset, offsetX, offsetY, dimensions, width, height, pivoted, mimicked, lockTo, lockXTo, lockYTo, scale, roll, noUserInteraction, noPositionDependencies, noCanvasEngineUpdates, noFilters, noPathUpdates, purge, bringToFrontOnDrag.
    • Attributes defined in the delta mixin: delta, noDeltaUpdates.
    • Attributes defined in the pivot mixin: pivot, pivotCorner, addPivotHandle, addPivotOffset, addPivotRotation.
    • Attributes defined in the mimic mixin: mimic, useMimicDimensions, useMimicScale, useMimicStart, useMimicHandle, useMimicOffset, useMimicRotation, useMimicFlip, addOwnDimensionsToMimic, addOwnScaleToMimic, addOwnStartToMimic, addOwnHandleToMimic, addOwnOffsetToMimic, addOwnRotationToMimic.
    • Attributes defined in the path mixin: path, pathPosition, addPathHandle, addPathOffset, addPathRotation, constantPathSpeed.
    • Attributes defined in the anchor mixin: anchor.
    • Attributes defined in the dom mixin: domElement, pitch, yaw, offsetZ, css, classes, position, actionResize, trackHere, domAttributes.

    No additional attributes required beyond those supplied by the mixins

  • ¶

    Packet management

    No additional packet functionality required

  • ¶

    Clone management

    No additional clone functionality required

  • ¶

    Kill management

    P.factoryKill = function () {
    
        removeItem(uiSubscribedElements, this.name);
    
        this.domElement.remove();
    };
  • ¶

    Get, Set, deltaSet

    let S = P.setters;
  • ¶

    text - this is the preferred way to update an element’s text content because the text supplied in the argument is not treated as HTML by the browser.

    When we update the DOM attribute element.textContent, it deletes any position-reporting corner divs we may have added to the element. Thus we need to repopulate the element with its ‘kids’ after updating the text

    S.text = function (item) {
    
        if (isa_dom(this.domElement)) {
    
            let el = this.domElement,
                kids = el.querySelectorAll('[data-corner-div="sc"]');
    
            el.textContent = item;
    
            kids.forEach(kid => el.appendChild(kid));
    
            this.dirtyContent = true;
        }
    };
  • ¶

    content - WARNING - this is a dangerous function! It does not perform any character escaping before inserting the supplied argument into the element. Raw HTML (including, for instance, <script> tags) will be added to the DOM. It’s up to the developer to make sure this content is safe!

    When we update the DOM attribute element.innerHTML, it deletes any position-reporting corner divs we may have added to the element. Thus we need to repopulate the element with its ‘kids’ after updating the text

    S.content = function (item) {
    
        if (this.domElement) {
    
            let el = this.domElement,
                kids = el.querySelectorAll('[data-corner-div="sc"]');
    
            el.innerHTML = item;
    
            kids.forEach(kid => el.appendChild(kid));
    
            this.dirtyContent = true;
        }
    };
  • ¶

    Prototype functions

  • ¶

    cleanDimensionsAdditionalActions - overwrites mixin/position function.

    P.cleanDimensionsAdditionalActions = function () {
    
        this.dirtyDomDimensions = true;
    };
  • ¶

    Component-related functions

  • ¶

    addCanvas - adds a new <canvas> element to Scrawl-canvas stack immediately before this element, and sets up the canvas to mimic the element (meaning it will mimic changes to the element’s dimensions, positioning, scale and 3D rotational values)

    • The function can accept a Javascript object argument containing key:value pairs which will be used to set up the new canvas’s attributes after it has been created.
    • To make the canvas look as if it is in front of the element, set the element’s opacity CSS attribute to 0
    • This function is used when adding a Scrawl-canvas component to a stacked element.
    P.addCanvas = function (items = {}) {
    
        if (!this.canvas) {
    
            let canvas = document.createElement('canvas'),
                el = this.domElement;
    
            let rect = el.getBoundingClientRect(),
                style = window.getComputedStyle(el);
    
            el.parentNode.insertBefore(canvas, this.domElement);
    
            let art = makeCanvas({
                name: `${this.name}-canvas`,
                domElement: canvas,
    
                position: 'absolute',
    
                width: rect.width,
                height: rect.height,
    
                mimic: this.name,
                lockTo: 'mimic',
                
                useMimicDimensions: true,
                useMimicScale: true,
                useMimicStart: true,
                useMimicHandle: true,
                useMimicOffset: true,
                useMimicRotation: true,
    
                addOwnDimensionsToMimic: false,
                addOwnScaleToMimic: false,
                addOwnStartToMimic: false,
                addOwnHandleToMimic: false,
                addOwnOffsetToMimic: false,
                addOwnRotationToMimic: false,
            });
    
            art.set(items);
    
            this.canvas = art;
    
            return art;
        }
    };
  • ¶

    Factory

    Get a handle to a Stack wrapper
    let stack = scrawl.library.stack.mystack;
    
    stack.addNewElement({
    
        name: 'list',
        tag: 'ul',
    
        width: '25%',
        height: 80,
    
        startX: 400,
        startY: 120,
        handleX: 'center',
        handleY: 'center',
    
        roll: 30,
    
        classes: 'red-text',
    
        content: `<li>unordered list</li>
    <li>with several</li>
    <li>bullet points</li>`,
    
        css: {
            font: '12px fantasy',
            paddingInlineStart: '20px',
            paddingTop: '0.5em',
            margin: '0',
            border: '1px solid red',
            cursor: 'grab',
        },
    
    }).clone({
    
        name: 'list-no-border',
    
        startY: 250,
        scale: 1.25,
        pitch: 60,
        yaw: 80,
    
        css: {
            border: 0,
        },
    });
    const makeElement = function (items) {
        
        return new Element(items);
    };
    
    constructors.Element = Element;
  • ¶

    Exports

    export {
        makeElement,
    };