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

    Filter mixin

    The filter mixin adds functionality to Cell, Group and all entity factories which allows those objects to use Scrawl-canvas Filter objects in their output.

  • ¶

    Demos:

    • Canvas-007 - Apply filters at the entity, group and cell level
    • Component-004 - Scrawl-canvas packets; save and load a range of different entitys
  • ¶

    Imports

    import { filter, asset } from '../core/library.js';
    import { mergeOver, pushUnique, removeItem } from '../core/utilities.js';
    import { requestCell, releaseCell } from '../factory/cell.js';
  • ¶

    Export function

    export default function (P = {}) {
  • ¶

    Filter-related attributes

    All factories using the filter mixin will add these attributes to their objects

        let defaultAttributes = {
  • ¶

    filters - An array of filter object String names. If only one filter is to be applied, then it is enough to use the String name of that filter object - Scrawl-canvas will make sure it gets added to the Array.

    • To add/remove new filters to the filters array, use the addFilters and removeFilters functions. Note that the set function will replace all the existing filters in the array with the new filters. To remove all existing filters from the array, use the clearFilters function
    • Multiple filters will be batch-applied to an entity, group of entitys, or an entire cell in one operation. Filters are applied in the order that they appear in in the filters array.
    • Be aware that the “filters” (plural) attribute is different to the CSS/SVG “filter” (singular) attribute - details about how Scrawl-canvas uses CSS/SVG filter Strings to produce filtering effects (at the entity and Cell levels only) are investigated in the Filter Demos 051 to 055. CSS/SVG filter Strings can be applied in addition to Scrawl-canvas filters Array objects, and will be applied after them.
            filters: null,
  • ¶

    isStencil - Use the entity as a stencil. When this flag is set filter effects will be applied to the background imagery covered by the entity (or Group of entitys, or Cell), the results of which will replace the entity/Group/Cell in the final display.

            isStencil: false,
        };
        P.defs = mergeOver(P.defs, defaultAttributes);
  • ¶

    Get, Set, deltaSet

        let S = P.setters;
  • ¶

    filters - ___Dangerous action!__ - replaces the existing filters Array with a new filters Array. If a string name is supplied, will add that name to the existing filters array

        S.filters = function (item) {
    
            if (!Array.isArray(this.filters)) this.filters = [];
    
            if (item) {
    
                if (Array.isArray(item)) {
    
                    this.filters = item;
    
                    this.dirtyFilters = true;
                    this.dirtyImageSubscribers = true;
            
                }
                else if (item.substring) {
                    
                    pushUnique(this.filters, item); 
    
                    this.dirtyFilters = true;
                    this.dirtyImageSubscribers = true;
                }
            }
        };
  • ¶

    Packet management

    No additional packet functionality defined here

  • ¶

    Clone management

    No additional clone functionality defined here

  • ¶

    Kill management

    No additional kill functionality defined here

  • ¶

    Get, Set, deltaSet

    No additional functionality defined here

  • ¶

    Prototype functions

    cleanFilters - Internal housekeeping

        P.cleanFilters = function () {
    
            this.dirtyFilters = false;
    
            if (!this.filters) this.filters = [];
    
            let myfilters = this.filters,
                floor = Math.floor,
                buckets = [],
                myobj, order;
    
            myfilters.forEach(name => {
    
                myobj = filter[name];
    
                if (myobj) {
    
                    order = floor(myobj.order) || 0;
    
                    if (!buckets[order]) buckets[order] = [];
    
                    buckets[order].push(myobj);
                }
            });
    
            this.currentFilters = buckets.reduce((a, v) => a.concat(v), []);
        };
  • ¶

    addFilters, removeFilters - Add or remove one or more filter name strings to/from the filters array. Filter name strings can be supplied as comma-separated arguments to the function

        P.addFilters = function (...args) {
    
            if (!Array.isArray(this.filters)) this.filters = [];
    
            args.forEach(item => {
    
                if (item && item.type === 'Filter') item = item.name;
                pushUnique(this.filters, item);
    
            }, this);
    
            this.dirtyFilters = true;
            this.dirtyImageSubscribers = true;
    
            return this;
        };
    
        P.removeFilters = function (...args) {
    
            if (!Array.isArray(this.filters)) this.filters = [];
    
            args.forEach(item => {
    
                if (item && item.type === 'Filter') item = item.name;
                removeItem(this.filters, item);
    
            }, this);
    
            this.dirtyFilters = true;
            this.dirtyImageSubscribers = true;
            
            return this;
        };
  • ¶

    clearFilters - Clears the filters array

        P.clearFilters = function () {
    
            if (!Array.isArray(this.filters)) this.filters = [];
    
            this.filters.length = 0;
    
            this.dirtyFilters = true;
            this.dirtyImageSubscribers = true;
            
            return this;
        };
  • ¶

    preprocessFilters - internal function called as part of the Display cycle. The process-image filter action loads a Scrawl-canvas asset into the filters web worker, where it can be used as a lineIn or lineMix argument for other filter actions.

        P.preprocessFilters = function (filters) {
    
            filters.forEach(filter => {
    
                filter.actions.forEach(obj => {
    
                    if (obj.action == 'process-image') {
    
                        let flag = true;
    
                        let img = asset[obj.asset];
    
                        if (img) {
    
                            if (img.type === 'Noise') {
    
                                img.checkSource();
                            }
    
                            let width = img.sourceNaturalWidth || img.sourceNaturalDimensions[0] || img.currentDimensions[0],
                                height = img.sourceNaturalHeight || img.sourceNaturalDimensions[1] || img.currentDimensions[1];
    
                            if (width && height) {
    
                                flag = false;
    
                                let copyX = obj.copyX || 0,
                                    copyY = obj.copyY || 0,
                                    copyWidth = obj.copyWidth || 1,
                                    copyHeight = obj.copyHeight || 1,
                                    destWidth = obj.width || 1,
                                    destHeight = obj.height || 1;
    
                                if (copyX.substring) copyX = (parseFloat(copyX) / 100) * width;
                                if (copyY.substring) copyY = (parseFloat(copyY) / 100) * height;
                                if (copyWidth.substring) copyWidth = (parseFloat(copyWidth) / 100) * width;
                                if (copyHeight.substring) copyHeight = (parseFloat(copyHeight) / 100) * height;
    
                                copyX = Math.abs(copyX);
                                copyY = Math.abs(copyY);
                                copyWidth = Math.abs(copyWidth);
                                copyHeight = Math.abs(copyHeight);
    
                                if (copyX > width) {
                                    copyX = width - 2;
                                    copyWidth = 1;
                                }
    
                                if (copyY > height) {
                                    copyY = height - 2;
                                    copyHeight = 1;
                                }
    
                                if (copyWidth > width) {
                                    copyWidth = width - 1;
                                    copyX = 0;
                                }
    
                                if (copyHeight > height) {
                                    copyHeight = height - 1;
                                    copyY = 0;
                                }
    
    
                                if (copyX + copyWidth > width) {
                                    copyX = width - copyWidth - 1;
                                }
    
                                if (copyY + copyHeight > height) {
                                    copyY = height - copyHeight - 1;
                                }
    
                                let cell = requestCell(),
                                    engine = cell.engine,
                                    canvas = cell.element;
    
                                canvas.width = destWidth;
                                canvas.height = destHeight;
    
                                engine.setTransform(1, 0, 0, 1, 0, 0);
                                engine.globalCompositeOperation = 'source-over';
                                engine.globalAlpha = 1;
    
                                let src = img.source || img.element;
    
                                engine.drawImage(src, copyX, copyY, copyWidth, copyHeight, 0, 0, destWidth, destHeight);
    
                                obj.assetData = engine.getImageData(0, 0, destWidth, destHeight);
    
                                releaseCell(cell);
                            }
                        }
    
                        if (flag) {
    
                            obj.assetData = {
                                width: 1,
                                height: 1,
                                data: [0, 0, 0, 0],
                            }
                        }
                    }
                });
            });
        };
  • ¶

    Return the prototype

        return P;
    };