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

    Pattern factory

    Scrawl-canvas Pattern objects implement the Canvas API’s createPattern method. The resulting CanvasPattern object can be used by any Scrawl-canvas entity as its fillStyle or strokeStyle.

  • §

    Imports

    import { constructors, entity } from '../core/library.js';
    
    import { doCreate, pushUnique, isa_obj, Ωempty } from '../helper/utilities.js';
    
    import { gettableVideoAssetAtributes, settableVideoAssetAtributes } from '../asset-management/video-asset.js';
    
    import { gettableImageAssetAtributes, settableImageAssetAtributes } from '../asset-management/image-asset.js';
    
    import baseMix from '../mixin/base.js';
    import patternMix from '../mixin/pattern.js';
    import assetConsumerMix from '../mixin/asset-consumer.js';
  • §

    Shared constants

    import { $IMAGE, $VIDEO, _isArray, _keys, _values, NAME, STYLES, UNDEF } from '../helper/shared-vars.js';
  • §

    Local constants

    const T_PATTERN = 'Pattern';
  • §

    Pattern constructor

    const Pattern = function (items = Ωempty) {
    
        this.makeName(items.name);
        this.register();
        this.set(this.defs);
    
        this.source = null;
        this.sourceNaturalWidth = 0;
        this.sourceNaturalHeight = 0;
        this.sourceLoaded = false;
        this.dirtyImage = true;
        this.dirtyCopyStart = true;
        this.dirtyCopyDimensions = true;
        this.dirtyImageSubscribers = true;
        this.patternMatrix = null;
    
        this.set(items);
    
        return this;
    };
  • §

    Pattern prototype

    const P = Pattern.prototype = doCreate();
    P.type = T_PATTERN;
    P.lib = STYLES;
    P.isArtefact = false;
    P.isAsset = false;
  • §

    Mixins

    baseMix(P);
    patternMix(P);
    assetConsumerMix(P);
  • §

    Pattern attributes

    No additional attributes required beyond those supplied by the mixins

  • §

    Packet management

    P.packetObjects = pushUnique(P.packetObjects, ['asset']);
    
    P.finalizePacketOut = function (copy, items) {
    
        if (_isArray(items.patternMatrix)) copy.patternMatrix = items.patternMatrix;
        else {
    
            const m = this.patternMatrix;
            if (m) copy.patternMatrix = [m.a, m.b, m.c, m.d, m.e, m.f];
        }
    
        return copy;
    };
  • §

    Clone management

    No additional clone functionality required

  • §

    Kill management

    P.kill = function () {
    
        const { name, asset, removeAssetOnKill } = this;
        let state, defs, fill, stroke;
    
        if (isa_obj(asset)) asset.unsubscribe(this);
  • §

    Remove style from all entity state objects

        _values(entity).forEach(ent => {
    
            state = ent.state;
            defs = state.defs;
    
            if (state) {
    
                fill = state.fillStyle;
                stroke = state.strokeStyle;
    
                if (isa_obj(fill) && fill.name === name) state.fillStyle = defs.fillStyle;
                if (isa_obj(stroke) && stroke.name === name) state.strokeStyle = defs.strokeStyle;
            }
        });
  • §

    Cascade kill invocation to the asset object, if required

        if (removeAssetOnKill) {
    
            if (removeAssetOnKill.substring) asset.kill(true);
            else asset.kill();
        }
  • §

    Remove style from the Scrawl-canvas library

        this.deregister();
    
        return this;
    };
  • §

    Get, Set, deltaSet

    Pattern get and set (but not deltaSet) functions need to take into account their current source, whose attributes can be retrieved/amended directly on the Picture object

  • §

    get

    P.get = function (item) {
    
        const source = this.source;
    
        if ((item.indexOf($VIDEO) === 0 || item.indexOf($IMAGE) === 0) && source) {
    
            if (gettableVideoAssetAtributes.includes(item)) return source[item.substring(6)];
            else if (gettableImageAssetAtributes.includes(item)) return source[item.substring(6)];
        }
    
        else {
    
            const getter = this.getters[item];
    
            if (getter) return getter.call(this);
    
            else {
    
                const def = this.defs[item];
    
                if (typeof def !== UNDEF) {
    
                    const val = this[item];
                    return (typeof val !== UNDEF) ? val : def;
                }
                return undefined;
            }
        }
    };
  • §

    set

    P.set = function (items = Ωempty) {
    
        const keys = _keys(items),
            keysLen = keys.length;
    
        if (keysLen) {
    
            const setters = this.setters,
                source = this.source,
                defs = this.defs;
    
            let fn, i, key, value;
    
            for (i = 0; i < keysLen; i++) {
    
                key = keys[i];
                value = items[key];
    
                if ((key.indexOf($VIDEO) === 0 || key.indexOf($IMAGE) === 0) && source) {
    
                    if (settableVideoAssetAtributes.includes(key)) source[key.substring(6)] = value
                    else if (settableImageAssetAtributes.includes(key)) source[key.substring(6)] = value
                }
    
                else if (key && key !== NAME && value != null) {
    
                    fn = setters[key];
    
                    if (fn) fn.call(this, value);
                    else if (typeof defs[key] !== UNDEF) this[key] = value;
                }
            }
            this.dirtyFilterIdentifier = true;
        }
        return this;
    };
  • §

    Prototype functions

  • §

    getData function called by Cell objects when calculating required updates to its CanvasRenderingContext2D engine, specifically for an entity’s fillStyle, strokeStyle and shadowColor attributes.

    • This is the point when we clean Scrawl-canvas assets which have told their subscribers that asset data/attributes have updated
    P.getData = function (entity, cell) {
    
        if (this.dirtyAsset) this.cleanAsset();
        this.asset.checkSource(this.sourceNaturalWidth, this.sourceNaturalHeight);
    
        return this.buildStyle(cell);
    };
  • §

    Factory

    scrawl.importDomImage('.mypatterns');
    
    scrawl.makePattern({
    
        name: 'brick-pattern',
        asset: 'brick',
    
    }).clone({
    
        name: 'marble-pattern',
        imageSource: 'img/marble.png',
    });
    
    scrawl.makeBlock({
    
        name: 'marble-block',
    
        width: '40%',
        height: '40%',
    
        startX: '25%',
        startY: '25%',
    
        handleX: 'center',
        handleY: 'center',
    
        lineWidth: 20,
        lineJoin: 'round',
    
        method: 'fillThenDraw',
    
        fillStyle: 'marble-pattern',
        strokeStyle: 'brick-pattern',
    });
    
    export const makePattern = function (items) {
    
        if (!items) return false;
        return new Pattern(items);
    };
    
    constructors.Pattern = Pattern;