- 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

- §

  # DOM management

  Core DOM element discovery and management functionality

  The order in which DOM stack and canvas elements are processed during the display cycle can be changed by setting that element’s controller’s order attribute to a higher or lower integer value; elements are processed (in batches) from lowest to highest order value

- §

  #### Imports

      import { artefact } from "./library.js";

      import { pushUnique, Ωempty } from "./utilities.js";

      import { getPixelRatio, getIgnorePixelRatio } from "./events.js";

      import { releaseArray, requestArray } from '../factory/array-pool.js';

      import { _css, _keys, _xcss, AUTO, BLOCK, GRAYSCALE, MOZOSX_FONT_SMOOTHING, NEVER, NONE, SMOOTH_FONT, T_CANVAS, WEBKIT_FONT_SMOOTHING, ZERO_STR } from './shared-vars.js';

- §

  #### DOM element updates

  Scrawl-canvas will batch process all DOM element updates, to minimize disruptive impacts on web page performance. We don’t maintain a full/comprehensive ‘shadow’ or ‘virtual’ DOM, but Scrawl-canvas does maintain a record of element (absolute) position and dimension data, alongside details of scaling, perspective and any other CSS related data (including CSS classes) which we tell it about, on a per-element basis.

  The decision on whether to update a DOM element is mediated through a suite of ‘dirty’ flags assigned on the Scrawl-canvas artefact object which wraps each DOM element. As part of the compile component of the Scrawl-canvas Display cycle, the code will take a decision on whether the DOM element needs to be updated and insert the artefact’s name in the domShowElements array, and set the domShowRequired flag to true, which will then trigger the domShow() function to run at the end of each Display cycle.

  The domShow() function is exported, and can be triggered for any DOM-related artefact at any time by invoking it with the artefact’s name as the function’s argument.

  The order in which DOM elements get updated is determined by the order attributes set on the Stack artefact, on Group objects, and (least important) on the element artefact.

- §

  Local variable

      const domShowElements = [];
      let domShowRequired = false;

- §

  `Exported function` (to modules).

      export const setDomShowRequired = (val = true) => domShowRequired = val;

- §

  `Exported function` (to modules).

      export const addDomShowElement = function (item = ZERO_STR) {

          if (item && item.substring) {

              pushUnique(domShowElements, item);
          }
      };

