UNPKG

scrawl-canvas

Version:
1,358 lines (840 loc) 46 kB
<!DOCTYPE html> <html> <head> <title>Demo Canvas 037</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="canvas-001.html"> ./demo/canvas-001.js </a> <a class="source" href="canvas-002.html"> ./demo/canvas-002.js </a> <a class="source" href="canvas-003.html"> ./demo/canvas-003.js </a> <a class="source" href="canvas-004.html"> ./demo/canvas-004.js </a> <a class="source" href="canvas-005.html"> ./demo/canvas-005.js </a> <a class="source" href="canvas-006.html"> ./demo/canvas-006.js </a> <a class="source" href="canvas-007.html"> ./demo/canvas-007.js </a> <a class="source" href="canvas-008.html"> ./demo/canvas-008.js </a> <a class="source" href="canvas-009.html"> ./demo/canvas-009.js </a> <a class="source" href="canvas-010.html"> ./demo/canvas-010.js </a> <a class="source" href="canvas-011.html"> ./demo/canvas-011.js </a> <a class="source" href="canvas-012.html"> ./demo/canvas-012.js </a> <a class="source" href="canvas-013.html"> ./demo/canvas-013.js </a> <a class="source" href="canvas-014.html"> ./demo/canvas-014.js </a> <a class="source" href="canvas-015.html"> ./demo/canvas-015.js </a> <a class="source" href="canvas-015a.html"> ./demo/canvas-015a.js </a> <a class="source" href="canvas-016.html"> ./demo/canvas-016.js </a> <a class="source" href="canvas-017.html"> ./demo/canvas-017.js </a> <a class="source" href="canvas-018.html"> ./demo/canvas-018.js </a> <a class="source" href="canvas-019.html"> ./demo/canvas-019.js </a> <a class="source" href="canvas-019a.html"> ./demo/canvas-019a.js </a> <a class="source" href="canvas-020.html"> ./demo/canvas-020.js </a> <a class="source" href="canvas-021.html"> ./demo/canvas-021.js </a> <a class="source" href="canvas-022.html"> ./demo/canvas-022.js </a> <a class="source" href="canvas-023.html"> ./demo/canvas-023.js </a> <a class="source" href="canvas-024.html"> ./demo/canvas-024.js </a> <a class="source" href="canvas-025.html"> ./demo/canvas-025.js </a> <a class="source" href="canvas-026.html"> ./demo/canvas-026.js </a> <a class="source" href="canvas-027.html"> ./demo/canvas-027.js </a> <a class="source" href="canvas-028.html"> ./demo/canvas-028.js </a> <a class="source" href="canvas-029.html"> ./demo/canvas-029.js </a> <a class="source" href="canvas-030.html"> ./demo/canvas-030.js </a> <a class="source" href="canvas-031.html"> ./demo/canvas-031.js </a> <a class="source" href="canvas-032.html"> ./demo/canvas-032.js </a> <a class="source" href="canvas-033.html"> ./demo/canvas-033.js </a> <a class="source" href="canvas-034.html"> ./demo/canvas-034.js </a> <a class="source" href="canvas-035.html"> ./demo/canvas-035.js </a> <a class="source" href="canvas-036.html"> ./demo/canvas-036.js </a> <a class="source" href="canvas-037.html"> ./demo/canvas-037.js </a> <a class="source" href="canvas-038.html"> ./demo/canvas-038.js </a> <a class="source" href="canvas-039.html"> ./demo/canvas-039.js </a> <a class="source" href="canvas-040.html"> ./demo/canvas-040.js </a> <a class="source" href="canvas-041.html"> ./demo/canvas-041.js </a> <a class="source" href="canvas-042.html"> ./demo/canvas-042.js </a> <a class="source" href="canvas-043.html"> ./demo/canvas-043.js </a> <a class="source" href="canvas-044.html"> ./demo/canvas-044.js </a> <a class="source" href="canvas-045.html"> ./demo/canvas-045.js </a> <a class="source" href="canvas-046.html"> ./demo/canvas-046.js </a> <a class="source" href="canvas-047.html"> ./demo/canvas-047.js </a> <a class="source" href="canvas-048.html"> ./demo/canvas-048.js </a> <a class="source" href="canvas-049.html"> ./demo/canvas-049.js </a> <a class="source" href="canvas-050.html"> ./demo/canvas-050.js </a> <a class="source" href="canvas-051.html"> ./demo/canvas-051.js </a> <a class="source" href="canvas-052.html"> ./demo/canvas-052.js </a> <a class="source" href="canvas-053.html"> ./demo/canvas-053.js </a> <a class="source" href="canvas-054.html"> ./demo/canvas-054.js </a> <a class="source" href="canvas-055.html"> ./demo/canvas-055.js </a> <a class="source" href="canvas-056.html"> ./demo/canvas-056.js </a> <a class="source" href="canvas-057.html"> ./demo/canvas-057.js </a> <a class="source" href="canvas-058.html"> ./demo/canvas-058.js </a> <a class="source" href="canvas-059.html"> ./demo/canvas-059.js </a> <a class="source" href="canvas-060.html"> ./demo/canvas-060.js </a> <a class="source" href="canvas-061.html"> ./demo/canvas-061.js </a> <a class="source" href="canvas-062.html"> ./demo/canvas-062.js </a> <a class="source" href="canvas-063.html"> ./demo/canvas-063.js </a> <a class="source" href="canvas-064.html"> ./demo/canvas-064.js </a> <a class="source" href="core-001.html"> ./demo/core-001.js </a> <a class="source" href="delaunator-001.html"> ./demo/delaunator-001.js </a> <a class="source" href="delaunator-002.html"> ./demo/delaunator-002.js </a> <a class="source" href="dom-001.html"> ./demo/dom-001.js </a> <a class="source" href="dom-002.html"> ./demo/dom-002.js </a> <a class="source" href="dom-003.html"> ./demo/dom-003.js </a> <a class="source" href="dom-004.html"> ./demo/dom-004.js </a> <a class="source" href="dom-005.html"> ./demo/dom-005.js </a> <a class="source" href="dom-006.html"> ./demo/dom-006.js </a> <a class="source" href="dom-007.html"> ./demo/dom-007.js </a> <a class="source" href="dom-008.html"> ./demo/dom-008.js </a> <a class="source" href="dom-009.html"> ./demo/dom-009.js </a> <a class="source" href="dom-010.html"> ./demo/dom-010.js </a> <a class="source" href="dom-011.html"> ./demo/dom-011.js </a> <a class="source" href="dom-012.html"> ./demo/dom-012.js </a> <a class="source" href="dom-013.html"> ./demo/dom-013.js </a> <a class="source" href="dom-015.html"> ./demo/dom-015.js </a> <a class="source" href="dom-016.html"> ./demo/dom-016.js </a> <a class="source" href="filters-001.html"> ./demo/filters-001.js </a> <a class="source" href="filters-002.html"> ./demo/filters-002.js </a> <a class="source" href="filters-002a.html"> ./demo/filters-002a.js </a> <a class="source" href="filters-003.html"> ./demo/filters-003.js </a> <a class="source" href="filters-004.html"> ./demo/filters-004.js </a> <a class="source" href="filters-005.html"> ./demo/filters-005.js </a> <a class="source" href="filters-006.html"> ./demo/filters-006.js </a> <a class="source" href="filters-007.html"> ./demo/filters-007.js </a> <a class="source" href="filters-008.html"> ./demo/filters-008.js </a> <a class="source" href="filters-009.html"> ./demo/filters-009.js </a> <a class="source" href="filters-010.html"> ./demo/filters-010.js </a> <a class="source" href="filters-011.html"> ./demo/filters-011.js </a> <a class="source" href="filters-012.html"> ./demo/filters-012.js </a> <a class="source" href="filters-013.html"> ./demo/filters-013.js </a> <a class="source" href="filters-014.html"> ./demo/filters-014.js </a> <a class="source" href="filters-015.html"> ./demo/filters-015.js </a> <a class="source" href="filters-016.html"> ./demo/filters-016.js </a> <a class="source" href="filters-017.html"> ./demo/filters-017.js </a> <a class="source" href="filters-018.html"> ./demo/filters-018.js </a> <a class="source" href="filters-019.html"> ./demo/filters-019.js </a> <a class="source" href="filters-020.html"> ./demo/filters-020.js </a> <a class="source" href="filters-021.html"> ./demo/filters-021.js </a> <a class="source" href="filters-022.html"> ./demo/filters-022.js </a> <a class="source" href="filters-023.html"> ./demo/filters-023.js </a> <a class="source" href="filters-024.html"> ./demo/filters-024.js </a> <a class="source" href="filters-025.html"> ./demo/filters-025.js </a> <a class="source" href="filters-026.html"> ./demo/filters-026.js </a> <a class="source" href="filters-027.html"> ./demo/filters-027.js </a> <a class="source" href="filters-101.html"> ./demo/filters-101.js </a> <a class="source" href="filters-102.html"> ./demo/filters-102.js </a> <a class="source" href="filters-103.html"> ./demo/filters-103.js </a> <a class="source" href="filters-104.html"> ./demo/filters-104.js </a> <a class="source" href="filters-105.html"> ./demo/filters-105.js </a> <a class="source" href="filters-501.html"> ./demo/filters-501.js </a> <a class="source" href="filters-502.html"> ./demo/filters-502.js </a> <a class="source" href="filters-503.html"> ./demo/filters-503.js </a> <a class="source" href="filters-504.html"> ./demo/filters-504.js </a> <a class="source" href="filters-505.html"> ./demo/filters-505.js </a> <a class="source" href="mediapipe-001.html"> ./demo/mediapipe-001.js </a> <a class="source" href="mediapipe-002.html"> ./demo/mediapipe-002.js </a> <a class="source" href="mediapipe-003.html"> ./demo/mediapipe-003.js </a> <a class="source" href="modules-001.html"> ./demo/modules-001.js </a> <a class="source" href="modules-002.html"> ./demo/modules-002.js </a> <a class="source" href="modules-003.html"> ./demo/modules-003.js </a> <a class="source" href="modules-004.html"> ./demo/modules-004.js </a> <a class="source" href="modules-005.html"> ./demo/modules-005.js </a> <a class="source" href="packets-001.html"> ./demo/packets-001.js </a> <a class="source" href="packets-002.html"> ./demo/packets-002.js </a> <a class="source" href="particles-001.html"> ./demo/particles-001.js </a> <a class="source" href="particles-002.html"> ./demo/particles-002.js </a> <a class="source" href="particles-003.html"> ./demo/particles-003.js </a> <a class="source" href="particles-004.html"> ./demo/particles-004.js </a> <a class="source" href="particles-005.html"> ./demo/particles-005.js </a> <a class="source" href="particles-006.html"> ./demo/particles-006.js </a> <a class="source" href="particles-007.html"> ./demo/particles-007.js </a> <a class="source" href="particles-008.html"> ./demo/particles-008.js </a> <a class="source" href="particles-009.html"> ./demo/particles-009.js </a> <a class="source" href="particles-010.html"> ./demo/particles-010.js </a> <a class="source" href="particles-011.html"> ./demo/particles-011.js </a> <a class="source" href="particles-012.html"> ./demo/particles-012.js </a> <a class="source" href="particles-013.html"> ./demo/particles-013.js </a> <a class="source" href="particles-014.html"> ./demo/particles-014.js </a> <a class="source" href="particles-015.html"> ./demo/particles-015.js </a> <a class="source" href="particles-016.html"> ./demo/particles-016.js </a> <a class="source" href="rapier-001.html"> ./demo/rapier-001.js </a> <a class="source" href="snippets-001.html"> ./demo/snippets-001.js </a> <a class="source" href="snippets-002.html"> ./demo/snippets-002.js </a> <a class="source" href="snippets-003.html"> ./demo/snippets-003.js </a> <a class="source" href="snippets-004.html"> ./demo/snippets-004.js </a> <a class="source" href="snippets-005.html"> ./demo/snippets-005.js </a> <a class="source" href="snippets-006.html"> ./demo/snippets-006.js </a> <a class="source" href="temp-000.html"> ./demo/temp-000.js </a> <a class="source" href="temp-001.html"> ./demo/temp-001.js </a> <a class="source" href="temp-001a.html"> ./demo/temp-001a.js </a> <a class="source" href="temp-002.html"> ./demo/temp-002.js </a> <a class="source" href="temp-003.html"> ./demo/temp-003.js </a> <a class="source" href="temp-004.html"> ./demo/temp-004.js </a> <a class="source" href="temp-005.html"> ./demo/temp-005.js </a> <a class="source" href="temp-006.html"> ./demo/temp-006.js </a> <a class="source" href="temp-007.html"> ./demo/temp-007.js </a> <a class="source" href="temp-008.html"> ./demo/temp-008.js </a> <a class="source" href="temp-009.html"> ./demo/temp-009.js </a> <a class="source" href="temp-010.html"> ./demo/temp-010.js </a> <a class="source" href="temp-011.html"> ./demo/temp-011.js </a> <a class="source" href="temp-012.html"> ./demo/temp-012.js </a> <a class="source" href="temp-013.html"> ./demo/temp-013.js </a> <a class="source" href="temp-014.html"> ./demo/temp-014.js </a> <a class="source" href="temp-015.html"> ./demo/temp-015.js </a> <a class="source" href="temp-016.html"> ./demo/temp-016.js </a> <a class="source" href="temp-017.html"> ./demo/temp-017.js </a> <a class="source" href="temp-018.html"> ./demo/temp-018.js </a> <a class="source" href="temp-018a.html"> ./demo/temp-018a.js </a> <a class="source" href="temp-019.html"> ./demo/temp-019.js </a> <a class="source" href="temp-020.html"> ./demo/temp-020.js </a> <a class="source" href="temp-021.html"> ./demo/temp-021.js </a> <a class="source" href="temp-022.html"> ./demo/temp-022.js </a> <a class="source" href="temp-023.html"> ./demo/temp-023.js </a> <a class="source" href="temp-024.html"> ./demo/temp-024.js </a> <a class="source" href="temp-025.html"> ./demo/temp-025.js </a> <a class="source" href="temp-026.html"> ./demo/temp-026.js </a> <a class="source" href="temp-027.html"> ./demo/temp-027.js </a> <a class="source" href="temp-028.html"> ./demo/temp-028.js </a> <a class="source" href="temp-029.html"> ./demo/temp-029.js </a> <a class="source" href="temp-030.html"> ./demo/temp-030.js </a> <a class="source" href="temp-031.html"> ./demo/temp-031.js </a> <a class="source" href="temp-032.html"> ./demo/temp-032.js </a> <a class="source" href="temp-033.html"> ./demo/temp-033.js </a> <a class="source" href="temp-034.html"> ./demo/temp-034.js </a> <a class="source" href="temp-035.html"> ./demo/temp-035.js </a> <a class="source" href="temp-036.html"> ./demo/temp-036.js </a> <a class="source" href="temp-037.html"> ./demo/temp-037.js </a> <a class="source" href="temp-100.html"> ./demo/temp-100.js </a> <a class="source" href="temp-101.html"> ./demo/temp-101.js </a> <a class="source" href="temp-102.html"> ./demo/temp-102.js </a> <a class="source" href="temp-103.html"> ./demo/temp-103.js </a> <a class="source" href="temp-104.html"> ./demo/temp-104.js </a> <a class="source" href="temp-200.html"> ./demo/temp-200.js </a> <a class="source" href="temp-201.html"> ./demo/temp-201.js </a> <a class="source" href="temp-301.html"> ./demo/temp-301.js </a> <a class="source" href="temp-inkscapeSvgFilters.html"> ./demo/temp-inkscapeSvgFilters.js </a> <a class="source" href="temp-lottie.html"> ./demo/temp-lottie.js </a> <a class="source" href="tensorflow-001.html"> ./demo/tensorflow-001.js </a> <a class="source" href="tensorflow-002.html"> ./demo/tensorflow-002.js </a> <a class="source" href="utilities.html"> ./demo/utilities.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="demo-canvas-037">Demo Canvas 037</h1> <p>Pan and zoom using a Picture entity</p> <p>Scrawl-canvas does not include built-in functionality to easily “zoom” (expand/contract the contents of) a &lt;canvas&gt; element. Nor does it include functionality to “pan” (move in any direction through the contents of) the canvas. The use cases for, and the user interactions for controlling, such functionality are too varied; any attempt to capture a particular approach within the library’s code base would necessarily make other, equally valid, approaches more problematic for developers to implement.</p> <p>The code in this demo demonstrates how to capture user actions in events, which can then be used to build a “zoom and pan” experience. The demo uses a Picture entity, because that entity <em>does</em> include functionality which prevents the entity from going beyond the borders of its image (or video) asset.</p> <p><a href="../../demo/canvas-037.html">Run code</a></p> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> scrawl <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../source/scrawl.js&#x27;</span>; <span class="hljs-keyword">import</span> { reportSpeed } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./utilities.js&#x27;</span>;</pre></div></div> </li> <li id="section-2"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-2">&#x00a7;</a> </div> <h4 id="scene-state">Scene state</h4> <p>Because we need to manually calculate the copy position and dimensions for the Picture entity, we need to create state to hold known values and record changes between user interactions</p> <ul> <li><code>naturalWidth/Height</code> - the image asset’s natural dimensions (fixed value)</li> <li><code>frameDimension</code> - the &lt;canvas&gt; element’s (non-responsive) dimension values</li> <li><code>scale</code> variables to track scale limits and value</li> <li><code>from</code> variables to track the copyStart coordinate</li> </ul> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">let</span> naturalWidth = <span class="hljs-number">4160</span>, naturalHeight = <span class="hljs-number">3120</span>, frameDimension = <span class="hljs-number">500</span>, maxScale = naturalHeight / frameDimension, currentScale = maxScale, minScale = <span class="hljs-number">1</span>, fromLeft = <span class="hljs-number">0</span>, fromTop = <span class="hljs-number">0</span>;</pre></div></div> </li> <li id="section-3"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-3">&#x00a7;</a> </div> <p>Convenience variables to access key Scrawl-canvas objects stored in the library</p> </div> <div class="content"><div class='highlight'><pre><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>, base = canvas.<span class="hljs-property">base</span>, baseGroup = scrawl.<span class="hljs-property">library</span>.<span class="hljs-property">group</span>[base.<span class="hljs-property">name</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="scene-setup">Scene setup</h4> </div> </li> <li id="section-5"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-5">&#x00a7;</a> </div> <p>The Picture entity will cover the entire displayed canvas</p> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">let</span> piccie = scrawl.<span class="hljs-title function_">makePicture</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;river-pic&#x27;</span>, <span class="hljs-attr">imageSource</span>: <span class="hljs-string">&#x27;./img/river.jpg&#x27;</span>, <span class="hljs-attr">width</span>: <span class="hljs-string">&#x27;100%&#x27;</span>, <span class="hljs-attr">height</span>: <span class="hljs-string">&#x27;100%&#x27;</span>, <span class="hljs-attr">copyWidth</span>: currentScale * frameDimension, <span class="hljs-attr">copyHeight</span>: currentScale * frameDimension, <span class="hljs-attr">copyStartX</span>: fromLeft, <span class="hljs-attr">copyStartY</span>: fromTop, });</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="scene-animation">Scene animation</h4> <p>Function to display frames-per-second data, and other information relevant to the demo</p> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">const</span> report = <span class="hljs-title function_">reportSpeed</span>(<span class="hljs-string">&#x27;#reportmessage&#x27;</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>Create the Display cycle animation</p> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">const</span> demoAnimation = scrawl.<span class="hljs-title function_">makeRender</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;demo-animation&quot;</span>, <span class="hljs-attr">target</span>: canvas, <span class="hljs-attr">afterShow</span>: report, });</pre></div></div> </li> <li id="section-8"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-8">&#x00a7;</a> </div> <h4 id="bespoke-user-interaction">Bespoke user interaction</h4> <p>We shall build the “zoom” and “pan” effects using event listeners.</p> <ul> <li>For the purposes of accessibility these events should be extended to include keyboard interactions</li> <li>Mobile devices should also include multitouch gestures - such activity is often best captured using a dedicated third party Javascript library, for example <a href="https://hammerjs.github.io/">hammer.js</a></li> </ul> <p>Zoom effect</p> </div> <div class="content"><div class='highlight'><pre>scrawl.<span class="hljs-title function_">addNativeListener</span>(<span class="hljs-string">&#x27;wheel&#x27;</span>, <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> { e.<span class="hljs-title function_">preventDefault</span>(); <span class="hljs-keyword">let</span> oldScale = currentScale, here = canvas.<span class="hljs-property">here</span>; currentScale += (e.<span class="hljs-property">deltaY</span> * -<span class="hljs-number">0.0005</span>); <span class="hljs-keyword">if</span> (currentScale &gt; maxScale) currentScale = maxScale; <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (currentScale &lt; minScale) currentScale = minScale; <span class="hljs-keyword">let</span> delta = (frameDimension * oldScale) - (frameDimension * currentScale); fromLeft += delta * here.<span class="hljs-property">normX</span>; fromTop += delta * here.<span class="hljs-property">normY</span>; piccie.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">copyWidth</span>: currentScale * frameDimension, <span class="hljs-attr">copyHeight</span>: currentScale * frameDimension, <span class="hljs-attr">copyStartX</span>: fromLeft, <span class="hljs-attr">copyStartY</span>: fromTop, }); }, canvas.<span class="hljs-property">domElement</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>Define some additional scene state, specifically for the “pan” effect</p> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">let</span> draggingArtefact = <span class="hljs-literal">false</span>, currentDragX = <span class="hljs-number">0</span>, currentDragY = <span class="hljs-number">0</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>Pan effect, split across three separate event listeners (starting, during, ending)</p> </div> <div class="content"><div class='highlight'><pre>scrawl.<span class="hljs-title function_">addListener</span>(<span class="hljs-string">&#x27;down&#x27;</span>, <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> { <span class="hljs-keyword">let</span> here = base.<span class="hljs-property">here</span>, target = baseGroup.<span class="hljs-title function_">getArtefactAt</span>(base.<span class="hljs-property">here</span>); draggingArtefact = (target &amp;&amp; target.<span class="hljs-property">artefact</span> &amp;&amp; target.<span class="hljs-property">artefact</span>.<span class="hljs-property">type</span> == <span class="hljs-string">&#x27;Picture&#x27;</span>) ? target.<span class="hljs-property">artefact</span> : <span class="hljs-literal">false</span>; <span class="hljs-keyword">if</span> (draggingArtefact) { currentDragX = here.<span class="hljs-property">x</span>; currentDragY = here.<span class="hljs-property">y</span>; } }, canvas.<span class="hljs-property">domElement</span>); scrawl.<span class="hljs-title function_">addListener</span>(<span class="hljs-string">&#x27;move&#x27;</span>, <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> { <span class="hljs-keyword">let</span> here = base.<span class="hljs-property">here</span>; <span class="hljs-keyword">if</span> (draggingArtefact) { fromLeft += (currentDragX - here.<span class="hljs-property">x</span>) * currentScale; fromTop += (currentDragY - here.<span class="hljs-property">y</span>) * currentScale; currentDragX = here.<span class="hljs-property">x</span>, currentDragY = here.<span class="hljs-property">y</span>; <span class="hljs-keyword">if</span> (fromLeft &lt; <span class="hljs-number">0</span>) fromLeft = <span class="hljs-number">0</span>; <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (fromLeft &gt; naturalWidth - frameDimension) fromLeft = naturalWidth - frameDimension; <span class="hljs-keyword">if</span> (fromTop &lt; <span class="hljs-number">0</span>) fromTop = <span class="hljs-number">0</span>; <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (fromTop &gt; naturalHeight - frameDimension) fromTop = naturalHeight - frameDimension; piccie.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">copyStartX</span>: fromLeft, <span class="hljs-attr">copyStartY</span>: fromTop, }); } }, canvas.<span class="hljs-property">domElement</span>); scrawl.<span class="hljs-title function_">addListener</span>([<span class="hljs-string">&#x27;up&#x27;</span>, <span class="hljs-string">&#x27;leave&#x27;</span>], <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> { draggingArtefact = <span class="hljs-literal">false</span>; currentDragX = <span class="hljs-number">0</span>; currentDragY = <span class="hljs-number">0</span>; }, canvas.<span class="hljs-property">domElement</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="development-and-testing">Development and testing</h4> </div> <div class="content"><div class='highlight'><pre><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(scrawl.<span class="hljs-property">library</span>);</pre></div></div> </li> </ul> </div> </body> </html>