UNPKG

scrawl-canvas

Version:
1,075 lines (698 loc) 88.2 kB
<!DOCTYPE html> <html> <head> <title>Base mixin</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="../factory/action.html"> ./source/factory/action.js </a> <a class="source" href="../factory/anchor.html"> ./source/factory/anchor.js </a> <a class="source" href="../factory/animation.html"> ./source/factory/animation.js </a> <a class="source" href="../factory/bezier.html"> ./source/factory/bezier.js </a> <a class="source" href="../factory/block.html"> ./source/factory/block.js </a> <a class="source" href="../factory/canvas.html"> ./source/factory/canvas.js </a> <a class="source" href="../factory/cell.html"> ./source/factory/cell.js </a> <a class="source" href="../factory/cog.html"> ./source/factory/cog.js </a> <a class="source" href="../factory/color.html"> ./source/factory/color.js </a> <a class="source" href="../factory/conicGradient.html"> ./source/factory/conicGradient.js </a> <a class="source" href="../factory/coordinate.html"> ./source/factory/coordinate.js </a> <a class="source" href="../factory/crescent.html"> ./source/factory/crescent.js </a> <a class="source" href="../factory/element.html"> ./source/factory/element.js </a> <a class="source" href="../factory/emitter.html"> ./source/factory/emitter.js </a> <a class="source" href="../factory/filter.html"> ./source/factory/filter.js </a> <a class="source" href="../factory/filterEngine-bluenoiseData.html"> ./source/factory/filterEngine-bluenoiseData.js </a> <a class="source" href="../factory/filterEngine.html"> ./source/factory/filterEngine.js </a> <a class="source" href="../factory/fontAttributes.html"> ./source/factory/fontAttributes.js </a> <a class="source" href="../factory/gradient.html"> ./source/factory/gradient.js </a> <a class="source" href="../factory/grid.html"> ./source/factory/grid.js </a> <a class="source" href="../factory/group.html"> ./source/factory/group.js </a> <a class="source" href="../factory/imageAsset.html"> ./source/factory/imageAsset.js </a> <a class="source" href="../factory/line.html"> ./source/factory/line.js </a> <a class="source" href="../factory/lineSpiral.html"> ./source/factory/lineSpiral.js </a> <a class="source" href="../factory/loom.html"> ./source/factory/loom.js </a> <a class="source" href="../factory/mesh.html"> ./source/factory/mesh.js </a> <a class="source" href="../factory/net.html"> ./source/factory/net.js </a> <a class="source" href="../factory/noiseAsset.html"> ./source/factory/noiseAsset.js </a> <a class="source" href="../factory/oval.html"> ./source/factory/oval.js </a> <a class="source" href="../factory/palette.html"> ./source/factory/palette.js </a> <a class="source" href="../factory/particle.html"> ./source/factory/particle.js </a> <a class="source" href="../factory/particleForce.html"> ./source/factory/particleForce.js </a> <a class="source" href="../factory/particleHistory.html"> ./source/factory/particleHistory.js </a> <a class="source" href="../factory/particleSpring.html"> ./source/factory/particleSpring.js </a> <a class="source" href="../factory/particleWorld.html"> ./source/factory/particleWorld.js </a> <a class="source" href="../factory/pattern.html"> ./source/factory/pattern.js </a> <a class="source" href="../factory/phrase.html"> ./source/factory/phrase.js </a> <a class="source" href="../factory/picture.html"> ./source/factory/picture.js </a> <a class="source" href="../factory/polygon.html"> ./source/factory/polygon.js </a> <a class="source" href="../factory/polyline.html"> ./source/factory/polyline.js </a> <a class="source" href="../factory/quadratic.html"> ./source/factory/quadratic.js </a> <a class="source" href="../factory/quaternion.html"> ./source/factory/quaternion.js </a> <a class="source" href="../factory/radialGradient.html"> ./source/factory/radialGradient.js </a> <a class="source" href="../factory/rawAsset.html"> ./source/factory/rawAsset.js </a> <a class="source" href="../factory/rdAsset.html"> ./source/factory/rdAsset.js </a> <a class="source" href="../factory/rectangle.html"> ./source/factory/rectangle.js </a> <a class="source" href="../factory/renderAnimation.html"> ./source/factory/renderAnimation.js </a> <a class="source" href="../factory/shape.html"> ./source/factory/shape.js </a> <a class="source" href="../factory/spiral.html"> ./source/factory/spiral.js </a> <a class="source" href="../factory/spriteAsset.html"> ./source/factory/spriteAsset.js </a> <a class="source" href="../factory/stack.html"> ./source/factory/stack.js </a> <a class="source" href="../factory/star.html"> ./source/factory/star.js </a> <a class="source" href="../factory/state.html"> ./source/factory/state.js </a> <a class="source" href="../factory/tetragon.html"> ./source/factory/tetragon.js </a> <a class="source" href="../factory/ticker.html"> ./source/factory/ticker.js </a> <a class="source" href="../factory/tracer.html"> ./source/factory/tracer.js </a> <a class="source" href="../factory/tween.html"> ./source/factory/tween.js </a> <a class="source" href="../factory/unstackedElement.html"> ./source/factory/unstackedElement.js </a> <a class="source" href="../factory/vector.html"> ./source/factory/vector.js </a> <a class="source" href="../factory/videoAsset.html"> ./source/factory/videoAsset.js </a> <a class="source" href="../factory/wheel.html"> ./source/factory/wheel.js </a> <a class="source" href="anchor.html"> ./source/mixin/anchor.js </a> <a class="source" href="asset.html"> ./source/mixin/asset.js </a> <a class="source" href="assetAdvancedFunctionality.html"> ./source/mixin/assetAdvancedFunctionality.js </a> <a class="source" href="assetConsumer.html"> ./source/mixin/assetConsumer.js </a> <a class="source" href="base.html"> ./source/mixin/base.js </a> <a class="source" href="cascade.html"> ./source/mixin/cascade.js </a> <a class="source" href="delta.html"> ./source/mixin/delta.js </a> <a class="source" href="displayShape.html"> ./source/mixin/displayShape.js </a> <a class="source" href="dom.html"> ./source/mixin/dom.js </a> <a class="source" href="entity.html"> ./source/mixin/entity.js </a> <a class="source" href="filter.html"> ./source/mixin/filter.js </a> <a class="source" href="mimic.html"> ./source/mixin/mimic.js </a> <a class="source" href="path.html"> ./source/mixin/path.js </a> <a class="source" href="pattern.html"> ./source/mixin/pattern.js </a> <a class="source" href="pivot.html"> ./source/mixin/pivot.js </a> <a class="source" href="position.html"> ./source/mixin/position.js </a> <a class="source" href="shapeBasic.html"> ./source/mixin/shapeBasic.js </a> <a class="source" href="shapeCurve.html"> ./source/mixin/shapeCurve.js </a> <a class="source" href="shapePathCalculation.html"> ./source/mixin/shapePathCalculation.js </a> <a class="source" href="styles.html"> ./source/mixin/styles.js </a> <a class="source" href="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="base-mixin">Base mixin</h1> <p>This mixin sets up much of the basic functionality of a Scrawl-canvas Object:</p> <ul> <li><strong>defs</strong> - every Scrawl-canvas object comes with a set of pre-defined attributes with default values; the specific attributes will vary between factories, but all include a ‘name’ attribute.</li> <li><strong>getters</strong> - to retrieve values from a given attribute.</li> <li><strong>setters</strong> - to update a range of attribute values in a Scrawl-canvas object.</li> <li><strong>deltaSetters</strong> - to add supplied values to a range of attribute values in a Scrawl-canvas object.</li> <li><strong>name</strong> attribute functionality - all Scrawl-canvas objects are given a name attribute, either supplied by the developer or computer-generated by the system.</li> <li>Object <strong>registration</strong> functionality - most factory-generated objects get registered in the Scrawl-canvas library object.</li> <li><strong>packet</strong> generation and use - Scrawl-canvas objects can deliver and consume text-based packets to build new objects or update existing objects.</li> <li><strong>clone</strong> functionality - most Scrawl-canvas objects can be cloned, to make the development of a canvas (or stack) scene easier.</li> <li><strong>kill</strong> functionality - remove objects from the Scrawl-canvas system - and, where required, the DOM - in a safe way.</li> </ul> <p>Given the fundamental nature of the above functionality the base mixin should always, when coding a Scrawl-canvas factory, be the first to be applied to that factory function’s prototype.</p> </div> </li> <li id="section-2"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-2">&#x00a7;</a> </div> <h4 id="imports">Imports</h4> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> library <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../core/library.js&#x27;</span>; <span class="hljs-keyword">import</span> { mergeOver, pushUnique, removeItem, generateUniqueString, isa_boolean, isa_obj, addStrings, xt, xta, λ<span class="hljs-literal">null</span>, Ωempty } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../core/utilities.js&#x27;</span>;</pre></div></div> </li> <li id="section-3"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-3">&#x00a7;</a> </div> <h4 id="export-function">Export function</h4> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> (<span class="hljs-params">P = Ωempty</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="get-set-deltaset">Get, Set, deltaSet</h4> <p>The <strong>defs</strong> object supplies default values for a Scrawl-canvas object. Setter functions will check to see that a related defs attribute exists before allowing users to update an object attribute. Similarly the getter function will use the defs object to supply default values for an attribute that has not otherwise been set, or has been deleted by a user.</p> </div> <div class="content"><div class='highlight'><pre> P.<span class="hljs-property">defs</span> = {};</pre></div></div> </li> <li id="section-5"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-5">&#x00a7;</a> </div> <p>The <strong>getters</strong> object holds a suite of functions for given factory object attributes that need to have their values processed before they can be returned to the user.</p> </div> <div class="content"><div class='highlight'><pre> P.<span class="hljs-property">getters</span> = {};</pre></div></div> </li> <li id="section-6"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-6">&#x00a7;</a> </div> <p>The <strong>setters</strong> object holds a suite of functions for given factory object attributes that need to process a new value before setting it to the attribute.</p> </div> <div class="content"><div class='highlight'><pre> P.<span class="hljs-property">setters</span> = {};</pre></div></div> </li> <li id="section-7"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-7">&#x00a7;</a> </div> <p>The <strong>deltaSetters</strong> object holds a suite of functions for given factory object attributes that need to process a new value before adding it to the attribute’s existing value.</p> </div> <div class="content"><div class='highlight'><pre> P.<span class="hljs-property">deltaSetters</span> = {};</pre></div></div> </li> <li id="section-8"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-8">&#x00a7;</a> </div> <p><code>get</code> - Retrieve an attribute value using the <strong>get</strong> function. While many attributes can be retrieved directly - for example, <em>scrawl.artefact.myelement.scale</em> - some attributes should only ever be retrieved using get:</p> <pre><code>scrawl.<span class="hljs-property">artefact</span>.<span class="hljs-property">myelement</span>.<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;startX&#x27;</span>); -&gt; <span class="hljs-number">200</span> </code></pre> </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">if</span> (<span class="hljs-title function_">xt</span>(item)) { <span class="hljs-keyword">let</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]; <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> def != <span class="hljs-string">&#x27;undefined&#x27;</span>) { <span class="hljs-keyword">let</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">&#x27;undefined&#x27;</span>) ? val : def; } } } <span class="hljs-keyword">return</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><code>set</code> - Set an attribute value using the <strong>set</strong> function. It is extremely important that all factory object attributes are set using the set function; setting an attribute directly will lead to unexpected behaviour! The set function takes a single object as its argument.</p> <pre><code>scrawl.<span class="hljs-property">artefact</span>.<span class="hljs-property">myelement</span>.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">startX</span>: <span class="hljs-number">50</span>, <span class="hljs-attr">startY</span>: <span class="hljs-number">200</span>, <span class="hljs-attr">scale</span>: <span class="hljs-number">1.5</span>, <span class="hljs-attr">roll</span>: <span class="hljs-number">90</span>, }); </code></pre> </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>; <span class="hljs-keyword">let</span> predefined, i, key, value; <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i &lt; keysLen; i++) { key = keys[i]; value = items[key]; <span class="hljs-keyword">if</span> (key &amp;&amp; key !== <span class="hljs-string">&#x27;name&#x27;</span> &amp;&amp; value != <span class="hljs-literal">null</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">&#x27;undefined&#x27;</span>) <span class="hljs-variable language_">this</span>[key] = value; } } } <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</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><code>setDelta</code> - Add a value to an existing attribute value using the <strong>setDelta</strong> function. It is extremely important that all factory object attributes are updated using the setDelta function; updating an attribute directly will lead to unexpected behaviour! The setDelta function takes a single object as its argument.</p> <pre><code>scrawl.<span class="hljs-property">artefact</span>.<span class="hljs-property">myelement</span>.<span class="hljs-title function_">setDelta</span>({ <span class="hljs-attr">startX</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">startY</span>: -<span class="hljs-number">20</span>, <span class="hljs-attr">scale</span>: <span class="hljs-number">0.05</span>, <span class="hljs-attr">roll</span>: <span class="hljs-number">5</span>, }); </code></pre> </div> <div class="content"><div class='highlight'><pre> P.<span class="hljs-property">setDelta</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">deltaSetters</span>, defs = <span class="hljs-variable language_">this</span>.<span class="hljs-property">defs</span>; <span class="hljs-keyword">let</span> predefined, i, iz, key, value; <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i &lt; keysLen; i++) { key = keys[i]; value = items[key]; <span class="hljs-keyword">if</span> (key &amp;&amp; key !== <span class="hljs-string">&#x27;name&#x27;</span> &amp;&amp; value != <span class="hljs-literal">null</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">&#x27;undefined&#x27;</span>) <span class="hljs-variable language_">this</span>[key] = <span class="hljs-title function_">addStrings</span>(<span class="hljs-variable language_">this</span>[key], value); } } } <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>; };</pre></div></div> </li> <li id="section-11"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-11">&#x00a7;</a> </div> <h4 id="shared-attributes">Shared attributes</h4> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">let</span> defaultAttributes = {</pre></div></div> </li> <li id="section-12"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-12">&#x00a7;</a> </div> <p>Scrawl-canvas relies on unique <strong>name</strong> values being present in a factory object for a wide range of functionalities. Most of the library sections store an object by its name value, for example: <em>scrawl.artefact.myelement</em></p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;&#x27;</span>, }; P.<span class="hljs-property">defs</span> = <span class="hljs-title function_">mergeOver</span>(P.<span class="hljs-property">defs</span>, defaultAttributes); <span class="hljs-keyword">let</span> G = P.<span class="hljs-property">getters</span>; G.<span class="hljs-property">type</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">type</span>; }; G.<span class="hljs-property">isArtefact</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">isArtefact</span>; }; G.<span class="hljs-property">isAsset</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">isAsset</span>; };</pre></div></div> </li> <li id="section-13"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-13">&#x00a7;</a> </div> <h4 id="packet-management">Packet management</h4> <p><strong>Packets</strong> are Scrawl-canvas’s way of generating and consuming SC object data, both locally and over a network. A packet is a formatted JSON String which can be captured in a variable or saved to a text file.</p> <p>The packet format is as follows:</p> <pre><code><span class="hljs-string">&quot;[object-name, object-type, object&#x27;s-library-section, {object-data-key:value-pairs}]&quot;</span> </code></pre> <ul> <li>Use <strong>saveAsPacket()</strong> to get a stringified representation of a Scrawl-canvas object, which can then be consumed by other SC objects at a later date.</li> <li>Use <strong>actionPacket(‘packet-string’)</strong> to apply a previously saved packet to an existing SC object, or to create a new SC object from the packet if it doesn’t exist already</li> <li>Use <strong>importPacket(url)</strong> to retrieve a packet from a text file (normally kept remotely on a server); the function’s argument can be either the packet file’s url address, or an Array of such addresses.</li> </ul> <p>Using <em>JSON.stringify(object)</em>, or <em>object.toString()</em>, to generate String representations of SC objects is not recommended as they will forego the pre-processing that saveAsPacket performs to generate the packet String.</p> <p>Example:</p> <pre><code><span class="hljs-keyword">let</span> canvas = scrawl.<span class="hljs-property">library</span>.<span class="hljs-property">canvas</span>.<span class="hljs-property">mycanvas</span>; canvas.<span class="hljs-title function_">setAsCurrentCanvas</span>(); <span class="hljs-keyword">let</span> box = scrawl.<span class="hljs-title function_">makeBlock</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;my-box&#x27;</span>, <span class="hljs-attr">startX</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">startY</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">width</span>: <span class="hljs-number">100</span>, <span class="hljs-attr">height</span>: <span class="hljs-number">50</span>, <span class="hljs-attr">fillStyle</span>: <span class="hljs-string">&#x27;red&#x27;</span>, <span class="hljs-attr">onEnter</span>: <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { box.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">fillStyle</span>: <span class="hljs-string">&#x27;pink&#x27;</span>, }); }, <span class="hljs-attr">onLeave</span>: <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { box.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">fillStyle</span>: <span class="hljs-string">&#x27;red&#x27;</span>, }); } }); <span class="hljs-keyword">let</span> boxPacket = box.<span class="hljs-title function_">saveAsPacket</span>(); <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(boxPacket); | [ | <span class="hljs-string">&quot;my-box&quot;</span>, | <span class="hljs-string">&quot;Block&quot;</span>, | <span class="hljs-string">&quot;entity&quot;</span>, | { | <span class="hljs-string">&quot;name&quot;</span>:<span class="hljs-string">&quot;my-box&quot;</span>, | <span class="hljs-string">&quot;dimensions&quot;</span>:[<span class="hljs-number">100</span>,<span class="hljs-number">50</span>], | <span class="hljs-string">&quot;start&quot;</span>:[<span class="hljs-number">10</span>,<span class="hljs-number">10</span>], | <span class="hljs-string">&quot;delta&quot;</span>:{}, | <span class="hljs-string">&quot;onEnter&quot;</span>:<span class="hljs-string">&quot;function () {\n\t\tbox.set({\n\t\t\tfillStyle: &#x27;pink&#x27;,\n\t\t});\n\t}&quot;</span>, | <span class="hljs-string">&quot;onLeave&quot;</span>:<span class="hljs-string">&quot;function () {\n\t\tbox.set({\n\t\t\tfillStyle: &#x27;red&#x27;,\n\t\t});\n\t}&quot;</span>, | <span class="hljs-string">&quot;group&quot;</span>:<span class="hljs-string">&quot;mycanvas_base&quot;</span>, | <span class="hljs-string">&quot;fillStyle&quot;</span>:<span class="hljs-string">&quot;black&quot;</span> | } | ] <span class="hljs-comment">// delete the box</span> box.<span class="hljs-title function_">kill</span>() <span class="hljs-comment">// recreate the entity - we can invoke the function on any handy SC object without affecting that object</span> <span class="hljs-keyword">let</span> resurrectedBox = canvas.<span class="hljs-title function_">actionPacket</span>(boxPacket); <span class="hljs-comment">// recreate the entity - if we had saved the packet to a file on a server</span> <span class="hljs-keyword">let</span> fetchedBox = canvas.<span class="hljs-title function_">importPacket</span>(<span class="hljs-string">&#x27;https://example.com/path/to/boxPacket.txt&#x27;</span>); </code></pre> </div> </li> <li id="section-14"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-14">&#x00a7;</a> </div> <p>Internal processing Arrays</p> </div> <div class="content"><div class='highlight'><pre> P.<span class="hljs-property">packetExclusions</span> = []; P.<span class="hljs-property">packetExclusionsByRegex</span> = []; P.<span class="hljs-property">packetCoordinates</span> = []; P.<span class="hljs-property">packetObjects</span> = []; P.<span class="hljs-property">packetFunctions</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><code>saveAsPacket</code> - accepts an items {key:value} object argument with the following (optional) attributes:</p> <ul> <li><strong>includeDefaults</strong> - either a boolean (default: false), or an array of attribute strings listing those attributes whose values should be included in the packet even if those values are the default values; setting this attribute to boolean true will include all of the Scrawl-canvas object’s attribute values in the (much larger) packet.</li> </ul> <p>Note: if the argument is supplied as a boolean ‘true’, code will create an items object with an attribute ‘includeDefaults’ set to true.</p> </div> <div class="content"><div class='highlight'><pre> P.<span class="hljs-property">saveAsPacket</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">items = Ωempty</span>) { <span class="hljs-keyword">if</span> (<span class="hljs-title function_">isa_boolean</span>(items) &amp;&amp; items) items = { <span class="hljs-attr">includeDefaults</span>: <span class="hljs-literal">true</span>, } <span class="hljs-keyword">let</span> defs = <span class="hljs-variable language_">this</span>.<span class="hljs-property">defs</span>, defKeys = <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">keys</span>(defs), packetExclusions = <span class="hljs-variable language_">this</span>.<span class="hljs-property">packetExclusions</span>, packetExclusionsByRegex = <span class="hljs-variable language_">this</span>.<span class="hljs-property">packetExclusionsByRegex</span>, packetCoordinates = <span class="hljs-variable language_">this</span>.<span class="hljs-property">packetCoordinates</span>, packetObjects = <span class="hljs-variable language_">this</span>.<span class="hljs-property">packetObjects</span>, packetFunctions = <span class="hljs-variable language_">this</span>.<span class="hljs-property">packetFunctions</span>, packetDefaultInclusions = items.<span class="hljs-property">includeDefaults</span> || <span class="hljs-literal">false</span>, copy = {}; <span class="hljs-keyword">if</span> (packetDefaultInclusions &amp;&amp; !<span class="hljs-title class_">Array</span>.<span class="hljs-title function_">isArray</span>(packetDefaultInclusions)) { packetDefaultInclusions = <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">keys</span>(defs); } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (!packetDefaultInclusions) packetDefaultInclusions = []; <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">entries</span>(<span class="hljs-variable language_">this</span>).<span class="hljs-title function_">forEach</span>(<span class="hljs-function">(<span class="hljs-params">[key, val]</span>) =&gt;</span> { <span class="hljs-keyword">let</span> flag = <span class="hljs-literal">true</span>, test; <span class="hljs-keyword">if</span> (defKeys.<span class="hljs-title function_">indexOf</span>(key) &lt; <span class="hljs-number">0</span>) flag = <span class="hljs-literal">false</span>; <span class="hljs-keyword">if</span> (flag &amp;&amp; packetExclusions.<span class="hljs-title function_">indexOf</span>(key) &gt;= <span class="hljs-number">0</span>) flag = <span class="hljs-literal">false</span>; <span class="hljs-keyword">if</span> (flag) { test = packetExclusionsByRegex.<span class="hljs-title function_">some</span>(<span class="hljs-function"><span class="hljs-params">reg</span> =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">RegExp</span>(reg).<span class="hljs-title function_">test</span>(key)); <span class="hljs-keyword">if</span> (test) flag = <span class="hljs-literal">false</span>; } <span class="hljs-keyword">if</span> (flag) { <span class="hljs-keyword">if</span> (packetFunctions.<span class="hljs-title function_">indexOf</span>(key) &gt;= <span class="hljs-number">0</span>) { <span class="hljs-keyword">if</span> (<span class="hljs-title function_">xt</span>(val) &amp;&amp; val !== <span class="hljs-literal">null</span>) { <span class="hljs-keyword">let</span> func = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">stringifyFunction</span>(val); <span class="hljs-keyword">if</span> (func &amp;&amp; func.<span class="hljs-property">length</span>) copy[key] = func; } } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (packetObjects.<span class="hljs-title function_">indexOf</span>(key) &gt;= <span class="hljs-number">0</span> &amp;&amp; <span class="hljs-variable language_">this</span>[key] &amp;&amp; <span class="hljs-variable language_">this</span>[key].<span class="hljs-property">name</span>) copy[key] = <span class="hljs-variable language_">this</span>[key].<span class="hljs-property">name</span>; <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (packetCoordinates.<span class="hljs-title function_">indexOf</span>(key) &gt;= <span class="hljs-number">0</span>) { <span class="hljs-keyword">if</span> (packetDefaultInclusions.<span class="hljs-title function_">indexOf</span>(key) &gt;= <span class="hljs-number">0</span>) copy[key] = val; <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (val[<span class="hljs-number">0</span>] || val[<span class="hljs-number">1</span>]) copy[key] = val; } <span class="hljs-keyword">else</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>Start cascade down to factory to pick up factory-specific exclusions</p> </div> <div class="content"><div class='highlight'><pre> test = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">processPacketOut</span>(key, val, packetDefaultInclusions); <span class="hljs-keyword">if</span> (test) copy[key] = val; } } }, <span class="hljs-variable language_">this</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>Start cascade down to factory to complete the copy object’s build</p> </div> <div class="content"><div class='highlight'><pre> copy = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">finalizePacketOut</span>(copy, items);</pre></div></div> </li> <li id="section-18"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-18">&#x00a7;</a> </div> <p>Return a JSON string</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>([<span class="hljs-variable language_">this</span>.<span class="hljs-property">name</span>, <span class="hljs-variable language_">this</span>.<span class="hljs-property">type</span>, <span class="hljs-variable language_">this</span>.<span class="hljs-property">lib</span>, copy]); };</pre></div></div> </li> <li id="section-19"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-19">&#x00a7;</a> </div> <p>Helper functions that get defined in various mixins and factories - localizing the functionality to meet the specific needs of that factory’s object instances</p> </div> </li> <li id="section-20"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-20">&#x00a7;</a> </div> <p><code>stringifyFunction</code></p> </div> <div class="content"><div class='highlight'><pre> P.<span class="hljs-property">stringifyFunction</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">val</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>The dotAll /s regex flag currently not supported by Firefox let matches = val.toString().match(/((.<em>?)).</em>?{(.*)}/s);</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">let</span> matches = val.<span class="hljs-title function_">toString</span>().<span class="hljs-title function_">match</span>(<span class="hljs-regexp">/\(([\s\S]*?)\)[\s\S]*?\{([\s\S]*)\}/</span>); <span class="hljs-keyword">let</span> vars = matches[<span class="hljs-number">1</span>]; <span class="hljs-keyword">let</span> func = matches[<span class="hljs-number">2</span>]; <span class="hljs-keyword">return</span> (<span class="hljs-title function_">xta</span>(vars, func)) ? <span class="hljs-string">`<span class="hljs-subst">${vars}</span>~~~<span class="hljs-subst">${func}</span>`</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><code>processPacketOut</code></p> </div> <div class="content"><div class='highlight'><pre> 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 func