- Jump To … +
  ./source/core/animation-loop.js ./source/core/display-cycle.js ./source/core/document-root-elements.js ./source/core/document.js ./source/core/events.js ./source/core/init.js ./source/core/library.js ./source/core/random-seed.js ./source/core/shared-vars.js ./source/core/snippets.js ./source/core/system-flags.js ./source/core/user-interaction.js ./source/core/utilities.js ./source/factory/action.js ./source/factory/anchor.js ./source/factory/animation.js ./source/factory/array-pool.js ./source/factory/bezier.js ./source/factory/block.js ./source/factory/canvas.js ./source/factory/cell-fragment.js ./source/factory/cell.js ./source/factory/cog.js ./source/factory/color.js ./source/factory/conic-gradient.js ./source/factory/coordinate.js ./source/factory/crescent.js ./source/factory/drag-zone.js ./source/factory/element.js ./source/factory/emitter.js ./source/factory/filter-engine-bluenoise-data.js ./source/factory/filter-engine.js ./source/factory/filter.js ./source/factory/font-attributes.js ./source/factory/gradient.js ./source/factory/grid.js ./source/factory/group.js ./source/factory/image-asset.js ./source/factory/keyboard-zone.js ./source/factory/line-spiral.js ./source/factory/line.js ./source/factory/loom.js ./source/factory/mesh.js ./source/factory/net.js ./source/factory/noise-asset.js ./source/factory/observe-update.js ./source/factory/oval.js ./source/factory/palette.js ./source/factory/particle-force.js ./source/factory/particle-history.js ./source/factory/particle-spring.js ./source/factory/particle-world.js ./source/factory/particle.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/radial-gradient.js ./source/factory/raw-asset.js ./source/factory/reaction-diffusion-asset.js ./source/factory/rectangle.js ./source/factory/render-animation.js ./source/factory/shape.js ./source/factory/spiral.js ./source/factory/sprite-asset.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/unstacked-element.js ./source/factory/vector.js ./source/factory/video-asset.js ./source/factory/wheel.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/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/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/shape-path-calculation.js ./source/mixin/styles.js ./source/mixin/tween.js

- §

  # Coordinate factory

  Scrawl-canvas uses Coordinate Arrays extensively throughout the code base - in particular to hold artefact coordinate [x, y] and dimensional [w, h] data. The Coordinate factory does not care whether these values are presented as Numbers or Strings (or a mixture of both) - it leaves such functionality to other mixins (in particular the position, dom and entity mixins) and factories.

- §

  #### Imports

      import { constructors } from '../core/library.js';

      import { xt } from '../core/utilities.js';

      import { _atan2, _cos, _create, _hypot, _isArray, _seal, _setPrototypeOf, _sin, T_COORDINATE, T_QUATERNION, T_VECTOR } from '../core/shared-vars.js';

- §

  #### Coordinate constructor

      const Coordinate = function (items, y) {

          const coords = [0, 0];

          _setPrototypeOf(coords, Coordinate.prototype);
          _seal(coords);

          if (items) coords.set(items, y);

          return coords;
      };

- §

  #### Coordinate prototype

      const P = Coordinate.prototype = _create(Array.prototype);
      P.constructor = Coordinate;
      P.type = T_COORDINATE;

- §

  #### Mixins

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

- §

  #### Coordinate attributes

  There are no attributes. The constructor returns an Array containing two members, whose prototype object includes functions for manipulating those members in various ways.

- §

  #### Get, Set, deltaSet

  The Array members can be set using a `set` function, which is overloaded as follows:

  - `mycoordinate.set(Coordinate)` - use another Coordinate Array to set this Coordinate members’ values
  - `mycoordinate.set(Array)` - - use a Javascript Array to set this Coordinate members’ values
  - `mycoordinate.set(Quaternion)` - use a Quaternion object (specifically, its v Vector object attribute) to set this Coordinate members’ values
  - `mycoordinate.set(Vector)` - use a Vector object to set this Coordinate members’ values
  - `mycoordinate.set(a:Number|String, b:Number|String)` - supply two arguments to the function

      P.set = function (items, y) {

          if (xt(items)) {

              if (items.type == T_COORDINATE) this.setFromArray(items);
              else if (items.type == T_VECTOR) this.setFromVector(items);
              else if (items.type == T_QUATERNION) this.setFromVector(items.v);
              else if (_isArray(items)) this.setFromArray(items);
              else if (xt(y)) this.setFromArray([items, y]);
          }
          return this;
      };

      P.setFromArray = function (item) {

          this[0] = item[0];
          this[1] = item[1];

          return this;
      };

      P.setFromVector = function (item) {

          this[0] = item.x;
          this[1] = item.y;

          return this;
      };

