scrawl-canvas
Version:
Version 8.9.4 - 19 Nov 2022
1,126 lines (739 loc) • 121 kB
HTML
<!DOCTYPE html>
<html>
<head>
<title>Mesh 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 …</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">§</a>
</div>
<h1 id="mesh-factory">Mesh factory</h1>
<p>The Scrawl-canvas Mesh entity applies a Net particle system to an image, allowing the image to be deformed by dragging particles around the canvas. This is a similar concept to <a href="https://helpx.adobe.com/uk/photoshop/using/warp-images-shapes-paths.html">Photoshop warp meshes</a> and (more distantly) <a href="https://docs.gimp.org/2.10/en/gimp-tool-cage.html">the Gimp’s cage tool</a>.</p>
<p>Mesh entitys are <em><strong>composite entitys</strong></em> - an entity that relies on other entitys for its basic functionality.</p>
<ul>
<li>Every Mesh object requires a <a href="./net.html">Net</a> entity create the grid that it uses for transforming its image.</li>
<li>A Mesh entity also requires a <a href="./picture.html">Picture</a> entity to act as its image source.</li>
<li>Meshes can (in theory) 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 (in theory) use <strong>Anchor</strong> objects for user navigation. </li>
<li>They can (in theory) be rendered to the canvas by including them in a <strong>Cell</strong> object’s <strong>Group</strong>. </li>
<li>They can (in theory) be <strong>animated</strong> directly, or using delta animation, or act as the target for <strong>Tween</strong> animations.</li>
<li>Meshes can (in theory) be cloned, and killed.</li>
</ul>
<p><em><strong>Note that this is experimental technology!</strong></em></p>
<ul>
<li>The Mesh entity code base shares many similarities to that of the Loom entity; some of the code has been copied over from that file directly.</li>
<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: packet management, clone and kill functionality not yet tested. Much of the other functionality also lacks tests.</li>
</ul>
</div>
</li>
<li id="section-2">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-2">§</a>
</div>
<h4 id="demos">Demos:</h4>
<ul>
<li><a href="../../demo/particles-008.html">Particles-008</a> - Net entity: generation and basic functionality, including Spring objects</li>
<li><a href="../../demo/particles-016.html">Particles-016</a> - Mesh entitys</li>
</ul>
</div>
</li>
<li id="section-3">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-3">§</a>
</div>
<h4 id="imports">Imports</h4>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">import</span> { constructors, artefact } <span class="hljs-keyword">from</span> <span class="hljs-string">'../core/library.js'</span>;
<span class="hljs-keyword">import</span> { currentGroup } <span class="hljs-keyword">from</span> <span class="hljs-string">'../core/document.js'</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">'../core/utilities.js'</span>;
<span class="hljs-keyword">import</span> { makeState, stateKeys } <span class="hljs-keyword">from</span> <span class="hljs-string">'../factory/state.js'</span>;
<span class="hljs-keyword">import</span> { requestCell, releaseCell } <span class="hljs-keyword">from</span> <span class="hljs-string">'../factory/cell.js'</span>;
<span class="hljs-keyword">import</span> baseMix <span class="hljs-keyword">from</span> <span class="hljs-string">'../mixin/base.js'</span>;
<span class="hljs-keyword">import</span> deltaMix <span class="hljs-keyword">from</span> <span class="hljs-string">'../mixin/delta.js'</span>;
<span class="hljs-keyword">import</span> anchorMix <span class="hljs-keyword">from</span> <span class="hljs-string">'../mixin/anchor.js'</span>;</pre></div></div>
</li>
<li id="section-4">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-4">§</a>
</div>
<h4 id="mesh-constructor">Mesh constructor</h4>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">const</span> <span class="hljs-title class_">Mesh</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-title function_">set</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">defs</span>);
<span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span> = <span class="hljs-title function_">makeState</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">§</a>
</div>
<h4 id="mesh-prototype">Mesh prototype</h4>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">let</span> P = <span class="hljs-title class_">Mesh</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">'Mesh'</span>;
P.<span class="hljs-property">lib</span> = <span class="hljs-string">'entity'</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">§</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">§</a>
</div>
<h4 id="mesh-attributes">Mesh 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">§</a>
</div>
<p><strong>net</strong> - A Mesh entity requires a Net entity, set to generate a weak or strong net, to supply Particle objects to act as its mapping coordinates.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">net</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">§</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-10">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-10">§</a>
</div>
<p><strong>source</strong> - The Picture entity source for this Mesh. 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 Mesh entity are set in the Picture entity, not the Mesh, 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>; Mesh 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-11">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-11">§</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 Mesh entity to do this using a flag, rather than get the Picture entity to update all its Mesh 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-12">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-12">§</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-13">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-13">§</a>
</div>
<p>The Mesh 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">delta</span>: <span class="hljs-literal">null</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-14">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-14">§</a>
</div>
<p><strong>noCanvasEngineUpdates</strong> - Boolean flag - Canvas engine updates are required for the Mesh’s border - strokeStyle and line styling; if a Mesh 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-15">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-15">§</a>
</div>
<p><strong>noDeltaUpdates</strong> - Boolean flag - Mesh entitys support delta animation - achieved by updating the <code>...path</code> attributes by appropriate (and small!) values. If the Mesh 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-16">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-16">§</a>
</div>
<p><strong>onEnter</strong>, <strong>onLeave</strong>, <strong>onDown</strong>, <strong>onUp</strong> - Mesh entitys support <em><strong>collision detection</strong></em>, reporting a hit when a test coordinate falls within the Mesh’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-17">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-17">§</a>
</div>
<p><strong>noUserInteraction</strong> - Boolean flag - To switch off collision detection for a Mesh 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-18">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-18">§</a>
</div>
<p><a href="./anchor.html">Anchor objects</a> can be assigned to Mesh 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><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">'fill'</span>,</pre></div></div>
</li>
<li id="section-19">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-19">§</a>
</div>
<p>Mesh 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 Mesh entity’s border (the Shape entitys, with connecting lines between their paths’ start and end points) and fill (the image displayed between the Mesh’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 Mesh 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 Mesh’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-20">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-20">§</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">'pathObject'</span>, <span class="hljs-string">'state'</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">'^(local|dirty|current)'</span>, <span class="hljs-string">'Subscriber$'</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">'group'</span>, <span class="hljs-string">'net'</span>, <span class="hljs-string">'source'</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">'onEnter'</span>, <span class="hljs-string">'onLeave'</span>, <span class="hljs-string">'onDown'</span>, <span class="hljs-string">'onUp'</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) < <span class="hljs-number">0</span> && 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-21">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-21">§</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-22">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-22">§</a>
</div>
<h4 id="kill-management">Kill management</h4>
<p>No additional kill functionality required</p>
</div>
</li>
<li id="section-23">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-23">§</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-24">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-24">§</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">let</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">'undefined'</span>) {
val = <span class="hljs-variable language_">this</span>[item];
<span class="hljs-keyword">return</span> (<span class="hljs-keyword">typeof</span> val != <span class="hljs-string">'undefined'</span>) ? val : def;
}
def = state.<span class="hljs-property">defs</span>[item];
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> def != <span class="hljs-string">'undefined'</span>) {
val = state[item];
<span class="hljs-keyword">return</span> (<span class="hljs-keyword">typeof</span> val != <span class="hljs-string">'undefined'</span>) ? val : def;
}
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
}
};</pre></div></div>
</li>
<li id="section-25">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-25">§</a>
</div>
<p><strong>set</strong> - copied over from the entity mixin.</p>
</div>
<div class="content"><div class='highlight'><pre>P.<span class="hljs-property">set</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">items = Ωempty</span>) {
<span class="hljs-keyword">const</span> keys = <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">keys</span>(items),
keysLen = keys.<span class="hljs-property">length</span>;
<span class="hljs-keyword">if</span> (keysLen) {
<span class="hljs-keyword">const</span> setters = <span class="hljs-variable language_">this</span>.<span class="hljs-property">setters</span>,
defs = <span class="hljs-variable language_">this</span>.<span class="hljs-property">defs</span>,
state = <span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>;
<span class="hljs-keyword">const</span> stateSetters = (state) ? state.<span class="hljs-property">setters</span> : Ωempty;
<span class="hljs-keyword">const</span> stateDefs = (state) ? state.<span class="hljs-property">defs</span> : Ωempty;
<span class="hljs-keyword">let</span> predefined, i, key, value;
<span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i < keysLen; i++) {
key = keys[i];
value = items[key];
<span class="hljs-keyword">if</span> (key && key != <span class="hljs-string">'name'</span> && value != <span class="hljs-literal">null</span>) {
<span class="hljs-keyword">if</span> (stateKeys.<span class="hljs-title function_">indexOf</span>(key) < <span class="hljs-number">0</span>) {
predefined = setters[key];
<span class="hljs-keyword">if</span> (predefined) predefined.<span class="hljs-title function_">call</span>(<span class="hljs-variable language_">this</span>, value);
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> defs[key] != <span class="hljs-string">'undefined'</span>) {
<span class="hljs-variable language_">this</span>[key] = value;
<span class="hljs-variable language_">this</span>.<span class="hljs-property">dirtyFilterIdentifier</span> = <span class="hljs-literal">true</span>;
}
}
<span class="hljs-keyword">else</span> {
predefined = stateSetters[key];
<span class="hljs-keyword">if</span> (predefined) predefined.<span class="hljs-title function_">call</span>(state, value);
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> stateDefs[key] != <span class="hljs-string">'undefined'</span>) state[key] = value;
}
}
}
}
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
};</pre></div></div>
</li>
<li id="section-26">
<div class="annotation">
<div class="sswrap ">
<a class="ss" href="#section-26">§</a>
</div>
<p><strong>setDelta</strong> - copied over from the entity mixin.</p>
</div>