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

    World factory

    The Scrawl-canvas particle physics engine is a simple system designed to allow developers a way to add particle-based effects to their canvas animation scenes. The physics engine is built on top of the following components:

    • Particle objects, which represent a 3-dimensional coordinate - based on a Scrawl-canvas Vector object - and include a history of recent positions which we can use to determine how to display that particle on screen.
    • History arrays which can be pooled (reused) to cut down on Array creation and distruction during the animation.
    • Force objects which define the general and occasional forces to be applied to each particle in the system as the animation progresses - a gravity force object is pre-defined by Scrawl-canvas.
    • Spring objects used to define a constraint (connection) between two particles in a system.
    • World objects where we can store attributes and values used by various objects; these attributes can be set up so that they will be inherited by clones of the World object. We can also influence the speed of the physics animation here.

    We do not have to handle particle generation and manipulation ourselves. Instead, Scrawl-canvas gives us three dedicated entitys which we use to add particle animation effects to the canvas scene. These entitys are:

    • Tracer - this entity generates a single non-recycled (in other words: long lasting) particle with a history, which we can use to display trace effects in the animation.
    • Emitter - an entity which generates a stream of short-lived, recycled particles, each with its own history. Emitters are highly versatile entitys which can generate a wide range of effects.
    • Net - a (generally) larger entity which uses both forces and springs to manage the animation of its non-recycled particles. Note that other artefacts can use Net particles as a reference for their own positioning.
  • ¶

    Demos:

    • particles-001 - Emitter entity, and Particle World, basic functionality
    • particles-002 - Emitter using artefacts
    • particles-003 - Position Emitter entity: start; pivot; mimic; path; mouse; drag-and-drop
    • particles-004 - Emit particles along the length of a path
    • particles-005 - Emit particles from inside an artefact’s area
    • particles-006 - Fixed number of particles in a field; preAction and postAction functionality
    • particles-007 - Particle Force objects: generation and functionality
    • particles-008 - Net entity: generation and basic functionality, including Spring objects
    • particles-009 - Net particles: drag-and-drop functionality
    • particles-010 - Net entity: using a shape path as a net template
    • particles-012 - Use Net entity particles as reference coordinates for other artefacts
    • canvas-040 - Trace out a Shape path over time
  • ¶

    Imports

    import { constructors } from '../core/library.js';
    import { mergeOver, isa_fn, xt } from '../core/utilities.js';
    
    import { makeQuaternion } from './quaternion.js';
    import { makeVector } from './vector.js';
    import { makeCoordinate } from './coordinate.js';
    
    import baseMix from '../mixin/base.js';
  • ¶

    World constructor

    const World = function (items = {}) {
    
        this.makeName(items.name);
        this.register();
    
        this.set(this.defs);
    
        let keytypes = items.keytypes || {};
        if (!keytypes.gravity) keytypes.gravity = 'Vector';
        if (!items.gravity) items.gravity = [0, 9.81, 0];
    
        if (items.userAttributes) {
    
            items.userAttributes.forEach(att => {
    
                this.addAttribute(att);
    
                if (att.type) keytypes[att.key] = att.type;
            });
        }
    
        this.initializeAttributes(keytypes);
    
        this.set(items);
    
        return this;
    };
  • ¶

    World prototype

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

    Mixins

    P = baseMix(P);
  • ¶

    World attributes

    • Attributes defined in the base mixin: name.
    let defaultAttributes = {
  • ¶

    x, y and z components of gravity, measured in meters/secondSquared (used in gravity force calculations)

        gravity: null,
  • ¶

    tickMultiplier - a positive float Number value. Larger values increase the physics effect - equivalent to speeding up the animation

        tickMultiplier: 1,
  • ¶

    keytypes - a Javascript object made up of key:String attributes. Used as part of the factory when generating worlds which use user-defined attributes that need to be Scrawl-canvas Quaternions, Vectors (like gravity) or Coordinates.

    • the key should be the attribute’s name
    • the value should be a String - either 'Quaternion', 'Vector' or 'Coordinate'.
        keytypes: null,
    };
    P.defs = mergeOver(P.defs, defaultAttributes);
  • ¶

    Packet management

    No additional packet management functionality required

  • ¶

    Clone management

    No additional clone functionality required

  • ¶

    Kill management

    P.kill = function () {
    
        this.deregister();
    
        return true;
    };
  • ¶

    Get, Set, deltaSet

    let G = P.getters,
        S = P.setters,
        D = P.deltaSetters;
  • ¶

    gravity, with pseudo-attributes gravityX, gravityY, gravityZ

    S.gravityX = function (item) { if (this.gravity && xt(item)) this.gravity.setX(item); };
    S.gravityY = function (item) { if (this.gravity && xt(item)) this.gravity.setY(item); };
    S.gravityZ = function (item) { if (this.gravity && xt(item)) this.gravity.setZ(item); };
    S.gravity = function (item) { if (this.gravity && xt(item)) this.gravity.set(item); };
  • ¶

    Prototype functions

  • ¶

    addAttribute, removeAttribute - we can use these functions to add and remove other attributes to the World object. See the following Demos for examples of constructing a World object and adding attributes to it:

    • particles-007 Particle Force objects: generation and functionality; and
    • particles-008 Net entity: generation and basic functionality, including Spring objects.
    P.addAttribute = function (items = {}) {
    
        let {key, defaultValue, setter, deltaSetter, getter} = items;
    
        if (key && key.substring) {
    
            this.defs[key] = xt(defaultValue) ? defaultValue : null;
            this[key] = xt(defaultValue) ? defaultValue : null;
    
            if (isa_fn(setter)) S[key] = setter;
            if (isa_fn(deltaSetter)) D[key] = deltaSetter;
            if (isa_fn(getter)) G[key] = getter;
        }
        return this;
    };
    P.removeAttribute = function (key) {
    
        if (key && key.substring) {
    
            delete this.defs[key];
            delete this[key];
            delete G[key];
            delete S[key];
            delete D[key];
        }
    
        return this;
    };
  • ¶

    initializeAttributes - internal function called by the constructor.

    P.initializeAttributes = function (types) {
    
        for (let [key, value] of Object.entries(types)) {
    
            switch (value) {
    
                case 'Quaternion' :
                    this[key] = makeQuaternion();
                    break;
    
                case 'Vector' :
                    this[key] = makeVector();
                    break;
    
                case 'Coordinate' :
                    this[key] = makeCoordinate();
                    break;
            }
        }};
  • ¶

    Factory

    scrawl.makeWorld({
    
        name: 'demo-world',
    
        tickMultiplier: 2,
    
        userAttributes: [
    
            {
                key: 'testCoordinate', 
                type: 'Coordinate',
                getter: function () { return [].concat(this.testCoordinate) },
                setter: function (item) { this.testCoordinate.set(item) },
            },
            {
                key: 'particleColor', 
                defaultValue: '#F0F8FF',
            },
        ],
        testCoordinate: [100, 100],
    });
    const makeWorld = function (items) {
        return new World(items);
    };
    
    constructors.World = World;
  • ¶

    Exports

    export {
        makeWorld,
    };