- §

  `Exported function` (to modules). This is the main DOM manipulation function which will be triggered once during each Display cycle.

      export const domShow = function (singleArtefact = ZERO_STR) {

          if (domShowRequired || singleArtefact) {

              const myartefacts = requestArray();

              if (singleArtefact && singleArtefact.substring) myartefacts.push(singleArtefact);
              else {

                  domShowRequired = false;
                  myartefacts.push(...domShowElements);
                  domShowElements.length = 0;
              }

              let i, iz, art, el, style,
                  p, dims, w, h,
                  j, jz, items, keys, key, keyName, value;

              const ignoreDpr = getIgnorePixelRatio();
              const dpr = getPixelRatio();

              for (i = 0, iz = myartefacts.length; i < iz; i++) {

                  art = artefact[myartefacts[i]];

                  if (art) {

                      el = art.domElement;

                      if (el) {

                          style = el.style;

                          if (style) {

- §

  update perspective

                              if (art.dirtyPerspective) {

                                  art.dirtyPerspective = false;

                                  p = art.perspective;

                                  style.perspectiveOrigin = `${p.x} ${p.y}`;
                                  style.perspective = `${p.z}px`;
                              }

- §

  update position

                              if (art.dirtyPosition) {

                                  art.dirtyPosition = false;
                                  style.position = art.position;
                              }

- §

  update dimensions

                              if (art.dirtyDomDimensions) {

                                  art.dirtyDomDimensions = false;

                                  dims = art.currentDimensions;
                                  w = dims[0];
                                  h = dims[1];

                                  if (art.type == T_CANVAS) {

                                      if (ignoreDpr) {

                                          el.width = w;
                                          el.height = h;
                                      }
                                      else {

                                          if (!art.ignoreCanvasCssDimensions) {

                                              style.width = `${w}px`;
                                              style.height = `${h}px`;
                                          }

                                          el.width = w * dpr;
                                          el.height = h * dpr;
                                      }
                                      if (art.renderOnResize) art.render();
                                  }
                                  else {

                                      style.width = `${w}px`;
                                      style.height = (h) ? `${h}px` : AUTO;
                                  }
                              }

- §

  update handle/transformOrigin

                              if (art.dirtyTransformOrigin) {

                                  art.dirtyTransformOrigin = false;
                                  style.transformOrigin = art.currentTransformOriginString;
                              }

- §

  update transform

                              if (art.dirtyTransform) {

                                  art.dirtyTransform = false;
                                  style.transform = art.currentTransformString;
                              }

- §

  update visibility

                              if (art.dirtyVisibility) {

                                  art.dirtyVisibility = false;
                                  style.display = (art.visibility) ? BLOCK : NONE;
                              }

- §

  update visibility

                              if (art.dirtySmoothFont) {

                                  art.dirtySmoothFont = false;

                                  if (art.smoothFont) {
                                      style[WEBKIT_FONT_SMOOTHING] = AUTO;
                                      style[MOZOSX_FONT_SMOOTHING] = AUTO;
                                      style[SMOOTH_FONT] = AUTO;
                                  }
                                  else {
                                      style[WEBKIT_FONT_SMOOTHING] = NONE;
                                      style[MOZOSX_FONT_SMOOTHING] = GRAYSCALE;
                                      style[SMOOTH_FONT] = NEVER;
                                  }
                              }

- §

  update other CSS changes

                              if (art.dirtyCss) {

                                  art.dirtyCss = false;

                                  items = art.css || Ωempty;
                                  keys = _keys(items);

                                  for (j = 0, jz = keys.length; j < jz; j++) {

                                      key = keys[j];
                                      value = items[key];

                                      if (_xcss.includes(key)) {

                                          keyName = `${key[0].toUpperCase}${key.substr(1)}`;

                                          style[`webkit${keyName}`] = value;
                                          style[`moz${keyName}`] = value;
                                          style[`ms${keyName}`] = value;
                                          style[`o${keyName}`] = value;
                                          style[key] = value;
                                      }
                                      else if (_css.includes(key)) style[key] = value;
                                  }
                              }

- §

  update element classes

                              if (art.dirtyClasses) {

                                  art.dirtyClasses = false;
                                  if (el.className.substring) el.className = art.classes;
                              }
                          }
                      }
                  }
              }
              releaseArray(myartefacts);
          }
      };

- §

  #### DOM Holding areas

  `Exported handles` (to modules). During its initialization phase, Scrawl-canvas will add two hidden ‘hold’ elements at the top and bottom of the document body where it can add additional elements as-and-when required.

- §

  Mainly for ARIA content. ARIA labels and descriptions are used by Scrawl-canvas <canvas> elements to inform non-visual website visitors about content in the canvas.

      export const scrawlCanvasHold = document.createElement('div');
      scrawlCanvasHold.style.padding = 0;
      scrawlCanvasHold.style.border = 0;
      scrawlCanvasHold.style.margin = 0;
      scrawlCanvasHold.style.width = '4500px';
      scrawlCanvasHold.style.boxSizing = 'border-box';
      scrawlCanvasHold.style.position = 'absolute';
      scrawlCanvasHold.style.top = '-5000px';
      scrawlCanvasHold.style.left = '-5000px';
      scrawlCanvasHold.id = 'Scrawl-ARIA-default-hold';
      document.body.appendChild(scrawlCanvasHold);

- §

  Navigation area - canvas anchor links. Canvases create their own (hidden) <nav> elements that get embedded in the Canvas Shadow DOM. These are used to store <a> links for clickable entitys in the canvas display, making them accessible to non-visual users (for example: screen readers). Should that <nav> element fail to be created, then those <a> links will be added to this element.

      export const scrawlNavigationHold = document.createElement('nav');
      scrawlNavigationHold.style.position = 'absolute';
      scrawlNavigationHold.style.top = '-5000px';
      scrawlNavigationHold.style.left = '-5000px';
      scrawlNavigationHold.id = 'Scrawl-navigation-default-hold';
      document.body.prepend(scrawlNavigationHold);