UNPKG

scrawl-canvas

Version:
986 lines (667 loc) 103 kB
<!DOCTYPE html> <html> <head> <title>Demo Snippets 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="../modules/canvas-minimap.html"> ./demo/modules/canvas-minimap.js </a> <a class="source" href="../modules/canvas-scene-editor.html"> ./demo/modules/canvas-scene-editor.js </a> <a class="source" href="../modules/dom-entity-editor.html"> ./demo/modules/dom-entity-editor.js </a> <a class="source" href="../modules/entity-copy-paste.html"> ./demo/modules/entity-copy-paste.js </a> <a class="source" href="../modules/entity-manipulation-gui.html"> ./demo/modules/entity-manipulation-gui.js </a> <a class="source" href="../modules/entity-navigation.html"> ./demo/modules/entity-navigation.js </a> <a class="source" href="../modules/entity-ring-builder.html"> ./demo/modules/entity-ring-builder.js </a> <a class="source" href="../modules/london-crime-graphic.html"> ./demo/modules/london-crime-graphic.js </a> <a class="source" href="../modules/london-crime-lines.html"> ./demo/modules/london-crime-lines.js </a> <a class="source" href="../modules/london-crime-stacked-bars.html"> ./demo/modules/london-crime-stacked-bars.js </a> <a class="source" href="../modules/lottie-loader.html"> ./demo/modules/lottie-loader.js </a> <a class="source" href="../modules/simple-chart-frame-tests.html"> ./demo/modules/simple-chart-frame-tests.js </a> <a class="source" href="../modules/simple-chart-frame.html"> ./demo/modules/simple-chart-frame.js </a> <a class="source" href="../modules/simple-graph-lines.html"> ./demo/modules/simple-graph-lines.js </a> <a class="source" href="../modules/simple-graph-stacked-bars.html"> ./demo/modules/simple-graph-stacked-bars.js </a> <a class="source" href="../modules/wikipedia-views-spiral-chart.html"> ./demo/modules/wikipedia-views-spiral-chart.js </a> <a class="source" href="animated-highlight-gradient-text-snippet.html"> ./demo/snippets/animated-highlight-gradient-text-snippet.js </a> <a class="source" href="animated-hover-gradient-snippet.html"> ./demo/snippets/animated-hover-gradient-snippet.js </a> <a class="source" href="animated-word-gradient-snippet.html"> ./demo/snippets/animated-word-gradient-snippet.js </a> <a class="source" href="before-after-slider-infographic.html"> ./demo/snippets/before-after-slider-infographic.js </a> <a class="source" href="bubbles-text-snippet.html"> ./demo/snippets/bubbles-text-snippet.js </a> <a class="source" href="green-box-snippet.html"> ./demo/snippets/green-box-snippet.js </a> <a class="source" href="jazzy-button-snippet.html"> ./demo/snippets/jazzy-button-snippet.js </a> <a class="source" href="page-performance-snippet-test.html"> ./demo/snippets/page-performance-snippet-test.js </a> <a class="source" href="page-performance-snippet.html"> ./demo/snippets/page-performance-snippet.js </a> <a class="source" href="pan-image-snippet.html"> ./demo/snippets/pan-image-snippet.js </a> <a class="source" href="placeholder-effect-snippet.html"> ./demo/snippets/placeholder-effect-snippet.js </a> <a class="source" href="ripple-effect-snippet.html"> ./demo/snippets/ripple-effect-snippet.js </a> <a class="source" href="risograph-text-gradient-snippet.html"> ./demo/snippets/risograph-text-gradient-snippet.js </a> <a class="source" href="spotlight-text-snippet-test.html"> ./demo/snippets/spotlight-text-snippet-test.js </a> <a class="source" href="spotlight-text-snippet.html"> ./demo/snippets/spotlight-text-snippet.js </a> <a class="source" href="swirling-stripes-text-snippet.html"> ./demo/snippets/swirling-stripes-text-snippet.js </a> <a class="source" href="text-snippet-helper.html"> ./demo/snippets/text-snippet-helper.js </a> <a class="source" href="word-highlighter-snippet.html"> ./demo/snippets/word-highlighter-snippet.js </a> <a class="source" href="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-snippets-005">Demo Snippets 005</h1> <p>Create a responsive, interactive and accessible before/after slider infographic</p> <p>Related files:</p> <ul> <li><a href="../snippets-005.html">Slider infographic snippet - main module</a></li> </ul> </div> </li> <li id="section-2"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-2">&#x00a7;</a> </div> <h3 id="before-after-slider-infographic-snippet">‘Before-after slider infographic’ snippet</h3> <p><strong>Purpose:</strong> Turn a pair of images, alongside associated data, into a fully responsive, interactive and accessible before-after slider infographic</p> <p>Note that this is a highly complex snippet, which relies on recieving an element to process in a very specific format containing a number of required child elements. All elements are expected to have various specified data- attributes which are used to build the infographic.</p> <p><strong>Function input:</strong> </p> <pre><code>&lt;div id=<span class="hljs-string">&quot;infographic-unique name&quot;</span> <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;some-class-name&quot;</span> data-label=<span class="hljs-string">&quot;Infographic title - required for accessibility&quot;</span> data-description=<span class="hljs-string">&quot;Infographic description - required for accessibility&quot;</span>&gt; <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;left-panel-unique-name&quot;</span> <span class="hljs-attr">data-date</span>=<span class="hljs-string">&quot;date of image&quot;</span> <span class="hljs-attr">data-frame</span>=<span class="hljs-string">&quot;left&quot;</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;left-panel-image-unique-name&quot;</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">&quot;Alternative text for image - required for accessibility&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;path/to/image/url&quot;</span> /&gt;</span> <span class="hljs-comment">&lt;!-- Each &amp;lt;p&gt; element needs an id value together with some data- attributes - data-type=&quot;pin&quot; - required (no default value) - for proof of concept we&#x27;re only handling spot pins, not area pins - data-position - required (no default value) - a string of two percentage values, separated by a comma - these are the &#x27;x%, y%&#x27; coords where the pin will appear on image - data-fill - pin fill color - default is &quot;red&quot; - data-stroke - pin stroke color - default is &quot;yellow&quot; - data-labelwidth - percentage label width value - default is &quot;20%&quot; - data-labelbackground - default is &quot;rgba(0,0,0,0.2)&quot; - data-labelposition - default is &quot;below&quot; - where we want the text to appear relative to the pin&#x27;s location - acceptable values: &quot;left&quot;, &quot;right&quot;, &quot;above&quot;, &quot;below&quot; - data-shared - default is not included - if included, we create the pin on both panels The text in the &lt;p&gt; element is the text that will be used for the pin&#x27;s label. Note that the snippet has been set up to interpret and display the following inline markup: - &lt;b&gt;&lt;/b&gt;, &lt;strong&gt;&lt;/strong&gt;, &lt;i&gt;&lt;/i&gt;, &lt;em&gt;&lt;/em&gt; - &lt;span class=&quot;sc-red&quot;&gt;&lt;/span&gt;, etc --&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;pin-unique-id&quot;</span> <span class="hljs-attr">data-type</span>=<span class="hljs-string">&quot;pin&quot;</span> <span class="hljs-attr">data-position</span>=<span class="hljs-string">&quot;59%, 21%&quot;</span> <span class="hljs-attr">data-fill</span>=<span class="hljs-string">&quot;blue&quot;</span>, <span class="hljs-attr">data-stroke</span>=<span class="hljs-string">&quot;yellow&quot;</span>, <span class="hljs-attr">data-labelwidth</span>=<span class="hljs-string">&quot;30%&quot;</span> <span class="hljs-attr">data-labelposition</span>=<span class="hljs-string">&quot;left&quot;</span> <span class="hljs-attr">data-labelbackground</span>=<span class="hljs-string">&quot;azure&quot;</span> <span class="hljs-attr">data-shared</span>&gt;</span>Text <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;sc-red&quot;</span>&gt;</span>appears<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> when user <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>hovers<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span> over pin<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;right-panel-unique-name&quot;</span> <span class="hljs-attr">data-date</span>=<span class="hljs-string">&quot;date of image&quot;</span> <span class="hljs-attr">data-frame</span>=<span class="hljs-string">&quot;right&quot;</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;right-panel-image-unique-name&quot;</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">&quot;Alternative text for image - required for accessibility&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;path/to/image/url&quot;</span> /&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>...Pin definitions<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> <span class="hljs-comment">&lt;!-- If we also want to include any clickable links in the infographic, we can include them in a &amp;lt;nav&gt; element - data-position - required (no default value) - a string of two percentage values, separated by a comma - these are the &#x27;x%, y%&#x27; coords where the link will appear over image - data-justify - one of: &quot;left&quot;, &quot;right&quot;, &quot;center&quot; (default) - data-width - defaults to &quot;20%&quot; - data-background - defaults to &quot;rgba(0,0,0,0.2)&quot; --&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">nav</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;link-unique-id&quot;</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;https://absolute/link/url&quot;</span> <span class="hljs-attr">data-position</span>=<span class="hljs-string">&quot;1%, 95%&quot;</span> <span class="hljs-attr">data-width</span>=<span class="hljs-string">&quot;45%&quot;</span> <span class="hljs-attr">data-justify</span>=<span class="hljs-string">&quot;left&quot;</span>&gt;</span>Text to include in the link<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;another-link-unique-id&quot;</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;relative/link/url&quot;</span> <span class="hljs-attr">data-position</span>=<span class="hljs-string">&quot;99%, 95%&quot;</span> <span class="hljs-attr">data-width</span>=<span class="hljs-string">&quot;45%&quot;</span> <span class="hljs-attr">data-background</span>=<span class="hljs-string">&quot;darkblue&quot;</span> <span class="hljs-attr">data-justify</span>=<span class="hljs-string">&quot;right&quot;</span>&gt;</span>Different text for different link<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span> </code></pre> </div> </li> <li id="section-3"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-3">&#x00a7;</a> </div> <h5 id="usage-example">Usage example:</h5> <pre><code><span class="hljs-keyword">import</span> slider <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./relative/or/absolute/path/to/this/file.js&#x27;</span>; <span class="hljs-keyword">let</span> myElements = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelectorAll</span>(<span class="hljs-string">&#x27;.some-class-name&#x27;</span>); myElements.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">el</span> =&gt;</span> <span class="hljs-title function_">slider</span>(el)); </code></pre> <p>Note that this snippet has a profound effect on the element it processes, moving images inside a canvas element and deleting most of the child elements (to prevent copy repetition for screen readers)</p> <p><strong>Function output:</strong> </p> <pre><code>{ element <span class="hljs-comment">// wrapper</span> canvas <span class="hljs-comment">// wrapper</span> animation <span class="hljs-comment">// object</span> demolish <span class="hljs-comment">// function</span> } </code></pre> <h3 id="snippet-code">Snippet code</h3> <p>Import the Scrawl-canvas object </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></pre></div></div> </li> <li id="section-4"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-4">&#x00a7;</a> </div> <p>Internal function to scrape data from the supplied element </p> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">const</span> getPanelData = <span class="hljs-keyword">function</span> (<span class="hljs-params">el, store, canvas</span>) { <span class="hljs-keyword">if</span> (!el) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; <span class="hljs-keyword">const</span> img = el.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&#x27;img&#x27;</span>); store.<span class="hljs-property">element</span> = el; store.<span class="hljs-property">name</span> = el.<span class="hljs-property">id</span>; store.<span class="hljs-property">date</span> = el.<span class="hljs-property">dataset</span>.<span class="hljs-property">date</span>; store.<span class="hljs-property">imageElement</span> = img; store.<span class="hljs-property">pinElements</span> = el.<span class="hljs-title function_">querySelectorAll</span>(<span class="hljs-string">&#x27;p&#x27;</span>); store.<span class="hljs-property">pins</span> = []; store.<span class="hljs-property">pinElements</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">p</span> =&gt;</span> { store.<span class="hljs-property">pins</span>.<span class="hljs-title function_">push</span>({ <span class="hljs-attr">name</span>: p.<span class="hljs-property">id</span>, <span class="hljs-attr">groupname</span>: store.<span class="hljs-property">name</span>, <span class="hljs-attr">type</span>: p.<span class="hljs-property">dataset</span>.<span class="hljs-property">type</span>, <span class="hljs-attr">position</span>: p.<span class="hljs-property">dataset</span>.<span class="hljs-property">position</span>, <span class="hljs-attr">fill</span>: p.<span class="hljs-property">dataset</span>.<span class="hljs-property">fill</span> || <span class="hljs-string">&#x27;red&#x27;</span>, <span class="hljs-attr">stroke</span>: p.<span class="hljs-property">dataset</span>.<span class="hljs-property">stroke</span> || <span class="hljs-string">&#x27;yellow&#x27;</span>, <span class="hljs-attr">labelposition</span>: p.<span class="hljs-property">dataset</span>.<span class="hljs-property">labelposition</span>, <span class="hljs-attr">labelwidth</span>: p.<span class="hljs-property">dataset</span>.<span class="hljs-property">labelwidth</span> || <span class="hljs-string">&#x27;25%&#x27;</span>, <span class="hljs-attr">labelbackground</span>: p.<span class="hljs-property">dataset</span>.<span class="hljs-property">labelbackground</span> || <span class="hljs-string">&#x27;rgba(0,0,0,0.2)&#x27;</span>, <span class="hljs-attr">labeltext</span>: p.<span class="hljs-property">innerHTML</span>, <span class="hljs-attr">shared</span>: (p.<span class="hljs-property">dataset</span>.<span class="hljs-property">shared</span> != <span class="hljs-literal">null</span>) ? <span class="hljs-literal">true</span> : <span class="hljs-literal">false</span>, }); }); canvas.<span class="hljs-property">domElement</span>.<span class="hljs-title function_">appendChild</span>(img); <span class="hljs-keyword">return</span> store; };</pre></div></div> </li> <li id="section-5"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-5">&#x00a7;</a> </div> <p>Internal function to scrape data from the supplied element </p> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">const</span> getNavigationData = <span class="hljs-keyword">function</span> (<span class="hljs-params">el, store, canvas</span>) { <span class="hljs-keyword">if</span> (!el) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; store.<span class="hljs-property">element</span> = el; store.<span class="hljs-property">links</span> = []; <span class="hljs-keyword">const</span> linkElements = el.<span class="hljs-title function_">querySelectorAll</span>(<span class="hljs-string">&#x27;a&#x27;</span>); linkElements.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">a</span> =&gt;</span> { store.<span class="hljs-property">links</span>.<span class="hljs-title function_">push</span>({ <span class="hljs-attr">name</span>: a.<span class="hljs-property">id</span>, <span class="hljs-attr">href</span>: a.<span class="hljs-property">href</span>, <span class="hljs-attr">width</span>: a.<span class="hljs-property">dataset</span>.<span class="hljs-property">width</span> || <span class="hljs-string">&#x27;20%&#x27;</span>, <span class="hljs-attr">position</span>: a.<span class="hljs-property">dataset</span>.<span class="hljs-property">position</span>, <span class="hljs-attr">background</span>: a.<span class="hljs-property">dataset</span>.<span class="hljs-property">background</span> || <span class="hljs-string">&#x27;rgba(0,0,0,0.2)&#x27;</span>, <span class="hljs-attr">justify</span>: a.<span class="hljs-property">dataset</span>.<span class="hljs-property">justify</span> || <span class="hljs-string">&#x27;center&#x27;</span>, <span class="hljs-attr">text</span>: a.<span class="hljs-property">innerHTML</span>, }); }); <span class="hljs-keyword">return</span> store; };</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 pin factory takes all the data about pins that we scraped from the element and builds a set of interactive Scrawl-canvas entitys for each pin</p> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">const</span> pinFactory = <span class="hljs-keyword">function</span> (<span class="hljs-params">items, canvas, pinTextGroup, pinTextBackgroundGroup, colors</span>) { <span class="hljs-keyword">let</span> { name, groupname, position, fill, stroke, labeltext, labelposition, labelwidth, labelbackground, shared, suppressAccessibleText } = items; <span class="hljs-keyword">const</span> coords = position.<span class="hljs-title function_">split</span>(<span class="hljs-string">&#x27;,&#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>TODO: We don’t want to display a label if its associated pin is not currently visible to the user</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">const</span> checkVisibility = <span class="hljs-keyword">function</span> (<span class="hljs-params">entity</span>) { <span class="hljs-keyword">return</span> <span class="hljs-literal">true</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>Generate the visible pin</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">const</span> pin = 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>: <span class="hljs-string">`<span class="hljs-subst">${groupname}</span>-cell`</span>, <span class="hljs-attr">start</span>: coords, <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">10</span>, <span class="hljs-attr">fillStyle</span>: fill, <span class="hljs-attr">strokeStyle</span>: stroke, <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>, });</pre></div></div> </li> <li id="section-9"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-9">&#x00a7;</a> </div> <p>The hit zone for the pin is assigned to the canvas element’s base cell, to make the user interaction (eg collision detection with the mouse cursor) code as simple as posssible</p> </div> <div class="content"><div class='highlight'><pre> pin.<span class="hljs-title function_">clone</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">`<span class="hljs-subst">${name}</span>-hitzone`</span>, <span class="hljs-attr">group</span>: canvas.<span class="hljs-property">base</span>.<span class="hljs-property">name</span>, <span class="hljs-attr">radius</span>: <span class="hljs-number">25</span>, <span class="hljs-attr">method</span>: <span class="hljs-string">&#x27;none&#x27;</span>, <span class="hljs-attr">onEnter</span>: <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { <span class="hljs-keyword">if</span> (<span class="hljs-title function_">checkVisibility</span>(pin)) {</pre></div></div> </li> <li id="section-10"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-10">&#x00a7;</a> </div> <p>Increase the visible pin’s size</p> </div> <div class="content"><div class='highlight'><pre> pin.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">radius</span>: <span class="hljs-number">15</span>, <span class="hljs-attr">lineWidth</span>: <span class="hljs-number">4</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>Display the pin’s associated label</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (pinText) { pinText.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">visibility</span>: <span class="hljs-literal">true</span> }); pinBackground.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">visibility</span>: <span class="hljs-literal">true</span> }); } } }, <span class="hljs-attr">onLeave</span>: <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { <span class="hljs-keyword">if</span> (<span class="hljs-title function_">checkVisibility</span>(pin)) {</pre></div></div> </li> <li id="section-12"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-12">&#x00a7;</a> </div> <p>Decrease the visible pin’s size</p> </div> <div class="content"><div class='highlight'><pre> pin.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">radius</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">lineWidth</span>: <span class="hljs-number">2</span>, });</pre></div></div> </li> <li id="section-13"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-13">&#x00a7;</a> </div> <p>Hide the pin’s associated label</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (pinText) { pinText.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">visibility</span>: <span class="hljs-literal">false</span> }); pinBackground.<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-14"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-14">&#x00a7;</a> </div> <p>Generate the label associated with each pin (assuming it’s been defined in the data)</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">let</span> pinText, pinBackground; <span class="hljs-keyword">if</span> (labeltext) {</pre></div></div> </li> <li id="section-15"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-15">&#x00a7;</a> </div> <p>Labels can be positioned above, below, or to the right or left of the pin.</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!labelposition) labelposition = <span class="hljs-string">&#x27;below&#x27;</span>; <span class="hljs-keyword">let</span> handle = [<span class="hljs-string">&#x27;center&#x27;</span>, <span class="hljs-string">&#x27;-20%&#x27;</span>]; <span class="hljs-keyword">if</span> (<span class="hljs-string">&#x27;above&#x27;</span> === labelposition) handle = [<span class="hljs-string">&#x27;center&#x27;</span>, <span class="hljs-string">&#x27;120%&#x27;</span>]; <span class="hljs-keyword">if</span> (<span class="hljs-string">&#x27;left&#x27;</span> === labelposition) handle = [<span class="hljs-string">&#x27;110%&#x27;</span>, <span class="hljs-string">&#x27;center&#x27;</span>]; <span class="hljs-keyword">if</span> (<span class="hljs-string">&#x27;right&#x27;</span> === labelposition) handle = [<span class="hljs-string">&#x27;-10%&#x27;</span>, <span class="hljs-string">&#x27;center&#x27;</span>]; pinText = scrawl.<span class="hljs-title function_">makePhrase</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">`<span class="hljs-subst">${name}</span>-label`</span>, <span class="hljs-attr">group</span>: <span class="hljs-string">`<span class="hljs-subst">${groupname}</span>-cell`</span>, <span class="hljs-attr">order</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">text</span>: labeltext, <span class="hljs-attr">justify</span>: <span class="hljs-string">&#x27;center&#x27;</span>, <span class="hljs-attr">lineHeight</span>: <span class="hljs-number">1.15</span>, <span class="hljs-attr">width</span>: labelwidth,</pre></div></div> </li> <li id="section-16"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-16">&#x00a7;</a> </div> <p>@ts-expect-error</p> </div> <div class="content"><div class='highlight'><pre> handle, <span class="hljs-attr">pivot</span>: <span class="hljs-string">`<span class="hljs-subst">${name}</span>-pin`</span>, <span class="hljs-attr">lockTo</span>: <span class="hljs-string">&#x27;pivot&#x27;</span>, <span class="hljs-attr">font</span>: <span class="hljs-string">&#x27;28px Arial, sans-serif&#x27;</span>, <span class="hljs-attr">fillStyle</span>: colors.<span class="hljs-property">default</span>, <span class="hljs-attr">exposeText</span>: (suppressAccessibleText) ? <span class="hljs-literal">false</span> : <span class="hljs-literal">true</span>, <span class="hljs-attr">visibility</span>: <span class="hljs-literal">false</span>, }); pinTextGroup.<span class="hljs-title function_">addArtefacts</span>(<span class="hljs-string">`<span class="hljs-subst">${name}</span>-label`</span>); pinBackground = scrawl.<span class="hljs-title function_">makeBlock</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">`<span class="hljs-subst">${name}</span>-background`</span>, <span class="hljs-attr">group</span>: <span class="hljs-string">`<span class="hljs-subst">${groupname}</span>-cell`</span>, <span class="hljs-attr">order</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">fillStyle</span>: labelbackground, <span class="hljs-attr">width</span>: <span class="hljs-number">20</span>, <span class="hljs-attr">height</span>: <span class="hljs-number">20</span>, <span class="hljs-attr">handleY</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">mimic</span>: <span class="hljs-string">`<span class="hljs-subst">${name}</span>-label`</span>, <span class="hljs-attr">lockTo</span>: <span class="hljs-string">&#x27;mimic&#x27;</span>, <span class="hljs-attr">useMimicDimensions</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">useMimicStart</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">useMimicHandle</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">addOwnDimensionsToMimic</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">addOwnHandleToMimic</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">visibility</span>: <span class="hljs-literal">false</span>, }); pinTextBackgroundGroup.<span class="hljs-title function_">addArtefacts</span>(<span class="hljs-string">`<span class="hljs-subst">${name}</span>-background`</span>); } };</pre></div></div> </li> <li id="section-17"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-17">&#x00a7;</a> </div> <p>The link factory takes all the data about links that we scraped from the element and builds a set of interactive Scrawl-canvas entitys for each link</p> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">const</span> linkFactory = <span class="hljs-keyword">function</span> (<span class="hljs-params">items, canvas, linkTextGroup, colors</span>) { <span class="hljs-keyword">const</span> {name, position, href, justify, text, width, background} = items; <span class="hljs-keyword">const</span> start = position.<span class="hljs-title function_">split</span>(<span class="hljs-string">&#x27;,&#x27;</span>); scrawl.<span class="hljs-title function_">makePhrase</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">`<span class="hljs-subst">${name}</span>-link`</span>, <span class="hljs-attr">group</span>: canvas.<span class="hljs-property">base</span>.<span class="hljs-property">name</span>, <span class="hljs-attr">order</span>: <span class="hljs-number">1</span>, text, start, width, <span class="hljs-attr">handleX</span>: justify, <span class="hljs-attr">handleY</span>: justify, justify, <span class="hljs-attr">font</span>: <span class="hljs-string">&#x27;16px Arial, sans-serif&#x27;</span>, <span class="hljs-attr">lineHeight</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">fillStyle</span>: colors.<span class="hljs-property">link</span>, <span class="hljs-attr">underlinePosition</span>: <span class="hljs-number">0.8</span>, <span class="hljs-attr">underlineStyle</span>: colors.<span class="hljs-property">linkunderline</span>, <span class="hljs-attr">onEnter</span>: <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { canvas.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">css</span>: { <span class="hljs-attr">cursor</span>: <span class="hljs-string">&#x27;pointer&#x27;</span>, } });</pre></div></div> </li> <li id="section-18"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-18">&#x00a7;</a> </div> <p>@ts-expect-error</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">text</span>: <span class="hljs-string">`§UNDERLINE§<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.text}</span>`</span>, }); }, <span class="hljs-attr">onLeave</span>: <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { canvas.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">css</span>: { <span class="hljs-attr">cursor</span>: <span class="hljs-string">&#x27;auto&#x27;</span>, } });</pre></div></div> </li> <li id="section-19"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-19">&#x00a7;</a> </div> <p>@ts-expect-error</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">text</span>: <span class="hljs-variable language_">this</span>.<span class="hljs-property">text</span>.<span class="hljs-title function_">replace</span>(<span class="hljs-string">&#x27;§UNDERLINE§&#x27;</span>, <span class="hljs-string">&#x27;&#x27;</span>), }); }, <span class="hljs-attr">onUp</span>: <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) {</pre></div></div> </li> <li id="section-20"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-20">&#x00a7;</a> </div> <p>@ts-expect-error</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">clickAnchor</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>Suppress accessible text here because we’re also including an anchor, which will also add its description text to the canvas shadow DOM (as part of the navigation)</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">exposeText</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">anchor</span>: { name, href, <span class="hljs-attr">description</span>: text, <span class="hljs-attr">focusAction</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">blurAction</span>: <span class="hljs-literal">true</span>, }, }); linkTextGroup.<span class="hljs-title function_">addArtefacts</span>(<span class="hljs-string">`<span class="hljs-subst">${name}</span>-link`</span>); scrawl.<span class="hljs-title function_">makeBlock</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">`<span class="hljs-subst">${name}</span>-background`</span>, <span class="hljs-attr">group</span>: canvas.<span class="hljs-property">base</span>.<span class="hljs-property">name</span>, <span class="hljs-attr">order</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">fillStyle</span>: background, <span class="hljs-attr">width</span>: <span class="hljs-number">20</span>, <span class="hljs-attr">height</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">handleY</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">mimic</span>: <span class="hljs-string">`<span class="hljs-subst">${name}</span>-link`</span>, <span class="hljs-attr">lockTo</span>: <span class="hljs-string">&#x27;mimic&#x27;</span>, <span class="hljs-attr">useMimicDimensions</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">useMimicStart</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">useMimicHandle</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">addOwnDimensionsToMimic</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">addOwnHandleToMimic</span>: <span class="hljs-literal">true</span>, }) };</pre></div></div> </li> <li id="section-22"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-22">&#x00a7;</a> </div> <h5 id="the-exported-function">The exported function</h5> </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">el</span>) {</pre></div></div> </li> <li id="section-23"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-23">&#x00a7;</a> </div> <p>Apply the snippet to the DOM element</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">let</span> snippet = scrawl.<span class="hljs-title function_">makeSnippet</span>({ <span class="hljs-attr">domElement</span>: el, }); <span class="hljs-keyword">if</span> (snippet) {</pre></div></div> </li> <li id="section-24"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-24">&#x00a7;</a> </div> <p><strong>0. Convenience handle variables</strong>; basic followup housekeeping</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">let</span> canvas = snippet.<span class="hljs-property">canvas</span>, animation = snippet.<span class="hljs-property">animation</span>, wrapper = snippet.<span class="hljs-property">element</span>, element = wrapper.<span class="hljs-property">domElement</span>, name = wrapper.<span class="hljs-property">name</span>; canvas.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">&#x27;white&#x27;</span>, }).<span class="hljs-title function_">render</span>(); wrapper.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">canvasOnTop</span>: <span class="hljs-literal">true</span>, });</pre></div></div> </li> <li id="section-25"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-25">&#x00a7;</a> </div> <p><strong>1. Get all information required from the wrapper’s panel &lt;div&gt; child elements</strong></p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">const</span> leftPanel = <span class="hljs-title function_">getPanelData</span>(element.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&#x27;[data-frame=&quot;left&quot;]&#x27;</span>), {}, canvas); <span class="hljs-keyword">const</span> rightPanel = <span class="hljs-title function_">getPanelData</span>(element.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&#x27;[data-frame=&quot;right&quot;]&#x27;</span>), {}, canvas);</pre></div></div> </li> <li id="section-26"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-26">&#x00a7;</a> </div> <p>Snippet will fail if we don’t have both panels to build</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (leftPanel &amp;&amp; rightPanel) {</pre></div></div> </li> <li id="se