UNPKG

scrawl-canvas

Version:
918 lines (620 loc) 87.3 kB
<!DOCTYPE html> <html> <head> <title>Demo Modules 005</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-minimap.html"> ./demo/modules/canvas-minimap.js </a> <a class="source" href="canvas-scene-editor.html"> ./demo/modules/canvas-scene-editor.js </a> <a class="source" href="dom-entity-editor.html"> ./demo/modules/dom-entity-editor.js </a> <a class="source" href="entity-copy-paste.html"> ./demo/modules/entity-copy-paste.js </a> <a class="source" href="entity-manipulation-gui.html"> ./demo/modules/entity-manipulation-gui.js </a> <a class="source" href="entity-navigation.html"> ./demo/modules/entity-navigation.js </a> <a class="source" href="entity-ring-builder.html"> ./demo/modules/entity-ring-builder.js </a> <a class="source" href="london-crime-graphic.html"> ./demo/modules/london-crime-graphic.js </a> <a class="source" href="london-crime-lines.html"> ./demo/modules/london-crime-lines.js </a> <a class="source" href="london-crime-stacked-bars.html"> ./demo/modules/london-crime-stacked-bars.js </a> <a class="source" href="lottie-loader.html"> ./demo/modules/lottie-loader.js </a> <a class="source" href="simple-chart-frame-tests.html"> ./demo/modules/simple-chart-frame-tests.js </a> <a class="source" href="simple-chart-frame.html"> ./demo/modules/simple-chart-frame.js </a> <a class="source" href="simple-graph-lines.html"> ./demo/modules/simple-graph-lines.js </a> <a class="source" href="simple-graph-stacked-bars.html"> ./demo/modules/simple-graph-stacked-bars.js </a> <a class="source" href="wikipedia-views-spiral-chart.html"> ./demo/modules/wikipedia-views-spiral-chart.js </a> <a class="source" href="../snippets/animated-highlight-gradient-text-snippet.html"> ./demo/snippets/animated-highlight-gradient-text-snippet.js </a> <a class="source" href="../snippets/animated-hover-gradient-snippet.html"> ./demo/snippets/animated-hover-gradient-snippet.js </a> <a class="source" href="../snippets/animated-word-gradient-snippet.html"> ./demo/snippets/animated-word-gradient-snippet.js </a> <a class="source" href="../snippets/before-after-slider-infographic.html"> ./demo/snippets/before-after-slider-infographic.js </a> <a class="source" href="../snippets/bubbles-text-snippet.html"> ./demo/snippets/bubbles-text-snippet.js </a> <a class="source" href="../snippets/green-box-snippet.html"> ./demo/snippets/green-box-snippet.js </a> <a class="source" href="../snippets/jazzy-button-snippet.html"> ./demo/snippets/jazzy-button-snippet.js </a> <a class="source" href="../snippets/page-performance-snippet-test.html"> ./demo/snippets/page-performance-snippet-test.js </a> <a class="source" href="../snippets/page-performance-snippet.html"> ./demo/snippets/page-performance-snippet.js </a> <a class="source" href="../snippets/pan-image-snippet.html"> ./demo/snippets/pan-image-snippet.js </a> <a class="source" href="../snippets/placeholder-effect-snippet.html"> ./demo/snippets/placeholder-effect-snippet.js </a> <a class="source" href="../snippets/ripple-effect-snippet.html"> ./demo/snippets/ripple-effect-snippet.js </a> <a class="source" href="../snippets/risograph-text-gradient-snippet.html"> ./demo/snippets/risograph-text-gradient-snippet.js </a> <a class="source" href="../snippets/spotlight-text-snippet-test.html"> ./demo/snippets/spotlight-text-snippet-test.js </a> <a class="source" href="../snippets/spotlight-text-snippet.html"> ./demo/snippets/spotlight-text-snippet.js </a> <a class="source" href="../snippets/swirling-stripes-text-snippet.html"> ./demo/snippets/swirling-stripes-text-snippet.js </a> <a class="source" href="../snippets/text-snippet-helper.html"> ./demo/snippets/text-snippet-helper.js </a> <a class="source" href="../snippets/word-highlighter-snippet.html"> ./demo/snippets/word-highlighter-snippet.js </a> <a class="source" href="../snippets/worley-text-gradient-snippet.html"> ./demo/snippets/worley-text-gradient-snippet.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-modules-005">Demo Modules 005</h1> <p>Accessible GUI-based simple canvas editor</p> <p>Related files:</p> <ul> <li><a href="../modules-005.html">Accessible GUI-based simple canvas editor - main demo</a></li> </ul> <h4 id="usage">Usage</h4> <p>This module creates a simple GUI control that appears when an entity, or a group of entitys, are selected. The control allows users to move, scale and rotate selected entitys. The control can be positioned in relation to the selected entitys using both drag, and keyboard, input. All the control’s actions can be replicated using the keyboard. The module adds the following zones to the supplied Canvas wrapper:</p> <ul> <li>Three GUI drag zones -one for each part of the control - to manipulate the GUI control (processingOrder: 50, 51, 52)</li> <li>A keyboard zone - to handle <code>alphanumeric</code> and <code>SHIFT + alphanumeric</code> input to position, scale and rotate selected entitys. A function is also exported to allow users to customise the alphanumeric key mappings</li> </ul> <p><strong>Inputs to the <code>initializeEntityManipulationGui</code> function</strong></p> <ul> <li><code>canvas</code> - SC canvas wrapper object (required)</li> <li><code>cell</code> - the scene Cell wrapper object, from the canvas-minimap module (required)</li> <li><code>selectedEntitys</code> - the selected entitys group, from the entity-navigation module (required)</li> <li><code>updateControllerDisplay</code> - an object containing functions to update the canvas element’s cursor appearance during hover and drag actions, from the entity-navigation module (required)</li> <li><code>dashboard</code> - an object containing DOM form functions, from the dom-entity-editor module (required)</li> </ul> <p><strong>Output from the <code>initializeEntityManipulationGui</code> function</strong> - is an object containing the following attributes:</p> <ul> <li><code>checkForSelectionUpdates</code> - a function to be added to an animation object elsewhere</li> <li><code>setGuiControlChars</code> - a function which allows users to adjust their keyboard mappings</li> <li><code>createGui</code> - the function to (re)create the GUI control</li> <li><code>killEntityManipulationGui</code> - kill function, to remove everything associated with the GUI control</li> </ul> </div> </li> <li id="section-2"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-2">&#x00a7;</a> </div> <h4 id="initialization-function-exported">Initialization function (exported)</h4> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">const</span> <span class="hljs-title function_">initializeEntityManipulationGui</span> = (<span class="hljs-params">items = {}, scrawl</span>) =&gt; {</pre></div></div> </li> <li id="section-3"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-3">&#x00a7;</a> </div> <p>Check we have required arguments/values</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">const</span> { canvas, cell, selectedEntitys, dashboard, updateControllerDisplay } = items; <span class="hljs-keyword">if</span> (scrawl == <span class="hljs-literal">null</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(<span class="hljs-string">&#x27;SC entity manipulation GUI module error: missing Scrawl-canvas object argument&#x27;</span>); <span class="hljs-keyword">let</span> argsCheck = <span class="hljs-string">&#x27;&#x27;</span>; <span class="hljs-keyword">if</span> (canvas == <span class="hljs-literal">null</span>) argsCheck += <span class="hljs-string">&#x27; Canvas wrapper;&#x27;</span>; <span class="hljs-keyword">if</span> (cell == <span class="hljs-literal">null</span>) argsCheck += <span class="hljs-string">&#x27; - Cell wrapper&#x27;</span>; <span class="hljs-keyword">if</span> (selectedEntitys == <span class="hljs-literal">null</span>) argsCheck += <span class="hljs-string">&#x27; - Selected entitys group&#x27;</span>; <span class="hljs-keyword">if</span> (updateControllerDisplay == <span class="hljs-literal">null</span>) argsCheck += <span class="hljs-string">&#x27; - Controllers display functions&#x27;</span>; <span class="hljs-keyword">if</span> (dashboard == <span class="hljs-literal">null</span>) argsCheck += <span class="hljs-string">&#x27; - DOM entity editor dashboard functionality&#x27;</span>; <span class="hljs-keyword">if</span> (argsCheck.<span class="hljs-property">length</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(<span class="hljs-string">`SC entity manipulation GUI module error: missing arguments<span class="hljs-subst">${argsCheck}</span>`</span>);</pre></div></div> </li> <li id="section-4"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-4">&#x00a7;</a> </div> <p>All GUI operations happen in their own cell group</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">const</span> gui = scrawl.<span class="hljs-title function_">makeGroup</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">`<span class="hljs-subst">${cell.name}</span>-gui-group`</span>, <span class="hljs-attr">host</span>: cell.<span class="hljs-property">name</span>, <span class="hljs-attr">order</span>: <span class="hljs-number">9999</span>, <span class="hljs-attr">visibility</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">checkForEntityHover</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">onEntityHover</span>: updateControllerDisplay.<span class="hljs-property">setCursorTo</span>.<span class="hljs-property">pointer</span>, <span class="hljs-attr">onEntityNoHover</span>: updateControllerDisplay.<span class="hljs-property">setCursorTo</span>.<span class="hljs-property">auto</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>Functions to switch the GUI display on/off</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">const</span> <span class="hljs-title function_">showGui</span> = (<span class="hljs-params"></span>) =&gt; { movePinGroup.<span class="hljs-title function_">addArtefacts</span>(moveControl); rotatePinGroup.<span class="hljs-title function_">addArtefacts</span>(rotateControl); scalePinGroup.<span class="hljs-title function_">addArtefacts</span>(scaleControl); gui.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">visibility</span>: <span class="hljs-literal">true</span>, }); }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">hideGui</span> = (<span class="hljs-params"></span>) =&gt; { gui.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">visibility</span>: <span class="hljs-literal">false</span>, }); };</pre></div></div> </li> <li id="section-6"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-6">&#x00a7;</a> </div> <p>We rebuild the GUI every time the user (un)selects entitys</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">let</span> moveControl, scaleControl, rotateControl; <span class="hljs-keyword">const</span> movePinGroup = scrawl.<span class="hljs-title function_">makeGroup</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;gui-control-drag-group&#x27;</span>, }); <span class="hljs-keyword">const</span> <span class="hljs-title function_">getGuiPinPosition</span> = (<span class="hljs-params"></span>) =&gt; { <span class="hljs-keyword">const</span> artefacts = selectedEntitys.<span class="hljs-property">artefacts</span>; <span class="hljs-keyword">if</span> (artefacts.<span class="hljs-property">length</span> === <span class="hljs-number">1</span>) { <span class="hljs-keyword">const</span> entity = selectedEntitys.<span class="hljs-title function_">getArtefact</span>(artefacts[<span class="hljs-number">0</span>]); <span class="hljs-keyword">return</span> entity.<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;position&#x27;</span>); } <span class="hljs-keyword">else</span> { <span class="hljs-keyword">let</span> [minX, minY] = cell.<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;dimensions&#x27;</span>); <span class="hljs-keyword">let</span> maxX = <span class="hljs-number">0</span>, maxY = <span class="hljs-number">0</span>; artefacts.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">name</span> =&gt;</span> { <span class="hljs-keyword">const</span> entity = selectedEntitys.<span class="hljs-title function_">getArtefact</span>(name); <span class="hljs-keyword">const</span> [x, y] = entity.<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;position&#x27;</span>); <span class="hljs-keyword">if</span> (minX &gt; x) minX = x; <span class="hljs-keyword">if</span> (minY &gt; y) minY = y; <span class="hljs-keyword">if</span> (maxX &lt; x) maxX = x; <span class="hljs-keyword">if</span> (maxY &lt; y) maxY = y; }); <span class="hljs-keyword">return</span> [ minX + ((maxX - minX) / <span class="hljs-number">2</span>), minY + ((maxY - minY) / <span class="hljs-number">2</span>), ]; } }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">createGui</span> = (<span class="hljs-params"></span>) =&gt; {</pre></div></div> </li> <li id="section-7"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-7">&#x00a7;</a> </div> <p>get rid of the old GUI entitys</p> </div> <div class="content"><div class='highlight'><pre> gui.<span class="hljs-title function_">killArtefacts</span>(); <span class="hljs-keyword">if</span> (!selectedEntitys.<span class="hljs-property">artefacts</span>.<span class="hljs-property">length</span>) <span class="hljs-title function_">hideGui</span>(); <span class="hljs-keyword">else</span> { <span class="hljs-keyword">const</span> pinPosition = <span class="hljs-title function_">getGuiPinPosition</span>(); moveControl = scrawl.<span class="hljs-title function_">makeWheel</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;gui-move-control&#x27;</span>, <span class="hljs-attr">group</span>: gui, <span class="hljs-attr">stampOrder</span>: <span class="hljs-number">20</span>, <span class="hljs-attr">radius</span>: <span class="hljs-number">22</span>, <span class="hljs-attr">start</span>: pinPosition, <span class="hljs-attr">handle</span>: [<span class="hljs-string">&#x27;center&#x27;</span>, <span class="hljs-string">&#x27;center&#x27;</span>], <span class="hljs-attr">fillStyle</span>: <span class="hljs-string">&#x27;white&#x27;</span>, <span class="hljs-attr">strokeStyle</span>: <span class="hljs-string">&#x27;red&#x27;</span>, <span class="hljs-attr">lineWidth</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">method</span>: <span class="hljs-string">&#x27;fillThenDraw&#x27;</span>, <span class="hljs-attr">bringToFrontOnDrag</span>: <span class="hljs-literal">false</span>, }); <span class="hljs-keyword">const</span> moveControlLabel = scrawl.<span class="hljs-title function_">makePhrase</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;gui-move-control-label&#x27;</span>, <span class="hljs-attr">group</span>: gui, <span class="hljs-attr">order</span>: <span class="hljs-number">21</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">&#x27;MOVE&#x27;</span>, <span class="hljs-attr">lineHeight</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">handle</span>: [<span class="hljs-string">&#x27;center&#x27;</span>, <span class="hljs-string">&#x27;center&#x27;</span>], <span class="hljs-attr">pivot</span>: moveControl, <span class="hljs-attr">lockTo</span>: <span class="hljs-string">&#x27;pivot&#x27;</span>, }); scaleControl = moveControl.<span class="hljs-title function_">clone</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;gui-scale-control&#x27;</span>, <span class="hljs-attr">calculateOrder</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">stampOrder</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">pivot</span>: moveControl, <span class="hljs-attr">lockTo</span>: <span class="hljs-string">&#x27;pivot&#x27;</span>, <span class="hljs-attr">offsetY</span>: -<span class="hljs-number">100</span>, }); moveControlLabel.<span class="hljs-title function_">clone</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;gui-scale-control-label&#x27;</span>, <span class="hljs-attr">order</span>: <span class="hljs-number">11</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">&#x27;SCALE&#x27;</span>, <span class="hljs-attr">pivot</span>: scaleControl, }); rotateControl = moveControl.<span class="hljs-title function_">clone</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;gui-rotate-control&#x27;</span>, <span class="hljs-attr">stampOrder</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">pivot</span>: moveControl, <span class="hljs-attr">lockTo</span>: <span class="hljs-string">&#x27;pivot&#x27;</span>, <span class="hljs-attr">offsetX</span>: <span class="hljs-number">100</span>, }); moveControlLabel.<span class="hljs-title function_">clone</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;gui-rotate-control-label&#x27;</span>, <span class="hljs-attr">order</span>: <span class="hljs-number">11</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">&#x27;ROLL&#x27;</span>, <span class="hljs-attr">pivot</span>: rotateControl, }); scrawl.<span class="hljs-title function_">makeLine</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;gui-scale-control-line&#x27;</span>, <span class="hljs-attr">group</span>: gui, <span class="hljs-attr">calculateOrder</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">method</span>: <span class="hljs-string">&#x27;draw&#x27;</span>, <span class="hljs-attr">strokeStyle</span>: <span class="hljs-string">&#x27;red&#x27;</span>, <span class="hljs-attr">lineWidth</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">pivot</span>: moveControl, <span class="hljs-attr">lockTo</span>: <span class="hljs-string">&#x27;pivot&#x27;</span>, <span class="hljs-attr">endPivot</span>: scaleControl, <span class="hljs-attr">endLockTo</span>: <span class="hljs-string">&#x27;pivot&#x27;</span>, <span class="hljs-attr">useStartAsControlPoint</span>: <span class="hljs-literal">true</span>, }).<span class="hljs-title function_">clone</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;gui-rotate-control-line&#x27;</span>, <span class="hljs-attr">endPivot</span>: rotateControl, }); <span class="hljs-title function_">createGuiStrings</span>(pinPosition); <span class="hljs-title function_">showGui</span>(); } }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">createGuiStrings</span> = (<span class="hljs-params">start</span>) =&gt; { selectedEntitys.<span class="hljs-property">artefacts</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">name</span> =&gt;</span> { scrawl.<span class="hljs-title function_">makeLine</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">`<span class="hljs-subst">${name}</span>-string`</span>, <span class="hljs-attr">group</span>: gui, <span class="hljs-attr">calculateOrder</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">method</span>: <span class="hljs-string">&#x27;draw&#x27;</span>, <span class="hljs-attr">strokeStyle</span>: <span class="hljs-string">&#x27;red&#x27;</span>, start, <span class="hljs-attr">pivot</span>: moveControl, <span class="hljs-attr">lockTo</span>: <span class="hljs-string">&#x27;pivot&#x27;</span>, <span class="hljs-attr">endPivot</span>: name, <span class="hljs-attr">endLockTo</span>: <span class="hljs-string">&#x27;pivot&#x27;</span>, <span class="hljs-attr">useStartAsControlPoint</span>: <span class="hljs-literal">true</span>, }); scrawl.<span class="hljs-title function_">makeWheel</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">`<span class="hljs-subst">${name}</span>-pin`</span>, <span class="hljs-attr">group</span>: gui, <span class="hljs-attr">pivot</span>: name, <span class="hljs-attr">lockTo</span>: <span class="hljs-string">&#x27;pivot&#x27;</span>, <span class="hljs-attr">handle</span>: [<span class="hljs-string">&#x27;center&#x27;</span>, <span class="hljs-string">&#x27;center&#x27;</span>], <span class="hljs-attr">radius</span>: <span class="hljs-number">5</span>, <span class="hljs-attr">fillStyle</span>: <span class="hljs-string">&#x27;white&#x27;</span>, <span class="hljs-attr">strokeStyle</span>: <span class="hljs-string">&#x27;red&#x27;</span>, <span class="hljs-attr">method</span>: <span class="hljs-string">&#x27;fillThenDraw&#x27;</span>, }); }); }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">restorePinDisplay</span> = (<span class="hljs-params">pin</span>) =&gt; { pin.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">fillStyle</span>: <span class="hljs-string">&#x27;white&#x27;</span>, }); }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">setPinDisplayForMove</span> = (<span class="hljs-params">pin</span>) =&gt; { pin.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">fillStyle</span>: <span class="hljs-string">&#x27;#bfb&#x27;</span>, }); }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">setPinDisplayForGroup</span> = (<span class="hljs-params">pin</span>) =&gt; { pin.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">fillStyle</span>: <span class="hljs-string">&#x27;#fbb&#x27;</span>, }); }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">setPinDisplayForEntity</span> = (<span class="hljs-params">pin</span>) =&gt; { pin.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">fillStyle</span>: <span class="hljs-string">&#x27;#bbf&#x27;</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>Functions common to the following code</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">let</span> centerPosition; <span class="hljs-keyword">const</span> <span class="hljs-title function_">getCenterPosition</span> = (<span class="hljs-params"></span>) =&gt; centerPosition = moveControl.<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;position&#x27;</span>); <span class="hljs-keyword">let</span> pinStartPosition, pinStartDistance; <span class="hljs-keyword">const</span> <span class="hljs-title function_">getPinStartPosition</span> = (<span class="hljs-params">pin</span>) =&gt; { <span class="hljs-keyword">const</span> coord = scrawl.<span class="hljs-title function_">requestCoordinate</span>(); <span class="hljs-title function_">getCenterPosition</span>(); pinStartPosition = pin.<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;position&#x27;</span>); pinStartDistance = coord.<span class="hljs-title function_">setFromArray</span>(pinStartPosition).<span class="hljs-title function_">subtract</span>(centerPosition).<span class="hljs-title function_">getMagnitude</span>(); scrawl.<span class="hljs-title function_">releaseCoordinate</span>(coord); }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">enqueueDashboardUpdates</span> = (<span class="hljs-params"></span>) =&gt; { <span class="hljs-keyword">if</span> (selectedEntitys.<span class="hljs-property">artefacts</span>.<span class="hljs-property">length</span> === <span class="hljs-number">1</span>) { <span class="hljs-keyword">const</span> name = selectedEntitys.<span class="hljs-property">artefacts</span>[<span class="hljs-number">0</span>]; <span class="hljs-keyword">const</span> artefact = selectedEntitys.<span class="hljs-title function_">getArtefact</span>(name); <span class="hljs-keyword">const</span> [startX, startY] = artefact.<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;start&#x27;</span>); dashboard.<span class="hljs-property">queue</span>.<span class="hljs-title function_">push</span>({ <span class="hljs-attr">startX</span>: <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">round</span>(startX), <span class="hljs-attr">startY</span>: <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">round</span>(startY), <span class="hljs-attr">scale</span>: <span class="hljs-built_in">parseFloat</span>(artefact.<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;scale&#x27;</span>).<span class="hljs-title function_">toFixed</span>(<span class="hljs-number">4</span>)), <span class="hljs-attr">roll</span>: artefact.<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;roll&#x27;</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>MOVE pin’s drag-drop functionality </p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">const</span> <span class="hljs-title function_">startMove</span> = (<span class="hljs-params"></span>) =&gt; { updateControllerDisplay.<span class="hljs-title function_">onStart</span>(); <span class="hljs-title function_">setPinDisplayForMove</span>(moveControl); }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">whileMoveGroup</span> = (<span class="hljs-params">e</span>) =&gt; { selectedEntitys.<span class="hljs-title function_">updateArtefacts</span>({ <span class="hljs-attr">startX</span>: e.<span class="hljs-property">movementX</span>, <span class="hljs-attr">startY</span>: e.<span class="hljs-property">movementY</span>, }); }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">endMove</span> = (<span class="hljs-params"></span>) =&gt; { updateControllerDisplay.<span class="hljs-title function_">onEnd</span>(); <span class="hljs-title function_">restorePinDisplay</span>(moveControl); <span class="hljs-title function_">enqueueDashboardUpdates</span>(); }; <span class="hljs-keyword">const</span> movePinDragZone = scrawl.<span class="hljs-title function_">makeDragZone</span>({ <span class="hljs-attr">zone</span>: canvas, <span class="hljs-attr">coordinateSource</span>: cell, <span class="hljs-attr">collisionGroup</span>: movePinGroup, <span class="hljs-attr">endOn</span>: [<span class="hljs-string">&#x27;up&#x27;</span>, <span class="hljs-string">&#x27;leave&#x27;</span>], <span class="hljs-attr">preventTouchDefaultWhenDragging</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">updateOnStart</span>: startMove, <span class="hljs-attr">updateWhileMoving</span>: whileMoveGroup, <span class="hljs-attr">updateWhileShiftMoving</span>: <span class="hljs-function">() =&gt;</span> {}, <span class="hljs-attr">updateOnEnd</span>: endMove, <span class="hljs-attr">processingOrder</span>: <span class="hljs-number">50</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>ROLL pin’s drag-drop functionality </p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">const</span> rotatePinGroup = scrawl.<span class="hljs-title function_">makeGroup</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">`<span class="hljs-subst">${cell.name}</span>-gui-rotate-group`</span>, }); <span class="hljs-keyword">let</span> rotatingWithShift = <span class="hljs-literal">false</span>; <span class="hljs-keyword">let</span> rotateStartValues; <span class="hljs-keyword">const</span> radToDeg = <span class="hljs-number">180</span> / <span class="hljs-title class_">Math</span>.<span class="hljs-property">PI</span>; <span class="hljs-keyword">const</span> degToRad = <span class="hljs-title class_">Math</span>.<span class="hljs-property">PI</span> / <span class="hljs-number">180</span>; <span class="hljs-keyword">const</span> <span class="hljs-title function_">calculateAngle</span> = (<span class="hljs-params"></span>) =&gt; { <span class="hljs-keyword">const</span> coord = scrawl.<span class="hljs-title function_">requestCoordinate</span>(); <span class="hljs-keyword">const</span> currentPinPosition = rotateControl.<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;position&#x27;</span>); <span class="hljs-keyword">const</span> currentPinDistance = coord.<span class="hljs-title function_">setFromArray</span>(currentPinPosition).<span class="hljs-title function_">subtract</span>(centerPosition).<span class="hljs-title function_">getMagnitude</span>(); <span class="hljs-keyword">const</span> pinMoveDistance = coord.<span class="hljs-title function_">setFromArray</span>(currentPinPosition).<span class="hljs-title function_">subtract</span>(pinStartPosition).<span class="hljs-title function_">getMagnitude</span>(); <span class="hljs-keyword">const</span> isAbove = currentPinPosition[<span class="hljs-number">1</span>] &gt; centerPosition[<span class="hljs-number">1</span>]; <span class="hljs-keyword">const</span> angle = <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">acos</span>(((currentPinDistance * currentPinDistance) + (pinStartDistance * pinStartDistance) - (pinMoveDistance * pinMoveDistance)) / (<span class="hljs-number">2</span> * currentPinDistance * pinStartDistance)) * radToDeg; scrawl.<span class="hljs-title function_">releaseCoordinate</span>(coord); <span class="hljs-keyword">if</span> (isAbove) <span class="hljs-keyword">return</span> <span class="hljs-number">360</span> - angle; <span class="hljs-keyword">return</span> angle; }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">getRotateEntityStartValues</span> = (<span class="hljs-params"></span>) =&gt; { rotateStartValues = {}; selectedEntitys.<span class="hljs-property">artefacts</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">name</span> =&gt;</span> { rotateStartValues[name] = selectedEntitys.<span class="hljs-title function_">getArtefact</span>(name).<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;roll&#x27;</span>); }); }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">startRotateEntity</span> = (<span class="hljs-params"></span>) =&gt; { rotatingWithShift = <span class="hljs-literal">false</span>; updateControllerDisplay.<span class="hljs-title function_">onStart</span>(); <span class="hljs-title function_">setPinDisplayForEntity</span>(rotateControl); <span class="hljs-title function_">getCenterPosition</span>(); <span class="hljs-title function_">getPinStartPosition</span>(rotateControl); <span class="hljs-title function_">getRotateEntityStartValues</span>(); }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">whileRotateEntity</span> = (<span class="hljs-params"></span>) =&gt; { <span class="hljs-keyword">if</span> (rotatingWithShift) <span class="hljs-title function_">whileRotateGroup</span>(); <span class="hljs-keyword">else</span> { <span class="hljs-keyword">const</span> angle = <span class="hljs-title function_">calculateAngle</span>(); selectedEntitys.<span class="hljs-property">artefacts</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">name</span> =&gt;</span> { <span class="hljs-keyword">let</span> roll = rotateStartValues[name] - angle; <span class="hljs-keyword">while</span> (roll &lt; <span class="hljs-number">0</span>) { roll += <span class="hljs-number">360</span>; } <span class="hljs-keyword">while</span> (roll &gt; <span class="hljs-number">360</span>) { roll -= <span class="hljs-number">360</span>; } selectedEntitys.<span class="hljs-title function_">getArtefact</span>(name).<span class="hljs-title function_">set</span>({ roll, }); }); } }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">endRotateEntity</span> = (<span class="hljs-params"></span>) =&gt; { rotatingWithShift = <span class="hljs-literal">false</span>; updateControllerDisplay.<span class="hljs-title function_">onEnd</span>(); <span class="hljs-title function_">restorePinDisplay</span>(rotateControl); <span class="hljs-title function_">enqueueDashboardUpdates</span>(); }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">getRotateGroupStartValues</span> = (<span class="hljs-params"></span>) =&gt; { rotateStartValues = {}; <span class="hljs-keyword">const</span> coord = scrawl.<span class="hljs-title function_">requestCoordinate</span>(); selectedEntitys.<span class="hljs-property">artefacts</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">name</span> =&gt;</span> { <span class="hljs-keyword">const</span> artefact = selectedEntitys.<span class="hljs-title function_">getArtefact</span>(name); <span class="hljs-keyword">const</span> pos = artefact.<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;position&#x27;</span>); rotateStartValues[name] = { <span class="hljs-attr">position</span>: [...coord.<span class="hljs-title function_">setFromArray</span>(pos).<span class="hljs-title function_">subtract</span>(centerPosition)], <span class="hljs-attr">roll</span>: artefact.<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;roll&#x27;</span>), }; }); scrawl.<span class="hljs-title function_">releaseCoordinate</span>(coord); }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">startRotateGroup</span> = (<span class="hljs-params"></span>) =&gt; { rotatingWithShift = <span class="hljs-literal">true</span>; updateControllerDisplay.<span class="hljs-title function_">onStart</span>(); <span class="hljs-title function_">setPinDisplayForGroup</span>(rotateControl); <span class="hljs-title function_">getCenterPosition</span>(); <span class="hljs-title function_">getPinStartPosition</span>(rotateControl); <span class="hljs-title function_">getRotateGroupStartValues</span>(); }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">whileRotateGroup</span> = (<span class="hljs-params"></span>) =&gt; { <span class="hljs-keyword">if</span> (!rotatingWithShift) <span class="hljs-title function_">whileRotateEntity</span>(); <span class="hljs-keyword">else</span> { <span class="hljs-keyword">const</span> angle = <span class="hljs-title function_">calculateAngle</span>(); <span class="hljs-keyword">const</span> coord = scrawl.<span class="hljs-title function_">requestCoordinate</span>(); selectedEntitys.<span class="hljs-property">artefacts</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">name</span> =&gt;</span> { <span class="hljs-keyword">const</span> artefactValues = rotateStartValues[name]; coord.<span class="hljs-title function_">setFromArray</span>(artefactValues.<span class="hljs-property">position</span>).<span class="hljs-title function_">rotate</span>(-angle).<span class="hljs-title function_">add</span>(centerPosition); <span class="hljs-keyword">let</span> roll = artefactValues.<span class="hljs-property">roll</span> - angle; <span class="hljs-keyword">while</span> (roll &lt; <span class="hljs-number">0</span>) { roll += <span class="hljs-number">360</span>; } <span class="hljs-keyword">while</span> (roll &gt; <span class="hljs-number">360</span>) { roll -= <span class="hljs-number">360</span>; } selectedEntitys.<span class="hljs-title function_">getArtefact</span>(name).<span class="hljs-title function_">set</span>({ <span class="hljs-attr">start</span>: [...coord], roll, }); }); scrawl.<span class="hljs-title function_">releaseCoordinate</span>(coord); } }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">endRotateGroup</span> = (<span class="hljs-params"></span>) =&gt; { rotatingWithShift = <span class="hljs-literal">false</span>; updateControllerDisplay.<span class="hljs-title function_">onEnd</span>(); <span class="hljs-title function_">restorePinDisplay</span>(rotateControl); <span class="hljs-title function_">enqueueDashboardUpdates</span>(); }; <span class="hljs-keyword">const</span> rotatePinDragZone = scrawl.<span class="hljs-title function_">makeDragZone</span>({ <span class="hljs-attr">zone</span>: canvas, <span class="hljs-attr">coordinateSource</span>: cell, <span class="hljs-attr">collisionGroup</span>: rotatePinGroup, <span class="hljs-attr">endOn</span>: [<span class="hljs-string">&#x27;up&#x27;</span>, <span class="hljs-string">&#x27;leave&#x27;</span>], <span class="hljs-attr">preventTouchDefaultWhenDragging</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">updateOnShiftStart</span>: startRotateEntity, <span class="hljs-attr">updateOnStart</span>: startRotateGroup, <span class="hljs-attr">updateWhileShiftMoving</span>: whileRotateEntity, <span class="hljs-attr">updateWhileMoving</span>: whileRotateGroup, <span class="hljs-attr">updateOnShiftEnd</span>: endRotateEntity, <span class="hljs-attr">updateOnEnd</span>: endRotateGroup, <span class="hljs-attr">processingOrder</span>: <span class="hljs-number">51</span>, });</pre></div></div> </li> <li id="section-11"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-11">&#x00a7;</a> </div> <p>SCALE pin’s drag-drop functionality </p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">const</span> scalePinGroup = scrawl.<span class="hljs-title function_">makeGroup</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">`<span class="hljs-subst">${cell.name}</span>-gui-scale-group`</span>, }); <span class="hljs-keyword">let</span> scalingWithShift = <span class="hljs-literal">false</span>; <span class="hljs-keyword">let</span> scaleStartValues; <span class="hljs-keyword">const</span> <span class="hljs-title function_">getScaleRatio</span> = (<span class="hljs-params"></span>) =&gt; { <span class="hljs-keyword">const</span> coord = scrawl.<span class="hljs-title function_">requestCoordinate</span>(); <span class="hljs-keyword">const</span> currentPinPosition = scaleControl.<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;position&#x27;</span>); <span class="hljs-keyword">const</span> currentDistance = coord.<span class="hljs-title function_">setFromArray</span>(currentPinPosition).<span class="hljs-title function_">subtract</span>(centerPosition).<span class="hljs-title function_">getMagnitude</span>(); scrawl.<span class="hljs-title function_">releaseCoordinate</span>(coord); <span class="hljs-keyword">return</span> currentDistance / pinStartDistance; }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">getScaleEntityStartValues</span> = (<span class="hljs-params"></span>) =&gt; { scaleStartValues = {}; selectedEntitys.<span class="hljs-property">artefacts</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">name</span> =&gt;</span> { scaleStartValues[name] = selectedEntitys.<span class="hljs-title function_">getArtefact</span>(name).<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;scale&#x27;</span>); }); }; <span class="hljs-keyword">const</span> <span class="hljs-title function_">startScaleEntity</span> = (<span class="hljs-params"></span>) =&gt; { scalingWithShift = <span class="hljs-literal">false</span>; updateControllerDisplay.<span class="hljs-title function_">onStart</span>(); <span class="hljs-title function_">setPinDisplayForEntity</span>(scaleControl); <span class="h