- 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

- §

  # SpriteAsset factory

  The factory generates wrapper Objects around spritesheet <img> elements fetched from the server using an URL address.

  - Scrawl-canvas expects every spritesheet to be accompanied by a manifest, defined in either a `.json` encoded file, or a Javascript object. There is no single source of truth for the requirements or format of manifests, so Scrawl-canvas uses its own manifest format.

  SpriteAssets are used by Picture and Grid entitys, and Pattern styles.

  TODO: SpriteAssets don’t support animated `.gif` images (or if they do, then its entirely a lucky accident). Tested image formats are `.jpg` and `.png`.

- §

  #### Demos:

  - Canvas-021 - Import and use spritesheets
  - Canvas-023 - Grid entity - using picture-based assets (image, video, sprite)
- §

  #### Imports

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

      import { doCreate, isa_obj, mergeOver, λnull, λthis, Ωempty } from '../core/utilities.js';

      import baseMix from '../mixin/base.js';
      import assetMix from '../mixin/asset.js';

      import { $JSON, _isArray, ANONYMOUS, ASSET, ASSET_IMPORT_REGEX, BLOCK, IMG, NONE, T_SPRITE, ZERO_STR } from '../core/shared-vars.js';

- §

  #### SpriteAsset constructor

      const SpriteAsset = function (items = Ωempty) {

          this.assetConstructor(items);

          return this;
      };

- §

  #### SpriteAsset prototype

      const P = SpriteAsset.prototype = doCreate();
      P.type = T_SPRITE;
      P.lib = ASSET;
      P.isArtefact = false;
      P.isAsset = true;

- §

  #### Mixins

  - base
  - asset

      baseMix(P);
      assetMix(P);

- §

  #### SpriteAsset attributes

  - Attributes defined in the base mixin: name.
  - Attributes defined in the asset mixin: source, subscribers.

      const defaultAttributes = {

- §

  manifest - TODO - documentation

          manifest: null,
      };
      P.defs = mergeOver(P.defs, defaultAttributes);

- §

  #### Packet management

  Assets do not take part in the packet or clone systems; they can, however, be used for importing and actioning packets as they retain those base functions

      P.saveAsPacket = function () {

          return [this.name, this.type, this.lib, {}];
      };
      P.stringifyFunction = λnull;
      P.processPacketOut = λnull;
      P.finalizePacketOut = λnull;

- §

  #### Clone management

      P.clone = λthis;

- §

  #### Kill management

  No additional kill functionality required

- §

  #### Get, Set, deltaSet

      const S = P.setters;

- §

  source

      S.source = function (items = []) {

          if (items && items[0]) {

              if (!this.sourceHold) this.sourceHold = {};

              const hold = this.sourceHold;

              items.forEach(item => {

                  const name = item.id || item.name;

                  if (name) hold[name] = item;
              })

              this.source = items[0];
              this.sourceNaturalWidth = items[0].naturalWidth;
              this.sourceNaturalHeight = items[0].naturalHeight;
              this.sourceLoaded = items[0].complete;
          }
      };

- §

  #### Prototype functions

- §

  Sprite assets do not use the `checkSource` function. Instead, Picture entitys will interrogate the checkSpriteFrame function (defined in mixin/assetConsumer.js)

      P.checkSource = λnull;

- §

  `gettableSpriteAssetAtributes`, `settableSpriteAssetAtributes` - exported Arrays.

      export const gettableSpriteAssetAtributes = [];
      export const settableSpriteAssetAtributes = [];

- §

  #### Importing spritesheets into Scrawl-canvas

- §

  `importSprite` - load sprite images and manifest files from a remote server and create assets from them

  Arguments can be a comma-separated list of String urls. For example, for a spritesheet at server url `http://www.example.com/path/to/image/flower.jpg`:

  - Will attempt to give the new spriteAsset object, and img element, a name/id value of eg ‘flower’ (but not guaranteed)
  - Will attempt to load the associated manifest JSON file, which it expects to find at ‘/path/to/image/flower.json’
  - Will not add the new img element to the DOM

  Note: if using an url string path to import the spritesheet image, a manifest JSON file with the same filename (ending in `.json`) in the same folder must also be supplied!

