UNPKG

scrawl-canvas

Version:
1,130 lines (743 loc) 160 kB
<!DOCTYPE html> <html> <head> <title>Loom factory</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"> <link rel="stylesheet" media="all" href="../../docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <ul id="jump_to"> <li> <a class="large" href="javascript:void(0);">Jump To &hellip;</a> <a class="small" href="javascript:void(0);">+</a> <div id="jump_wrapper"> <div id="jump_page_wrapper"> <div id="jump_page"> <a class="source" href="../core/animationloop.html"> ./source/core/animationloop.js </a> <a class="source" href="../core/document.html"> ./source/core/document.js </a> <a class="source" href="../core/events.html"> ./source/core/events.js </a> <a class="source" href="../core/init.html"> ./source/core/init.js </a> <a class="source" href="../core/library.html"> ./source/core/library.js </a> <a class="source" href="../core/random-seed.html"> ./source/core/random-seed.js </a> <a class="source" href="../core/snippets.html"> ./source/core/snippets.js </a> <a class="source" href="../core/userInteraction.html"> ./source/core/userInteraction.js </a> <a class="source" href="../core/utilities.html"> ./source/core/utilities.js </a> <a class="source" href="action.html"> ./source/factory/action.js </a> <a class="source" href="anchor.html"> ./source/factory/anchor.js </a> <a class="source" href="animation.html"> ./source/factory/animation.js </a> <a class="source" href="bezier.html"> ./source/factory/bezier.js </a> <a class="source" href="block.html"> ./source/factory/block.js </a> <a class="source" href="canvas.html"> ./source/factory/canvas.js </a> <a class="source" href="cell.html"> ./source/factory/cell.js </a> <a class="source" href="cog.html"> ./source/factory/cog.js </a> <a class="source" href="color.html"> ./source/factory/color.js </a> <a class="source" href="conicGradient.html"> ./source/factory/conicGradient.js </a> <a class="source" href="coordinate.html"> ./source/factory/coordinate.js </a> <a class="source" href="crescent.html"> ./source/factory/crescent.js </a> <a class="source" href="element.html"> ./source/factory/element.js </a> <a class="source" href="emitter.html"> ./source/factory/emitter.js </a> <a class="source" href="filter.html"> ./source/factory/filter.js </a> <a class="source" href="filterEngine-bluenoiseData.html"> ./source/factory/filterEngine-bluenoiseData.js </a> <a class="source" href="filterEngine.html"> ./source/factory/filterEngine.js </a> <a class="source" href="fontAttributes.html"> ./source/factory/fontAttributes.js </a> <a class="source" href="gradient.html"> ./source/factory/gradient.js </a> <a class="source" href="grid.html"> ./source/factory/grid.js </a> <a class="source" href="group.html"> ./source/factory/group.js </a> <a class="source" href="imageAsset.html"> ./source/factory/imageAsset.js </a> <a class="source" href="line.html"> ./source/factory/line.js </a> <a class="source" href="lineSpiral.html"> ./source/factory/lineSpiral.js </a> <a class="source" href="loom.html"> ./source/factory/loom.js </a> <a class="source" href="mesh.html"> ./source/factory/mesh.js </a> <a class="source" href="net.html"> ./source/factory/net.js </a> <a class="source" href="noiseAsset.html"> ./source/factory/noiseAsset.js </a> <a class="source" href="oval.html"> ./source/factory/oval.js </a> <a class="source" href="palette.html"> ./source/factory/palette.js </a> <a class="source" href="particle.html"> ./source/factory/particle.js </a> <a class="source" href="particleForce.html"> ./source/factory/particleForce.js </a> <a class="source" href="particleHistory.html"> ./source/factory/particleHistory.js </a> <a class="source" href="particleSpring.html"> ./source/factory/particleSpring.js </a> <a class="source" href="particleWorld.html"> ./source/factory/particleWorld.js </a> <a class="source" href="pattern.html"> ./source/factory/pattern.js </a> <a class="source" href="phrase.html"> ./source/factory/phrase.js </a> <a class="source" href="picture.html"> ./source/factory/picture.js </a> <a class="source" href="polygon.html"> ./source/factory/polygon.js </a> <a class="source" href="polyline.html"> ./source/factory/polyline.js </a> <a class="source" href="quadratic.html"> ./source/factory/quadratic.js </a> <a class="source" href="quaternion.html"> ./source/factory/quaternion.js </a> <a class="source" href="radialGradient.html"> ./source/factory/radialGradient.js </a> <a class="source" href="rawAsset.html"> ./source/factory/rawAsset.js </a> <a class="source" href="rdAsset.html"> ./source/factory/rdAsset.js </a> <a class="source" href="rectangle.html"> ./source/factory/rectangle.js </a> <a class="source" href="renderAnimation.html"> ./source/factory/renderAnimation.js </a> <a class="source" href="shape.html"> ./source/factory/shape.js </a> <a class="source" href="spiral.html"> ./source/factory/spiral.js </a> <a class="source" href="spriteAsset.html"> ./source/factory/spriteAsset.js </a> <a class="source" href="stack.html"> ./source/factory/stack.js </a> <a class="source" href="star.html"> ./source/factory/star.js </a> <a class="source" href="state.html"> ./source/factory/state.js </a> <a class="source" href="tetragon.html"> ./source/factory/tetragon.js </a> <a class="source" href="ticker.html"> ./source/factory/ticker.js </a> <a class="source" href="tracer.html"> ./source/factory/tracer.js </a> <a class="source" href="tween.html"> ./source/factory/tween.js </a> <a class="source" href="unstackedElement.html"> ./source/factory/unstackedElement.js </a> <a class="source" href="vector.html"> ./source/factory/vector.js </a> <a class="source" href="videoAsset.html"> ./source/factory/videoAsset.js </a> <a class="source" href="wheel.html"> ./source/factory/wheel.js </a> <a class="source" href="../mixin/anchor.html"> ./source/mixin/anchor.js </a> <a class="source" href="../mixin/asset.html"> ./source/mixin/asset.js </a> <a class="source" href="../mixin/assetAdvancedFunctionality.html"> ./source/mixin/assetAdvancedFunctionality.js </a> <a class="source" href="../mixin/assetConsumer.html"> ./source/mixin/assetConsumer.js </a> <a class="source" href="../mixin/base.html"> ./source/mixin/base.js </a> <a class="source" href="../mixin/cascade.html"> ./source/mixin/cascade.js </a> <a class="source" href="../mixin/delta.html"> ./source/mixin/delta.js </a> <a class="source" href="../mixin/displayShape.html"> ./source/mixin/displayShape.js </a> <a class="source" href="../mixin/dom.html"> ./source/mixin/dom.js </a> <a class="source" href="../mixin/entity.html"> ./source/mixin/entity.js </a> <a class="source" href="../mixin/filter.html"> ./source/mixin/filter.js </a> <a class="source" href="../mixin/mimic.html"> ./source/mixin/mimic.js </a> <a class="source" href="../mixin/path.html"> ./source/mixin/path.js </a> <a class="source" href="../mixin/pattern.html"> ./source/mixin/pattern.js </a> <a class="source" href="../mixin/pivot.html"> ./source/mixin/pivot.js </a> <a class="source" href="../mixin/position.html"> ./source/mixin/position.js </a> <a class="source" href="../mixin/shapeBasic.html"> ./source/mixin/shapeBasic.js </a> <a class="source" href="../mixin/shapeCurve.html"> ./source/mixin/shapeCurve.js </a> <a class="source" href="../mixin/shapePathCalculation.html"> ./source/mixin/shapePathCalculation.js </a> <a class="source" href="../mixin/styles.html"> ./source/mixin/styles.js </a> <a class="source" href="../mixin/tween.html"> ./source/mixin/tween.js </a> </div> </div> </li> </ul> <ul class="sections"> <li id="section-1"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-1">&#x00a7;</a> </div> <h1 id="loom-factory">Loom factory</h1> <p>A Loom offers functionality to render an image onto a &lt;canvas&gt; element, where the image is not a rectangle - it can have curved borders. It can also offer the illusion of flat 3D images in the canvas, giving them perspective.</p> <p>Loom entitys are <em><strong>composite entitys</strong></em> - an entity that relies on other entitys for its basic functionality.</p> <ul> <li>Every Loom object requires two (or one) path-enabled <a href="./shape.html">Shape</a> entitys to act as its left and right tracks.</li> <li>A Loom entity also requires a <a href="./picture.html">Picture</a> entity to act as its image source.</li> <li>Looms can use CSS color Strings for their strokeStyle values, alongside <strong>Gradient</strong>, <strong>RadialGradient</strong>, <strong>Color</strong> and <strong>Pattern</strong> objects. </li> <li>They can use <strong>Anchor</strong> objects for user navigation. </li> <li>They can be rendered to the canvas by including them in a <strong>Cell</strong> object’s <strong>Group</strong>. </li> <li>They can be <strong>animated</strong> directly, or using delta animation, or act as the target for <strong>Tween</strong> animations.</li> <li>Looms can be cloned, and killed.</li> </ul> <p><em><strong>Note that this is experimental technology!</strong></em></p> <ul> <li>Current code does not use <a href="./mixin/position.html">position</a> or <a href="./mixin/entity.html">entity</a> mixins, meaning much of the code here has been copied over from those mixins (DRY issue).</li> <li>TODO: clone functionality not yet tested. A possible use case is to clome a Loom so they share the same Shape struts, but have different Picture sources and <code>from/toPathStart/End</code> cursor values - multiple images tracked and animated.</li> </ul> </div> </li> <li id="section-2"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-2">&#x00a7;</a> </div> <h4 id="demos">Demos:</h4> <ul> <li><a href="../../demo/canvas-024.html">Canvas-024</a> - Loom entity functionality</li> <li><a href="../../demo/dom-015.html">DOM-015</a> - Use stacked DOM artefact corners as pivot points</li> </ul> </div> </li> <li id="section-3"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-3">&#x00a7;</a> </div> <h4 id="imports">Imports</h4> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">import</span> { constructors, artefact, group } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../core/library.js&#x27;</span>; <span class="hljs-keyword">import</span> { currentGroup } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../core/document.js&#x27;</span>; <span class="hljs-keyword">import</span> { mergeOver, mergeDiscard, pushUnique, λ<span class="hljs-literal">null</span>, λ<span class="hljs-variable language_">this</span>, xta, Ωempty } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../core/utilities.js&#x27;</span>; <span class="hljs-keyword">import</span> { makeState, stateKeys } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../factory/state.js&#x27;</span>; <span class="hljs-keyword">import</span> { requestCell, releaseCell } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../factory/cell.js&#x27;</span>; <span class="hljs-keyword">import</span> baseMix <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../mixin/base.js&#x27;</span>; <span class="hljs-keyword">import</span> deltaMix <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../mixin/delta.js&#x27;</span>; <span class="hljs-keyword">import</span> anchorMix <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../mixin/anchor.js&#x27;</span>;</pre></div></div> </li> <li id="section-4"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-4">&#x00a7;</a> </div> <h4 id="loom-constructor">Loom constructor</h4> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">const</span> <span class="hljs-title class_">Loom</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">items = Ωempty</span>) { <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">makeName</span>(items.<span class="hljs-property">name</span>); <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">register</span>(); <span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span> = <span class="hljs-title function_">makeState</span>(Ωempty); <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">set</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">defs</span>); <span class="hljs-keyword">if</span> (!items.<span class="hljs-property">group</span>) items.<span class="hljs-property">group</span> = currentGroup; <span class="hljs-variable language_">this</span>.<span class="hljs-property">onEnter</span> = λ<span class="hljs-literal">null</span>; <span class="hljs-variable language_">this</span>.<span class="hljs-property">onLeave</span> = λ<span class="hljs-literal">null</span>; <span class="hljs-variable language_">this</span>.<span class="hljs-property">onDown</span> = λ<span class="hljs-literal">null</span>; <span class="hljs-variable language_">this</span>.<span class="hljs-property">onUp</span> = λ<span class="hljs-literal">null</span>; <span class="hljs-variable language_">this</span>.<span class="hljs-property">delta</span> = {}; <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">set</span>(items); <span class="hljs-variable language_">this</span>.<span class="hljs-property">fromPathData</span> = []; <span class="hljs-variable language_">this</span>.<span class="hljs-property">toPathData</span> = []; <span class="hljs-variable language_">this</span>.<span class="hljs-property">watchFromPath</span> = <span class="hljs-literal">null</span>; <span class="hljs-variable language_">this</span>.<span class="hljs-property">watchIndex</span> = -<span class="hljs-number">1</span>; <span class="hljs-variable language_">this</span>.<span class="hljs-property">engineInstructions</span> = []; <span class="hljs-variable language_">this</span>.<span class="hljs-property">engineDeltaLengths</span> = []; <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>; };</pre></div></div> </li> <li id="section-5"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-5">&#x00a7;</a> </div> <h4 id="loom-prototype">Loom prototype</h4> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">let</span> P = <span class="hljs-title class_">Loom</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span> = <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">create</span>(<span class="hljs-title class_">Object</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>); P.<span class="hljs-property">type</span> = <span class="hljs-string">&#x27;Loom&#x27;</span>; P.<span class="hljs-property">lib</span> = <span class="hljs-string">&#x27;entity&#x27;</span>; P.<span class="hljs-property">isArtefact</span> = <span class="hljs-literal">true</span>; P.<span class="hljs-property">isAsset</span> = <span class="hljs-literal">false</span>;</pre></div></div> </li> <li id="section-6"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-6">&#x00a7;</a> </div> <h4 id="mixins">Mixins</h4> </div> <div class="content"><div class='highlight'><pre>P = <span class="hljs-title function_">baseMix</span>(P); P = <span class="hljs-title function_">deltaMix</span>(P); P = <span class="hljs-title function_">anchorMix</span>(P);</pre></div></div> </li> <li id="section-7"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-7">&#x00a7;</a> </div> <h4 id="loom-attributes">Loom attributes</h4> <ul> <li>Attributes defined in the <a href="../mixin/base.html">base mixin</a>: <strong>name</strong>.</li> <li>Attributes defined in the <a href="../mixin/anchor.html">anchor mixin</a>: <strong>anchor</strong>.</li> </ul> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">let</span> defaultAttributes = {</pre></div></div> </li> <li id="section-8"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-8">&#x00a7;</a> </div> <p><strong>fromPath</strong>, <strong>toPath</strong> - A Loom entity uses 2 Shape paths to construct a frame between which the image will be redrawn. These attributes can be set using the Shapes’ name-String, or the Shape objects themselves</p> <ul> <li>The positioning, scaling etc of each strut is set in the constituent Shape entitys, not the Loom entity.</li> <li>We can use a single path for both attributes, though nothing will show if the <code>start/end</code> attributs do not have differing values.</li> </ul> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">fromPath</span>: <span class="hljs-literal">null</span>, <span class="hljs-attr">toPath</span>: <span class="hljs-literal">null</span>,</pre></div></div> </li> <li id="section-9"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-9">&#x00a7;</a> </div> <p><strong>fromPathStart</strong>, <strong>fromPathEnd</strong> and <strong>toPathStart</strong>, <strong>toPathEnd</strong> - float Numbers generally between <code>0.0 - 1.0</code> - The Loom entity can set the start and end cursors on each of its path struts, between which the image will be drawn. </p> <ul> <li>These can be animated to allow the image to <em>flow</em> between one part of the display and another, changing its shape as it moves.</li> </ul> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">fromPathStart</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">fromPathEnd</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">toPathStart</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">toPathEnd</span>: <span class="hljs-number">1</span>,</pre></div></div> </li> <li id="section-10"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-10">&#x00a7;</a> </div> <p><strong>synchronizePathCursors</strong> - Boolean flag - To make sure the <code>from...</code> and <code>to...</code> strut start points, and end points, have the same value set the attribute to <code>true</code> (default). </p> <ul> <li>Setting it to <code>false</code> allows the cursors to be set independently on each strut … which in turn may lead to unexpected display consequences.</li> </ul> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">synchronizePathCursors</span>: <span class="hljs-literal">true</span>,</pre></div></div> </li> <li id="section-11"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-11">&#x00a7;</a> </div> <p> <strong>loopPathCursors</strong> - Boolean flag - For animation purposes, the image will move between the struts with the bottom of the page appearing again at the top of the Loom as it moves down (and vice versa). </p> <ul> <li>To change this functionality - so that the image slowly disappears as it animates up and down past the ends of the struts, set the attribute to <code>false</code>.</li> </ul> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">loopPathCursors</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">constantPathSpeed</span>: <span class="hljs-literal">true</span>,</pre></div></div> </li> <li id="section-12"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-12">&#x00a7;</a> </div> <p><strong>isHorizontalCopy</strong> - Boolean flag - Copying the source image to the output happens, by default, by rows - which effectively means the struts are on the left-hand and right-hand edges of the image. </p> <ul> <li>To change this to columns (which sets the struts to the top and bottom edges of the image) set the attribute to <code>false</code></li> </ul> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">isHorizontalCopy</span>: <span class="hljs-literal">true</span>,</pre></div></div> </li> <li id="section-13"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-13">&#x00a7;</a> </div> <p><strong>showBoundingBox</strong> (Boolean), <strong>boundingBoxColor</strong> (CSS color String) - Mainly for library development/testing work - shows the loom entity’s bounding box - which is calculated from the constituent Shape entitys’ current bounding boxes.</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">showBoundingBox</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">boundingBoxColor</span>: <span class="hljs-string">&#x27;#000000&#x27;</span>,</pre></div></div> </li> <li id="section-14"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-14">&#x00a7;</a> </div> <p><strong>source</strong> - The Picture entity source for this loom. For initialization and/or <code>set</code>, we can supply either the Picture entity itself, or its name-String value.</p> <ul> <li>The content image displayed by the Loom entity are set in the Picture entity, not the Loom, and can be any artefact supported by the Picture (image, video, sprite, or a Cell artefact).</li> <li>Note that any <em><strong>filters should be applied to the Picture entity</strong></em>; Loom entitys do not support filter functionality but will apply a Picture’s filters to the source image as-and-where appropriate.</li> </ul> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">source</span>: <span class="hljs-literal">null</span>,</pre></div></div> </li> <li id="section-15"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-15">&#x00a7;</a> </div> <p><strong>sourceIsVideoOrSprite</strong> - Boolean flag - If the Picture entity is hosting a video or sprite asset, we need to update the input on every frame. </p> <ul> <li>It’s easier to tell the Loom entity to do this using a flag, rather than get the Picture entity to update all its Loom subscribers on every display cycle. </li> <li>For Pictures using image assets the flag must be set to <code>false</code> (the default); setting the flag to <code>true</code> will significantly degrade display and animation performance.</li> </ul> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">sourceIsVideoOrSprite</span>: <span class="hljs-literal">false</span>,</pre></div></div> </li> <li id="section-16"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-16">&#x00a7;</a> </div> <p>The current Frame drawing process often leads to <a href="https://en.wikipedia.org/wiki/Moir%C3%A9_pattern">moiré interference patterns</a> appearing in the resulting image. Scrawl-canvas uses a resize trick to blur out these patterns. </p> <p><strong>interferenceLoops</strong> (positive integer Number), <strong>interferenceFactor</strong> (positive float Number) - The interferenceFactor attribute sets the resizing ratio; while he interferenceLoops attribute sets the number of times the image gets resized. </p> <ul> <li>If inteference patterns still appear in the final image, tweak these values to see if a better output can be achieved.</li> </ul> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">interferenceLoops</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">interferenceFactor</span>: <span class="hljs-number">1.03</span>,</pre></div></div> </li> <li id="section-17"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-17">&#x00a7;</a> </div> <p>The Loom entity does not use the <a href="./mixin/position.html">position</a> or <a href="./mixin/entity.html">entity</a> mixins (used by most other entitys) as its positioning is entirely dependent on the position, rotation, scale etc of its constituent Shape path entity struts. </p> <p>It does, however, use these attributes (alongside their setters and getters): <strong>visibility</strong>, <strong>order</strong>, <strong>delta</strong>, <strong>host</strong>, <strong>group</strong>, <strong>anchor</strong>, <strong>collides</strong>.</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">visibility</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">calculateOrder</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">stampOrder</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">host</span>: <span class="hljs-literal">null</span>, <span class="hljs-attr">group</span>: <span class="hljs-literal">null</span>, <span class="hljs-attr">anchor</span>: <span class="hljs-literal">null</span>,</pre></div></div> </li> <li id="section-18"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-18">&#x00a7;</a> </div> <p><strong>noCanvasEngineUpdates</strong> - Boolean flag - Canvas engine updates are required for the Loom’s border - strokeStyle and line styling; if a Loom is to be drawn without a border, then setting this flag to <code>true</code> may help improve rendering efficiency.</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">noCanvasEngineUpdates</span>: <span class="hljs-literal">false</span>,</pre></div></div> </li> <li id="section-19"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-19">&#x00a7;</a> </div> <p><strong>noDeltaUpdates</strong> - Boolean flag - Loom entitys support delta animation - achieved by updating the <code>...path</code> attributes by appropriate (and small!) values. If the Loom is not going to be animated by delta values, setting the flag to <code>true</code> may help improve rendering efficiency.</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">noDeltaUpdates</span>: <span class="hljs-literal">false</span>,</pre></div></div> </li> <li id="section-20"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-20">&#x00a7;</a> </div> <p><strong>onEnter</strong>, <strong>onLeave</strong>, <strong>onDown</strong>, <strong>onUp</strong> - Loom entitys support <em><strong>collision detection</strong></em>, reporting a hit when a test coordinate falls within the Loom’s output image. As a result, Looms can also accept and act on the four <strong>on</strong> functions - see <a href="../mixin/entity.html#section-11">entity event listener functions</a> for more details.</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">onEnter</span>: <span class="hljs-literal">null</span>, <span class="hljs-attr">onLeave</span>: <span class="hljs-literal">null</span>, <span class="hljs-attr">onDown</span>: <span class="hljs-literal">null</span>, <span class="hljs-attr">onUp</span>: <span class="hljs-literal">null</span>,</pre></div></div> </li> <li id="section-21"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-21">&#x00a7;</a> </div> <p><strong>noUserInteraction</strong> - Boolean flag - To switch off collision detection for a Loom entity - which might help improve rendering efficiency - set the flag to <code>true</code>.</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">noUserInteraction</span>: <span class="hljs-literal">false</span>,</pre></div></div> </li> <li id="section-22"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-22">&#x00a7;</a> </div> <p><a href="./anchor.html">Anchor objects</a> can be assigned to Loom entitys, meaning the following attributes are supported:</p> <ul> <li>anchorDescription</li> <li>anchorType</li> <li>anchorTarget</li> <li>anchorRel</li> <li>anchorReferrerPolicy</li> <li>anchorPing</li> <li>anchorHreflang</li> <li>anchorHref</li> <li>anchorDownload</li> </ul> <p>And the anchor attributes can also be supplied as a key:value object assigned to the <strong>anchor</strong> attribute:</p> <pre><code> <span class="hljs-attr">anchor</span>: { description download href hreflang ping referrerpolicy <span class="hljs-attr">rel</span>: <span class="hljs-attr">target</span>: anchorType <span class="hljs-attr">clickAction</span>: } </code></pre> <p>Note that Loom entitys DO NOT SUPPORT the sensor component of the Scrawl-canvas collisions system and will return an empty array when asked to supply sensor coordinates for testing against other artefacts.</p> </div> </li> <li id="section-23"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-23">&#x00a7;</a> </div> <p><strong>method</strong> - All normal Scrawl-canvas entity stamping methods are supported.</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">method</span>: <span class="hljs-string">&#x27;fill&#x27;</span>,</pre></div></div> </li> <li id="section-24"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-24">&#x00a7;</a> </div> <p>Loom entitys support appropriate styling attributes, mainly for their stroke styles (used with the <code>draw</code>, <code>drawAndFill</code>, <code>fillAndDraw</code>, <code>drawThenFill</code> and <code>fillThenDraw</code> stamping methods). </p> <ul> <li>These <em><strong>state</strong></em> attributes are stored directly on the object, rather than in a separate <a href="./state.html">State</a> object.</li> </ul> <p>The following attributes are thus supported:</p> <p>Alpha and Composite operations will be applied to both the Loom entity’s border (the Shape entitys, with connecting lines between their paths’ start and end points) and fill (the image displayed between the Loom’s struts)</p> <ul> <li><strong>globalAlpha</strong></li> <li><strong>globalCompositeOperation</strong></li> </ul> <p>All line attributes are supported</p> <ul> <li><strong>lineWidth</strong></li> <li><strong>lineCap</strong></li> <li><strong>lineJoin</strong></li> <li><strong>lineDash</strong></li> <li><strong>lineDashOffset</strong></li> <li><strong>miterLimit</strong></li> </ul> <p>The Loom entity’s strokeStyle can be any style supported by Scrawl-canvas - color strings, gradient objects, and pattern objects</p> <ul> <li><strong>strokeStyle</strong></li> </ul> <p>The shadow attributes will only be applied to the stroke (border), not to the Loom’s fill (image)</p> <ul> <li><strong>shadowOffsetX</strong></li> <li><strong>shadowOffsetY</strong></li> <li><strong>shadowBlur</strong></li> <li><strong>shadowColor</strong></li> </ul> </div> <div class="content"><div class='highlight'><pre>}; P.<span class="hljs-property">defs</span> = <span class="hljs-title function_">mergeOver</span>(P.<span class="hljs-property">defs</span>, defaultAttributes);</pre></div></div> </li> <li id="section-25"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-25">&#x00a7;</a> </div> <h4 id="packet-management">Packet management</h4> </div> <div class="content"><div class='highlight'><pre>P.<span class="hljs-property">packetExclusions</span> = <span class="hljs-title function_">pushUnique</span>(P.<span class="hljs-property">packetExclusions</span>, [<span class="hljs-string">&#x27;pathObject&#x27;</span>, <span class="hljs-string">&#x27;state&#x27;</span>]); P.<span class="hljs-property">packetExclusionsByRegex</span> = <span class="hljs-title function_">pushUnique</span>(P.<span class="hljs-property">packetExclusionsByRegex</span>, [<span class="hljs-string">&#x27;^(local|dirty|current)&#x27;</span>, <span class="hljs-string">&#x27;Subscriber$&#x27;</span>]); P.<span class="hljs-property">packetCoordinates</span> = <span class="hljs-title function_">pushUnique</span>(P.<span class="hljs-property">packetCoordinates</span>, []); P.<span class="hljs-property">packetObjects</span> = <span class="hljs-title function_">pushUnique</span>(P.<span class="hljs-property">packetObjects</span>, [<span class="hljs-string">&#x27;group&#x27;</span>, <span class="hljs-string">&#x27;fromPath&#x27;</span>, <span class="hljs-string">&#x27;toPath&#x27;</span>, <span class="hljs-string">&#x27;source&#x27;</span>]); P.<span class="hljs-property">packetFunctions</span> = <span class="hljs-title function_">pushUnique</span>(P.<span class="hljs-property">packetFunctions</span>, [<span class="hljs-string">&#x27;onEnter&#x27;</span>, <span class="hljs-string">&#x27;onLeave&#x27;</span>, <span class="hljs-string">&#x27;onDown&#x27;</span>, <span class="hljs-string">&#x27;onUp&#x27;</span>]); P.<span class="hljs-property">processPacketOut</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">key, value, includes</span>) { <span class="hljs-keyword">let</span> result = <span class="hljs-literal">true</span>; <span class="hljs-keyword">if</span>(includes.<span class="hljs-title function_">indexOf</span>(key) &lt; <span class="hljs-number">0</span> &amp;&amp; value === <span class="hljs-variable language_">this</span>.<span class="hljs-property">defs</span>[key]) result = <span class="hljs-literal">false</span>; <span class="hljs-keyword">return</span> result; }; P.<span class="hljs-property">finalizePacketOut</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">copy, items</span>) { <span class="hljs-keyword">let</span> stateCopy = <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">parse</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-title function_">saveAsPacket</span>(items))[<span class="hljs-number">3</span>]; copy = <span class="hljs-title function_">mergeOver</span>(copy, stateCopy); copy = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">handlePacketAnchor</span>(copy, items); <span class="hljs-keyword">return</span> copy; }; P.<span class="hljs-property">handlePacketAnchor</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">copy, items</span>) { <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">anchor</span>) { <span class="hljs-keyword">let</span> a = <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">parse</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">anchor</span>.<span class="hljs-title function_">saveAsPacket</span>(items))[<span class="hljs-number">3</span>]; copy.<span class="hljs-property">anchor</span> = a; } <span class="hljs-keyword">return</span> copy; }</pre></div></div> </li> <li id="section-26"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-26">&#x00a7;</a> </div> <h4 id="clone-management">Clone management</h4> <p>TODO - this functionality is currently disabled, need to enable it and make it work properly</p> </div> <div class="content"><div class='highlight'><pre>P.<span class="hljs-property">clone</span> = λ<span class="hljs-variable language_">this</span>;</pre></div></div> </li> <li id="section-27"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-27">&#x00a7;</a> </div> <h4 id="kill-management">Kill management</h4> <p>No additional kill functionality required</p> </div> </li> <li id="section-28"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-28">&#x00a7;</a> </div> <h4 id="get-set-deltaset">Get, Set, deltaSet</h4> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">let</span> G = P.<span class="hljs-property">getters</span>, S = P.<span class="hljs-property">setters</span>, D = P.<span class="hljs-property">deltaSetters</span>;</pre></div></div> </li> <li id="section-29"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-29">&#x00a7;</a> </div> <p><strong>get</strong> - copied over from the entity mixin</p> </div> <div class="content"><div class='highlight'><pre>P.<span class="hljs-property">get</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">item</span>) { <span class="hljs-keyword">const</span> getter = <span class="hljs-variable language_">this</span>.<span class="hljs-property">getters</span>[item]; <span class="hljs-keyword">if</span> (getter) <span class="hljs-keyword">return</span> getter.<span class="hljs-title function_">call</span>(<span class="hljs-variable language_">this</span>); <span class="hljs-keyword">else</span> { <span class="hljs-keyword">const</span> def = <span class="hljs-variable language_">this</span>.<span class="hljs-property">defs</span>[item], state = <span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>; <span class="hljs-keyword">let</span> val; <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> def != <span class="hljs-string">&#x27;undefined&#x27;</span>) { val = <span class="hljs-variable language_">this</span>[item]; <span class="hljs-keyword">return</span>