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

    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.

    • Most pattern-related functionality has been coded up in the styles mixin, and is documented there.
    • Functionality associated with assets, which Patterns use as their source, has been coded up in the assetConsumer mixin.
    • Patterns fully participate in the Scrawl-canvas packet system, thus can be saved, restored, cloned, killed, etc.
    • Patterns cannot be animated as such, but a Cell wrapper that is used as the Pattern’s source can be animated in any of the normal ways.
    • Scrawl-canvas does not support the Canvas API CanvasPattern.setTransform() method - it appears to be based on the SVGMatrix interface, which was deprecated in the SVG2 standard.
  • ¶

    Demos:

    • Canvas-009 - Pattern styles; Entity web link anchors; Dynamic accessibility
    • Canvas-035 - Pattern style functionality
  • ¶

    Imports

    import { constructors, cell, entity } from '../core/library.js';
    import { mergeOver, pushUnique, isa_obj } from '../core/utilities.js';
    import { gettableVideoAssetAtributes, settableVideoAssetAtributes } from './videoAsset.js';
    import { gettableImageAssetAtributes, settableImageAssetAtributes } from './imageAsset.js';
    
    
    import baseMix from '../mixin/base.js';
    import patternMix from '../mixin/pattern.js';
    import assetConsumerMix from '../mixin/assetConsumer.js';
  • ¶

    Pattern constructor

    const Pattern = function (items = {}) {
    
        this.makeName(items.name);
        this.register();
        this.set(this.defs);
        this.set(items);
    
        return this;
    };
  • ¶

    Pattern prototype

    let P = Pattern.prototype = Object.create(Object.prototype);
    
    P.type = 'Pattern';
    P.lib = 'styles';
    P.isArtefact = false;
    P.isAsset = false;
  • ¶

    Mixins

    P = baseMix(P);
    P = patternMix(P);
    P = assetConsumerMix(P);
  • ¶

    Pattern attributes

    • Attributes defined in the base mixin: name.
    • Attributes defined in the pattern mixin: repeat, patternMatrix, matrixA, matrixB, matrixC, matrixD, matrixE, matrixF.
    • Attributes defined in the assetConsumer mixin: asset, spriteTrack, imageSource, spriteSource, videoSource, source.
    let defaultAttributes = {};
    P.defs = mergeOver(P.defs, defaultAttributes);
  • ¶

    Packet management

    P.packetObjects = pushUnique(P.packetObjects, ['asset']);
    
    P.finalizePacketOut = function (copy, items) {
    
        if (Array.isArray(items.patternMatrix)) copy.patternMatrix = items.patternMatrix;
        else {
    
            let 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 () {
    
        let { name, asset, removeAssetOnKill } = this;
    
        if (isa_obj(asset)) asset.unsubscribe(this);
  • ¶

    Remove style from all entity state objects

        Object.entries(entity).forEach(([label, ent]) => {
    
            let state = ent.state;
    
            if (state) {
    
                let fill = state.fillStyle,
                    stroke = state.strokeStyle;
    
                if (isa_obj(fill) && fill.name === name) state.fillStyle = state.defs.fillStyle;
                if (isa_obj(stroke) && stroke.name === name) state.strokeStyle = state.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) {
    
        let source = this.source;
    
        if ((item.indexOf('video_') === 0 || item.indexOf('image_') === 0) && source) {
    
            if (gettableVideoAssetAtributes.indexOf(item) >= 0) return source[item.substring(6)];
            else if (gettableImageAssetAtributes.indexOf(item) >= 0) return source[item.substring(6)];
        }
    
        else {
    
            let getter = this.getters[item];
    
            if (getter) return getter.call(this);
    
            else {
    
                let def = this.defs[item],
                    val;
    
                if (typeof def != 'undefined') {
    
                    val = this[item];
                    return (typeof val != 'undefined') ? val : def;
                }
                return undef;
            }
        }
    };
  • ¶

    set

    P.set = function (items = {}) {
    
        if (Object.keys(items).length) {
    
            let setters = this.setters,
                defs = this.defs,
                source = this.source,
                predefined;
    
            Object.entries(items).forEach(([key, value]) => {
    
                if ((key.indexOf('video_') === 0 || key.indexOf('image_') === 0) && source) {
    
                    if (settableVideoAssetAtributes.indexOf(key) >= 0) source[key.substring(6)] = value
                    else if (settableImageAssetAtributes.indexOf(key) >= 0) source[key.substring(6)] = value
                }
    
                else if (key && key !== 'name' && value != null) {
    
                   predefined = setters[key];
    
                    if (predefined) predefined.call(this, value);
                    else if (typeof defs[key] !== 'undefined') this[key] = value;
                }
            }, this);
        }
        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',
    });
    const makePattern = function (items) {
        return new Pattern(items);
    };
    
    constructors.Pattern = Pattern;
  • ¶

    Exports

    export {
        makePattern,
    };