- §

  Alternatively, the arguments can include an object with the following attributes:

  - name string.
  - imageSrc (required) image url string, or an Array of such strings (for sprites using frames from multiple spritesheets).
  - manifestSrc (required) JSON manifest file url string, or an object detailing the manifest.
  - parent CSS search string - if set, Scrawl-canvas will attempt to append the new img element to the corresponding DOM element.
  - isVisible boolean - if true, and new img element has been added to DOM, make that image visible; default is false.
  - className string - list of classes to be added to the new img element.

  Note: strings and object arguments can be mixed - Scrawl-canvas will interrrogate each argument in turn and take appropriate action to load the assets.

  The manifest must resolve to an object containing a set of attributes which represent ‘tracks’ - sequences of frames which, when run, will result in a particular animation (eg ‘walk’, ‘turn’, ‘fire-arrow’, ‘die’, etc). Each track attribute is an Array of arrays, with each sub-array supplying details of the source file, copy start coordinates, and copy dimensions for each frame:

      manifestSrc: {

          "default" : [
              ['picturename', copyStartX, copyStartY, width, height]
          ],

          "walk": [
              ['picturename', copyStartX, copyStartY, width, height]
              ['picturename', copyStartX, copyStartY, width, height]
              ['picturename', copyStartX, copyStartY, width, height]
          ],
      }

  - Note that the frames for any track can be spread across more than one spritesheet image file. Note also that the default track is mandatory, and should consist of at least one frame.

      export const importSprite = function (...args) {

          const fileTlas = /\.(jpeg|jpg|png|gif|webp|svg|JPEG|JPG|PNG|GIF|WEBP|SVG)/,
              results = [];

          args.forEach(item => {

- §

  Load the sprite image in the normal way

              let name, urls, className, visibility, manifest,
                  parent = false;

              let flag = false;

              if (item.substring) {

                  const match = ASSET_IMPORT_REGEX.exec(item);

                  name = (match && match[1]) ? match[1] : ZERO_STR;
                  urls = [item];
                  className = ZERO_STR;
                  visibility = false;
                  manifest = item.replace(fileTlas, $JSON);

                  flag = true;
              }
              else {

                  if (!isa_obj(item) || !item.imageSrc || !item.manifestSrc) results.push(false);
                  else {

                      name = item.name || ZERO_STR;

                      urls = _isArray(item.imageSrc) ? item.imageSrc : [item.imageSrc];
                      manifest = item.manifestSrc;
                      className = item.className || ZERO_STR;
                      visibility = item.visibility || false;
                      parent = document.querySelector(item.parent);

                      flag = true;
                  }
              }

              if (flag) {

                  const image = makeSpriteAsset({
                      name: name,
                  });

- §

  Get manifest

                  if (isa_obj(manifest)) image.manifest = manifest;
                  else {

                      fetch(manifest)
                      .then(response => {

                          if (response.status != 200) throw new Error('Failed to load manifest');
                          return response.json();
                      })
                      .then(jsonString => image.manifest = jsonString)
                      .catch(err => console.log(err.message));
                  }

                  const imgArray = [];

                  urls.forEach(url => {

                      const img = document.createElement(IMG);

                      let filename, match;

                      if (fileTlas.test(url)) {

                          match = ASSET_IMPORT_REGEX.exec(url);
                          filename = (match && match[1]) ? match[1] : ZERO_STR;
                      }

                      img.name = filename || name;
                      img.className = className;
                      img.crossorigin = ANONYMOUS;

                      img.style.display = (visibility) ? BLOCK : NONE;

                      if (parent) parent.appendChild(img);

                      img.src = url;

                      imgArray.push(img);
                  });

                  image.set({
                      source: imgArray,
                  });

                  results.push(name);
              }
              else results.push(false);
          });
          return results;
      };

- §

  TODO: Scrawl-canvas does not yet support importing spritesheets defined in the web page HTML code

- §

  #### Factory

      export const makeSpriteAsset = function (items) {

          if (!items) return false;
          return new SpriteAsset(items);
      };

      constructors.SpriteAsset = SpriteAsset;

- §

  Examples used in Demos

  - Dino - https://www.gameart2d.com/free-dino-sprites.html
  - Wolf - https://opengameart.org/content/lpc-wolf-animation
  - Wall tiles - https://opengameart.org/content/2d-wall-tilesets
  - Bunny sprite - https://opengameart.org/content/bunny-sprite
  - Cat - https://www.kisspng.com/png-walk-cycle-css-animations-drawing-sprite-sprite-1064760/