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

    Vector factory

    Scrawl-canvas uses vector objects for some of its calculations - in particular for calculating rotations. These objects are not stored in the library; rather, they are kept in a vector pool and pulled from it when required.

  • ¶

    Imports

    import { constructors } from '../core/library.js';
    import { xt, xta, isa_obj, isa_number } from '../core/utilities.js';
  • ¶

    Vector constructor

    const Vector = function (x, y, z) {
    
        this.x = 0;
        this.y = 0;
        this.z = 0;
    
        if (xt(x)) this.set(x, y, z);
    
        return this;
    };
  • ¶

    Vector prototype

    let P = Vector.prototype = Object.create(Object.prototype);
    P.type = 'Vector';
  • ¶

    Mixins

    Vector objects do not use mixins - they are regular Javascript objects. As such, they do not possess packet, clone or kill functionality.

  • ¶

    Vector attributes

    The x, y and z attributes are set in the Vector constructor - the Vector object does not have a defs object.

  • ¶

    Get, Set, deltaSet

  • ¶

    Vector attributes can be retrieved directly - myvector.x, etc. The following convenience getters are defined on the Vector prototype, and return an Array

    P.getXYCoordinate = function () {
    
        return [this.x, this.y];
    };
    
    P.getXYZCoordinate = function () {
    
        return [this.x, this.y, this.z];
    };
  • ¶

    Vector attributes can be set directly - myvector.x = 0, etc. The following convenience setters are defined on the Vector prototype

    P.setX = function (x) {
    
        if (!xt(x)) throw new Error(`${this.name} Vector error - setX() arguments error: ${x}`);
    
        this.x = x;
    
        return this;
    };
    
    P.setY = function (y) {
    
        if (!xt(y)) throw new Error(`${this.name} Vector error - setY() arguments error: ${y}`);
    
        this.y = y;
    
        return this;
    };
    
    P.setZ = function (z) {
    
        if (!xt(z)) throw new Error(`${this.name} Vector error - setZ() arguments error: ${z}`);
        
        this.z = z;
    
        return this;
    };
    
    P.setXY = function (x, y) {
    
        if (!xta(x, y)) throw new Error(`${this.name} Vector error - setXY() arguments error: ${x}, ${y}`);
        
        this.x = x;
        this.y = y;
    
        return this;
    };
  • ¶

    The Vector set function is overloaded. It can accept the following arguments:

    • set(x-Number, y-Number [, z-Number]) - Number arguments
    • set([x-Number, y-Number [, z-Number]]) - an Array of Numbers
    • set({x:Number, y:Number, z:Number}) - a Javascript object containing x, y (and z) attributes
    • set(Vector) - a Vector object
    P.set = function (x, y, z) {
    
        if (isa_obj(x)) return this.setFromVector(x);
    
        if (Array.isArray(x)) return this.setFromArray(x);
    
        if (xta(x, y)) return this.setFromArray([x, y, z]);
    
        return this;
    };
    
    P.setFromArray = function (args) {
    
        if (!Array.isArray(args)) throw new Error(`${this.name} Vector error - setFromArray() arguments error: ${args}`);
    
        let [x, y, z] = args;
        
        if (isa_number(x)) this.x = x;
        if (isa_number(y)) this.y = y;
        if (isa_number(z)) this.z = z;
    
        return this;
    };
    
    P.setFromVector = function (item) {
    
        if (!isa_obj(item)) throw new Error(`${this.name} Vector error - setFromVector() arguments error: ${JSON.stringify(item)}`);
        
        let {x, y, z} = item;
    
        if (isa_number(x)) this.x = x;
        if (isa_number(y)) this.y = y;
        if (isa_number(z)) this.z = z;
    
        return this;
    };
  • ¶

    Prototype functions

  • ¶

    Set the Vector attributes to their default values

    P.zero = function () {
    
        this.x = 0;
        this.y = 0;
        this.z = 0;
    
        return this;
    };
  • ¶

    Add a Vector, or an Array of Number values, to this Vector

    P.vectorAdd = function (item = {}) {
    
        if (Array.isArray(item)) return this.vectorAddArray(item);
    
        let {x, y, z} = item;
    
        if (isa_number(x)) this.x += x;
        if (isa_number(y)) this.y += y;
        if (isa_number(z)) this.z += z;
    
        return this;
    };
    
    P.vectorAddArray = function (item = []) {
    
        let [x, y, z] = item;
    
        if (isa_number(x)) this.x += x;
        if (isa_number(y)) this.y += y;
        if (isa_number(z)) this.z += z;
    
        return this;
    };
  • ¶

    Subtract a Vector, or an Array of Number values, from this Vector

    P.vectorSubtract = function (item = {}) {
    
        if (Array.isArray(item)) return this.vectorSubtractArray(item);
    
        let {x, y, z} = item;
    
        if (isa_number(x)) this.x -= x;
        if (isa_number(y)) this.y -= y;
        if (isa_number(z)) this.z -= z;
    
        return this;
    };
    
    P.vectorSubtractArray = function (item) {
    
        let [x, y, z] = item;
    
        if (isa_number(x)) this.x -= x;
        if (isa_number(y)) this.y -= y;
        if (isa_number(z)) this.z -= z;
    
        return this;
    };
  • ¶

    Multiply all Vector attributes by the argument Number

    P.scalarMultiply = function (item) {
    
        if (!isa_number(item)) throw new Error(`${this.name} Vector error - scalarMultiply() argument not a number: ${item}`);
    
        this.x *= item;
        this.y *= item;
        this.z *= item;
    
        return this;
    };
    
    P.vectorMultiply = function (item = {}) {
    
        if (Array.isArray(item)) return this.vectorMultiplyArray(item);
    
        let {x, y, z} = item;
    
        if (isa_number(x)) this.x *= x;
        if (isa_number(y)) this.y *= y;
        if (isa_number(z)) this.z *= z;
    
        return this;
    };
    
    P.vectorMultiplyArray = function (item) {
    
        let [x, y, z] = item;
    
        if (isa_number(x)) this.x *= x;
        if (isa_number(y)) this.y *= y;
        if (isa_number(z)) this.z *= z;
    
        return this;
    };
  • ¶

    Divide all Vector attributes by the argument Number

    P.scalarDivide = function (item) {
    
        if (!isa_number(item)) throw new Error(`${this.name} Vector error - scalarDivide() argument not a number: ${item}`);
        if (!item) throw new Error(`${this.name} Vector error - scalarDivide() division by zero: ${item}`);
    
        this.x /= item;
        this.y /= item;
        this.z /= item;
    
        return this;
    };
  • ¶

    Get the Vector’s magnitude value

    P.getMagnitude = function () {
    
        return Math.sqrt((this.x * this.x) + (this.y * this.y) + (this.z * this.z));
    };
  • ¶

    Rotate a Vector by a given angle. Argument is a Number representing degrees, not radians.

    P.rotate = function (angle) {
    
        if (!isa_number(angle)) throw new Error(`${this.name} Vector error - rotate() argument not a number: ${angle}`);
    
        let arg = Math.atan2(this.y, this.x);
        arg += (angle * 0.01745329251);
        
        let mag = this.getMagnitude();
    
        this.x = mag * Math.cos(arg);
        this.y = mag * Math.sin(arg);
    
        return this;
    };
  • ¶

    Change the numerical sign of all Vector attributes

    P.reverse = function () {
    
        this.x = -this.x;
        this.y = -this.y;
        this.z = -this.z;
    
        return this;
    };
  • ¶

    Normalize the Vector

    P.normalize = function() {
        
        let val = this.getMagnitude();
        
        if (val > 0) {
            this.x /= val;
            this.y /= val;
            this.z /= val;
        }
        return this;
    };
  • ¶

    Vector pool

    An attempt to reuse vectors rather than constantly creating and deleting them

    const vectorPool = [];
  • ¶

    exported function - retrieve a Vector from the vector pool

    const requestVector = function (x, y, z) {
    
        if (!vectorPool.length) vectorPool.push(new Vector());
    
        let v = vectorPool.shift();
    
        v.set(x, y, z);
    
        return v
    };
  • ¶

    exported function - return a Vector to the vector pool. Failing to return Vectors to the pool may lead to more inefficient code and possible memory leaks.

    const releaseVector = function (item) {
    
        if (item && item.type === 'Vector') vectorPool.push(item.zero());
    };
  • ¶

    Factory

    const makeVector = function (x, y, z) {
        
        return new Vector(x, y, z);
    };
    
    constructors.Vector = Vector;
  • ¶

    Exports

    export {
        makeVector,
        requestVector,
        releaseVector,
    };