- §

  #### Prototype functions

  Set the Coordinate array to `[0, 0]`

      P.zero = function () {

          this[0] = 0;
          this[1] = 0;

          return this;
      };

- §

  Add a Vector object’s x and y attributes to the Coordinate members’ values

      P.vectorAdd = function (item) {

          this[0] += item.x;
          this[1] += item.y;

          return this;
      };

- §

  Subtract a Vector object’s x and y attributes from the Coordinate members’ values

      P.vectorSubtract = function (item) {

          this[0] -= item.x;
          this[1] -= item.y;

          return this;
      };

- §

  Array addition - argument is a `[Number, Number]` Array

      P.add = function (item) {

          this[0] += item[0];
          this[1] += item[1];

          return this;
      };

- §

  Array subtraction - argument is a `[Number, Number]` Array

      P.subtract = function (item) {

          this[0] -= item[0];
          this[1] -= item[1];

          return this;
      };

- §

  Array multiplication - argument is a `[Number, Number]` Array

      P.multiply = function (item) {

          this[0] *= item[0];
          this[1] *= item[1];

          return this;
      };

- §

  Array division - argument is a `[Number, Number]` Array

      P.divide = function (item) {

          const [x, y] = item;

          if (x && y) {

              this[0] /= x;
              this[1] /= y;
          }

          return this;
      };

- §

  Multiply both Coordinate Array members by the argument Number

      P.scalarMultiply = function (item) {

          this[0] *= item;
          this[1] *= item;

          return this;
      };

- §

  Divide both Coordinate Array members by the argument Number

      P.scalarDivide = function (item) {

          if (item && item.toFixed) {

              this[0] /= item;
              this[1] /= item;
          }

          return this;
      };

- §

  Get the Array’s magnitude value (treating the Coordinate as if it was a 2D vector)

      P.getMagnitude = function () {

          return _hypot(...this);
      };

- §

  Rotate the Coordinate by the argument number (treating the Coordinate as if it was a 2D vector) - the argument represents degrees, not radians

      P.rotate = function (angle) {

          const [x, y] = this;

          let r0 = _atan2(y, x);
          r0 += (angle * 0.01745329251);

          const r1 = _hypot(x, y);

          this[0] = r1 * _cos(r0);
          this[1] = r1 * _sin(r0);

          return this;
      };

- §

  Reverse the numerical sign on each of the Array’s members

      P.reverse = function () {

          this[0] = -this[0];
          this[1] = -this[1];

          return this;
      };

- §

  Get the Array’s dot product value (treating the Coordinate as if it was a 2D vector)

      P.getDotProduct = function (coord) {

          return (this[0] * coord[0]) + (this[1] * coord[1]);
      };

- §

  Normalize the Array’s members (treating the Coordinate as if it was a 2D vector)

      P.normalize = function() {

          const val = this.getMagnitude();

          if (val > 0) {
              this[0] /= val;
              this[1] /= val;
          }
          return this;
      };

- §

  #### Coordinate pool

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

      const coordinatePool = [];

- §

  `exported function` - retrieve a Coordinate from the coordinate pool

      export const requestCoordinate = function (items, y) {

          if (!coordinatePool.length) coordinatePool.push(new Coordinate());

          const c = coordinatePool.shift();
          c.set(items, y);
          return c
      };

- §

  `exported function` - return a Coordinate to the coordinate pool. Failing to return Coordinates to the pool may lead to more inefficient code and possible memory leaks.

      export const releaseCoordinate = function (c) {

          if (c && c.type == T_COORDINATE) coordinatePool.push(c.zero());
      };

- §

  #### Factory

      export const makeCoordinate = function (items, y) {

          return new Coordinate(items, y);
      };

      constructors.Coordinate = Coordinate;