UNPKG

scrawl-canvas

Version:
1,092 lines (704 loc) 73.1 kB
<!DOCTYPE html> <html> <head> <title>Palette factory</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"> <link rel="stylesheet" media="all" href="../../docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <ul id="jump_to"> <li> <a class="large" href="javascript:void(0);">Jump To &hellip;</a> <a class="small" href="javascript:void(0);">+</a> <div id="jump_wrapper"> <div id="jump_page_wrapper"> <div id="jump_page"> <a class="source" href="../core/animationloop.html"> ./source/core/animationloop.js </a> <a class="source" href="../core/document.html"> ./source/core/document.js </a> <a class="source" href="../core/events.html"> ./source/core/events.js </a> <a class="source" href="../core/init.html"> ./source/core/init.js </a> <a class="source" href="../core/library.html"> ./source/core/library.js </a> <a class="source" href="../core/random-seed.html"> ./source/core/random-seed.js </a> <a class="source" href="../core/snippets.html"> ./source/core/snippets.js </a> <a class="source" href="../core/userInteraction.html"> ./source/core/userInteraction.js </a> <a class="source" href="../core/utilities.html"> ./source/core/utilities.js </a> <a class="source" href="action.html"> ./source/factory/action.js </a> <a class="source" href="anchor.html"> ./source/factory/anchor.js </a> <a class="source" href="animation.html"> ./source/factory/animation.js </a> <a class="source" href="bezier.html"> ./source/factory/bezier.js </a> <a class="source" href="block.html"> ./source/factory/block.js </a> <a class="source" href="canvas.html"> ./source/factory/canvas.js </a> <a class="source" href="cell.html"> ./source/factory/cell.js </a> <a class="source" href="cog.html"> ./source/factory/cog.js </a> <a class="source" href="color.html"> ./source/factory/color.js </a> <a class="source" href="conicGradient.html"> ./source/factory/conicGradient.js </a> <a class="source" href="coordinate.html"> ./source/factory/coordinate.js </a> <a class="source" href="crescent.html"> ./source/factory/crescent.js </a> <a class="source" href="element.html"> ./source/factory/element.js </a> <a class="source" href="emitter.html"> ./source/factory/emitter.js </a> <a class="source" href="filter.html"> ./source/factory/filter.js </a> <a class="source" href="filterEngine-bluenoiseData.html"> ./source/factory/filterEngine-bluenoiseData.js </a> <a class="source" href="filterEngine.html"> ./source/factory/filterEngine.js </a> <a class="source" href="fontAttributes.html"> ./source/factory/fontAttributes.js </a> <a class="source" href="gradient.html"> ./source/factory/gradient.js </a> <a class="source" href="grid.html"> ./source/factory/grid.js </a> <a class="source" href="group.html"> ./source/factory/group.js </a> <a class="source" href="imageAsset.html"> ./source/factory/imageAsset.js </a> <a class="source" href="line.html"> ./source/factory/line.js </a> <a class="source" href="lineSpiral.html"> ./source/factory/lineSpiral.js </a> <a class="source" href="loom.html"> ./source/factory/loom.js </a> <a class="source" href="mesh.html"> ./source/factory/mesh.js </a> <a class="source" href="net.html"> ./source/factory/net.js </a> <a class="source" href="noiseAsset.html"> ./source/factory/noiseAsset.js </a> <a class="source" href="oval.html"> ./source/factory/oval.js </a> <a class="source" href="palette.html"> ./source/factory/palette.js </a> <a class="source" href="particle.html"> ./source/factory/particle.js </a> <a class="source" href="particleForce.html"> ./source/factory/particleForce.js </a> <a class="source" href="particleHistory.html"> ./source/factory/particleHistory.js </a> <a class="source" href="particleSpring.html"> ./source/factory/particleSpring.js </a> <a class="source" href="particleWorld.html"> ./source/factory/particleWorld.js </a> <a class="source" href="pattern.html"> ./source/factory/pattern.js </a> <a class="source" href="phrase.html"> ./source/factory/phrase.js </a> <a class="source" href="picture.html"> ./source/factory/picture.js </a> <a class="source" href="polygon.html"> ./source/factory/polygon.js </a> <a class="source" href="polyline.html"> ./source/factory/polyline.js </a> <a class="source" href="quadratic.html"> ./source/factory/quadratic.js </a> <a class="source" href="quaternion.html"> ./source/factory/quaternion.js </a> <a class="source" href="radialGradient.html"> ./source/factory/radialGradient.js </a> <a class="source" href="rawAsset.html"> ./source/factory/rawAsset.js </a> <a class="source" href="rdAsset.html"> ./source/factory/rdAsset.js </a> <a class="source" href="rectangle.html"> ./source/factory/rectangle.js </a> <a class="source" href="renderAnimation.html"> ./source/factory/renderAnimation.js </a> <a class="source" href="shape.html"> ./source/factory/shape.js </a> <a class="source" href="spiral.html"> ./source/factory/spiral.js </a> <a class="source" href="spriteAsset.html"> ./source/factory/spriteAsset.js </a> <a class="source" href="stack.html"> ./source/factory/stack.js </a> <a class="source" href="star.html"> ./source/factory/star.js </a> <a class="source" href="state.html"> ./source/factory/state.js </a> <a class="source" href="tetragon.html"> ./source/factory/tetragon.js </a> <a class="source" href="ticker.html"> ./source/factory/ticker.js </a> <a class="source" href="tracer.html"> ./source/factory/tracer.js </a> <a class="source" href="tween.html"> ./source/factory/tween.js </a> <a class="source" href="unstackedElement.html"> ./source/factory/unstackedElement.js </a> <a class="source" href="vector.html"> ./source/factory/vector.js </a> <a class="source" href="videoAsset.html"> ./source/factory/videoAsset.js </a> <a class="source" href="wheel.html"> ./source/factory/wheel.js </a> <a class="source" href="../mixin/anchor.html"> ./source/mixin/anchor.js </a> <a class="source" href="../mixin/asset.html"> ./source/mixin/asset.js </a> <a class="source" href="../mixin/assetAdvancedFunctionality.html"> ./source/mixin/assetAdvancedFunctionality.js </a> <a class="source" href="../mixin/assetConsumer.html"> ./source/mixin/assetConsumer.js </a> <a class="source" href="../mixin/base.html"> ./source/mixin/base.js </a> <a class="source" href="../mixin/cascade.html"> ./source/mixin/cascade.js </a> <a class="source" href="../mixin/delta.html"> ./source/mixin/delta.js </a> <a class="source" href="../mixin/displayShape.html"> ./source/mixin/displayShape.js </a> <a class="source" href="../mixin/dom.html"> ./source/mixin/dom.js </a> <a class="source" href="../mixin/entity.html"> ./source/mixin/entity.js </a> <a class="source" href="../mixin/filter.html"> ./source/mixin/filter.js </a> <a class="source" href="../mixin/mimic.html"> ./source/mixin/mimic.js </a> <a class="source" href="../mixin/path.html"> ./source/mixin/path.js </a> <a class="source" href="../mixin/pattern.html"> ./source/mixin/pattern.js </a> <a class="source" href="../mixin/pivot.html"> ./source/mixin/pivot.js </a> <a class="source" href="../mixin/position.html"> ./source/mixin/position.js </a> <a class="source" href="../mixin/shapeBasic.html"> ./source/mixin/shapeBasic.js </a> <a class="source" href="../mixin/shapeCurve.html"> ./source/mixin/shapeCurve.js </a> <a class="source" href="../mixin/shapePathCalculation.html"> ./source/mixin/shapePathCalculation.js </a> <a class="source" href="../mixin/styles.html"> ./source/mixin/styles.js </a> <a class="source" href="../mixin/tween.html"> ./source/mixin/tween.js </a> </div> </div> </li> </ul> <ul class="sections"> <li id="section-1"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-1">&#x00a7;</a> </div> <h1 id="palette-factory">Palette factory</h1> <p>Scrawl-canvas uses Palette objects to handle color management for its <a href="./gradient.html">Gradient</a> and <a href="./radialGradient.html">RadialGradient</a> styles.</p> <ul> <li>Every gradient-type object gets a Palette object as part of its construction, stored in its <code>palette</code> attribute.</li> <li>While Palette objects have their own section in the scrawl library, we don’t actually use that functionality - unlike entity State objects, Palette objects cannot be shared between gradients.</li> <li>Developers should never need to interact with Palette objects directly; gradient-type styles include functions for adding and manipulating gradient color stops.</li> <li>Packet, clone and kill functionality is also managed through the gradient-type style objects.</li> </ul> </div> </li> <li id="section-2"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-2">&#x00a7;</a> </div> <h5 id="gradients-and-color-stops">Gradients and color stops</h5> <p>The <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API">Canvas API</a> uses a rather convoluted way to add color data to a <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasGradient">CanvasGradient</a> interface object: </p> <ul> <li>the object is created first on the &lt;canvas&gt; context engine where it is to be applied, with <strong>start</strong> and <strong>end</strong> coordinates, </li> <li>then color stops are <em>individually</em> added to it afterwards. </li> <li>This needs to be done for every gradient applied to a context engine before any fill or stroke operation using that gradient. </li> <li>And only one gradient may be applied to the context engine at any time.</li> </ul> <p>The specificity of the above requirements - in particular relating to position coordinates - and the inability to update the CanvasGradient beyond adding color stops to it, means that storing these objects for future use is not a useful proposition … especially in a dynamic environment where we want the gradient to move in-step with an entity, or animate its colors in some way.</p> <p>Scrawl-canvas overcomes this problem through the use of <a href="../factory/palette.html">Palette objects</a> which separate a gradient-type style’s color-stop data from its positioning data. We treat Canvas API <code>CanvasGradient</code> objects as use-once-and-dispose objects, generating them in a just-in-time fashion for each entity’s <code>stamp</code> operation in the Display cycle.</p> <p>Palette objects store their color data in a <code>colors</code> attribute object:</p> <pre><code>{ <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;mygradient_palette&quot;</span>, <span class="hljs-attr">colors</span>: { <span class="hljs-string">&quot;0 &quot;</span>: [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>], <span class="hljs-string">&quot;350 &quot;</span>: [<span class="hljs-number">255</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>], <span class="hljs-string">&quot;650 &quot;</span>: [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">255</span>, <span class="hljs-number">1</span>], <span class="hljs-string">&quot;999 &quot;</span>: [<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">1</span>], <span class="hljs-string">&quot;index-label-between-0-and-999 &quot;</span>: [redValue, greenValue, blueValue, alphaValue] }, } </code></pre> <p>To <code>set</code> the Palette object’s <code>colors</code> object, either when creating the gradient-type style or at some point afterwards, we can use CSS color Strings instead of an array of values for each color:</p> <pre><code>myGradient.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">colors</span>: [ [<span class="hljs-number">0</span>, <span class="hljs-string">&#x27;black&#x27;</span>], [<span class="hljs-number">0</span>, <span class="hljs-string">&#x27;red&#x27;</span>], [<span class="hljs-number">0</span>, <span class="hljs-string">&#x27;blue&#x27;</span>], [<span class="hljs-number">0</span>, <span class="hljs-string">&#x27;white&#x27;</span>], ] }); </code></pre> </div> </li> <li id="section-3"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-3">&#x00a7;</a> </div> <h4 id="demos">Demos:</h4> <ul> <li><a href="../../demo/canvas-003.html">Canvas-003</a> - Linear gradients</li> <li><a href="../../demo/canvas-004.html">Canvas-004</a> - Radial gradients</li> <li><a href="../../demo/canvas-005.html">Canvas-005</a> - Cell-locked, and Entity-locked, gradients; animating gradients by delta, and by tween</li> <li><a href="../../demo/canvas-022.html">Canvas-022</a> - Grid entity - basic functionality (color, gradients)</li> <li><a href="../../demo/canvas-049.html">Canvas-049</a> - Conic gradients</li> <li><a href="../../demo/canvas-061.html">Canvas-061</a> - Gradients stress test</li> </ul> </div> </li> <li id="section-4"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-4">&#x00a7;</a> </div> <h4 id="imports">Imports</h4> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">import</span> { constructors } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../core/library.js&#x27;</span>; <span class="hljs-keyword">import</span> { λ<span class="hljs-literal">null</span>, λfirstArg, isa_obj, isa_fn, mergeOver, xt, xta, pushUnique, Ωempty, easeEngines } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../core/utilities.js&#x27;</span>; <span class="hljs-keyword">import</span> { makeColor } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./color.js&#x27;</span>; <span class="hljs-keyword">import</span> baseMix <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../mixin/base.js&#x27;</span>;</pre></div></div> </li> <li id="section-5"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-5">&#x00a7;</a> </div> <h4 id="palette-constructor">Palette constructor</h4> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">const</span> <span class="hljs-title class_">Palette</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">items = Ωempty</span>) { <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">makeName</span>(items.<span class="hljs-property">name</span>); <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">register</span>(); <span class="hljs-variable language_">this</span>.<span class="hljs-property">factory</span> = <span class="hljs-title function_">makeColor</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.name}</span>-color-factory`</span>, }); <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">set</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">defs</span>); <span class="hljs-variable language_">this</span>.<span class="hljs-property">colors</span> = items.<span class="hljs-property">colors</span> || {<span class="hljs-string">&#x27;0 &#x27;</span>: [<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">1</span>], <span class="hljs-string">&#x27;999 &#x27;</span>: [<span class="hljs-number">255</span>,<span class="hljs-number">255</span>,<span class="hljs-number">255</span>,<span class="hljs-number">1</span>]}; <span class="hljs-variable language_">this</span>.<span class="hljs-property">stops</span> = <span class="hljs-title class_">Array</span>(<span class="hljs-number">1000</span>); <span class="hljs-variable language_">this</span>.<span class="hljs-property">easingFunction</span> = λfirstArg; <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">set</span>(items); <span class="hljs-variable language_">this</span>.<span class="hljs-property">dirtyPalette</span> = <span class="hljs-literal">true</span>; <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>; };</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="palette-prototype">Palette prototype</h4> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">let</span> P = <span class="hljs-title class_">Palette</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span> = <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">create</span>(<span class="hljs-title class_">Object</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>); P.<span class="hljs-property">type</span> = <span class="hljs-string">&#x27;Palette&#x27;</span>; P.<span class="hljs-property">lib</span> = <span class="hljs-string">&#x27;palette&#x27;</span>; P.<span class="hljs-property">isArtefact</span> = <span class="hljs-literal">false</span>; P.<span class="hljs-property">isAsset</span> = <span class="hljs-literal">false</span>;</pre></div></div> </li> <li id="section-7"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-7">&#x00a7;</a> </div> <h4 id="mixins">Mixins</h4> </div> <div class="content"><div class='highlight'><pre>P = <span class="hljs-title function_">baseMix</span>(P);</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="palette-attributes">Palette attributes</h4> <ul> <li>Attributes defined in the <a href="../mixin/base.html">base mixin</a>: <strong>name</strong>.</li> </ul> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">let</span> defaultAttributes = {</pre></div></div> </li> <li id="section-9"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-9">&#x00a7;</a> </div> <p>The <strong>colors</strong> object is a raw Javascript object which uses stop values <code>(&#39;0 &#39; - &#39;999 &#39;)</code> as keys and an Array with four members holding color data as values. </p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">colors</span>: <span class="hljs-literal">null</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>The <strong>stops</strong> array is a fixed Array of length 1000 containing rgba color strings for each index. </p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">stops</span>: <span class="hljs-literal">null</span>,</pre></div></div> </li> <li id="section-11"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-11">&#x00a7;</a> </div> <p>If the <strong>cyclic</strong> flag is set, then we know to calculate appropriate stop values between the last key color and the first key color, thus allowing for smooth crossing of the 1 -&gt; 0 stops boundary</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">cyclic</span>: <span class="hljs-literal">false</span>,</pre></div></div> </li> <li id="section-12"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-12">&#x00a7;</a> </div> <p>The <strong>easing</strong> and <strong>easingFunction</strong> attributes affect represents a transformation that will be applied to a copy of the color stops Array - this allows us to create non-linear gradients</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">easing</span>: <span class="hljs-string">&#x27;linear&#x27;</span>, <span class="hljs-attr">easingFunction</span>: <span class="hljs-literal">null</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>The <strong>precision</strong> value - higher values lead to fewer stops being added to the gradient; setting the value to <code>0</code> forces the palette to skip setting the stops between defined colors in the <code>colors</code> Array</p> </div> <div class="content"><div class='highlight'><pre> <span class="hljs-attr">precision</span>: <span class="hljs-number">25</span>,</pre></div></div> </li> <li id="section-14"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-14">&#x00a7;</a> </div> <h5 id="non-retained-argument-attributes-for-factory-clone-set-functions---these-attributes-get-passed-on-to-the-palettes-color-object">Non-retained argument attributes (for factory, clone, set functions) - these attributes get passed on to the Palette’s Color object</h5> </div> </li> <li id="section-15"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-15">&#x00a7;</a> </div> <p><strong>colorSpace</strong> - String value defining the color space to be used by the Palette’s Color object for its internal calculations.</p> <ul> <li>Accepted values from: <code>&#39;RGB&#39;, &#39;HSL&#39;, &#39;HWB&#39;, &#39;XYZ&#39;, &#39;LAB&#39;, &#39;LCH&#39;, &#39;OKLAB&#39;, &#39;OKLCH&#39;</code> with <code>RGB</code> as the default</li> </ul> <p><strong>returnColorAs</strong> - String value defining the type of color String the Palette’s Color object will return.</p> <ul> <li>This is a shorter list than the internal colorSpace attribute as we only return values for CSS specified color spaces. Note that some of these color spaces are not widely supported across browsers and will lead to errors in canvases displayed on non-supported browsers</li> <li>Accepted values from: <code>&#39;RGB&#39;, &#39;HSL&#39;, &#39;HWB&#39;, &#39;LAB&#39;, &#39;LCH&#39;, &#39;OKLAB&#39;, &#39;OKLCH&#39;</code> with <code>RGB</code> as the default</li> </ul> </div> <div class="content"><div class='highlight'><pre> }; P.<span class="hljs-property">defs</span> = <span class="hljs-title function_">mergeOver</span>(P.<span class="hljs-property">defs</span>, defaultAttributes);</pre></div></div> </li> <li id="section-16"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-16">&#x00a7;</a> </div> <h4 id="packet-management">Packet management</h4> </div> <div class="content"><div class='highlight'><pre>P.<span class="hljs-property">packetFunctions</span> = <span class="hljs-title function_">pushUnique</span>(P.<span class="hljs-property">packetFunctions</span>, [<span class="hljs-string">&#x27;easingFunction&#x27;</span>]); P.<span class="hljs-property">packetExclusions</span> = <span class="hljs-title function_">pushUnique</span>(P.<span class="hljs-property">packetExclusions</span>, [<span class="hljs-string">&#x27;stops&#x27;</span>]);</pre></div></div> </li> <li id="section-17"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-17">&#x00a7;</a> </div> <h4 id="clone-management">Clone management</h4> <p>No additional clone functionality required</p> </div> </li> <li id="section-18"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-18">&#x00a7;</a> </div> <h4 id="kill-management">Kill management</h4> </div> <div class="content"><div class='highlight'><pre>P.<span class="hljs-property">kill</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">factory</span> &amp;&amp; <span class="hljs-variable language_">this</span>.<span class="hljs-property">factory</span>.<span class="hljs-property">kill</span>) <span class="hljs-variable language_">this</span>.<span class="hljs-property">factory</span>.<span class="hljs-title function_">kill</span>(); <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">deregister</span>(); <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>; };</pre></div></div> </li> <li id="section-19"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-19">&#x00a7;</a> </div> <h4 id="get-set-deltaset">Get, Set, deltaSet</h4> </div> <div class="content"><div class='highlight'><pre><span class="hljs-keyword">let</span> G = P.<span class="hljs-property">getters</span>, S = P.<span class="hljs-property">setters</span>;</pre></div></div> </li> <li id="section-20"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-20">&#x00a7;</a> </div> <p><strong>colors</strong> - an array of arrays, each sub-array being in the form <code>[Number, String]</code> where:</p> <ul> <li>Number is a positive integer in the range 0-999</li> <li>String is any legitimate CSS color string value (rgb-key, rgb-hex, <code>rgb()</code>, <code>rgba()</code>, <code>hsl()</code>, <code>hsla()</code>, <code>hwb()</code>, <code>lch()</code>, <code>lab()</code>, <code>oklch()</code>, <code>oklab()</code>). Also accepts xyz color space colors in the format <code>xyz(x-value y-value z-value)</code> or <code>xyz(x-value y-value z-value / alpha-value)</code></li> </ul> </div> <div class="content"><div class='highlight'><pre>G.<span class="hljs-property">colors</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { <span class="hljs-keyword">const</span> f = <span class="hljs-variable language_">this</span>.<span class="hljs-property">factory</span>, res = []; <span class="hljs-keyword">if</span> (f) { <span class="hljs-keyword">const</span> colorSpace = f.<span class="hljs-property">colorSpace</span>; <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> [key, value] <span class="hljs-keyword">of</span> <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">entries</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">colors</span>)) { res.<span class="hljs-title function_">push</span>([<span class="hljs-built_in">parseInt</span>(key, <span class="hljs-number">10</span>), f.<span class="hljs-title function_">buildColorString</span>(...value, colorSpace)]); } } <span class="hljs-keyword">else</span> res.<span class="hljs-title function_">push</span>([<span class="hljs-number">0</span>, <span class="hljs-string">&#x27;rgba(0 0 0 / 1)&#x27;</span>], [<span class="hljs-number">999</span>, <span class="hljs-string">&#x27;rgba(255 255 255 / 1)&#x27;</span>]); <span class="hljs-keyword">return</span> res; }; S.<span class="hljs-property">colors</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">item</span>) { <span class="hljs-keyword">if</span> (<span class="hljs-title class_">Array</span>.<span class="hljs-title function_">isArray</span>(item)) { <span class="hljs-keyword">let</span> f = <span class="hljs-variable language_">this</span>.<span class="hljs-property">factory</span>, newCols = {}, colorSpace = f.<span class="hljs-property">colorSpace</span>.<span class="hljs-title function_">toLowerCase</span>(); item.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">c</span> =&gt;</span> { <span class="hljs-keyword">let</span> [pos, col] = c; <span class="hljs-keyword">if</span> (pos.<span class="hljs-property">toFixed</span> &amp;&amp; col.<span class="hljs-property">substring</span>) { f.<span class="hljs-title function_">convert</span>(col); newCols[<span class="hljs-string">`<span class="hljs-subst">${pos}</span> `</span>] = [...f[colorSpace]]; } }); <span class="hljs-variable language_">this</span>.<span class="hljs-property">colors</span> = newCols; <span class="hljs-variable language_">this</span>.<span class="hljs-property">dirtyPalette</span> = <span class="hljs-literal">true</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><strong>easing</strong>, <strong>easingFunction</strong> - the easing to be applied to the gradient </p> <ul> <li>Can accept a String value identifying an SC pre-defined easing function (default: <code>linear</code>)</li> <li>Can also accept a function accepting a single Number argument (a value between 0-1) and returning an eased Number (again, between 0-1)</li> </ul> </div> <div class="content"><div class='highlight'><pre>S.<span class="hljs-property">easing</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">item</span>) { <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setEasingHelper</span>(item); }; S.<span class="hljs-property">easingFunction</span> = S.<span class="hljs-property">easing</span>; P.<span class="hljs-property">setEasing</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">item</span>) { <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setEasingHelper</span>(item); <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>; }; P.<span class="hljs-property">setEasingFunction</span> = P.<span class="hljs-property">setEasing</span>; P.<span class="hljs-property">setEasingHelper</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">item</span>) { <span class="hljs-keyword">if</span> (<span class="hljs-title function_">isa_fn</span>(item)) { <span class="hljs-variable language_">this</span>.<span class="hljs-property">easing</span> = <span class="hljs-string">&#x27;function&#x27;</span>; <span class="hljs-variable language_">this</span>.<span class="hljs-property">easingFunction</span> = item; } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (item.<span class="hljs-property">substring</span> &amp;&amp; easeEngines[item]) { <span class="hljs-variable language_">this</span>.<span class="hljs-property">easing</span> = item; <span class="hljs-variable language_">this</span>.<span class="hljs-property">easingFunction</span> = λfirstArg; } <span class="hljs-keyword">else</span> { <span class="hljs-variable language_">this</span>.<span class="hljs-property">easing</span> = <span class="hljs-string">&#x27;linear&#x27;</span>; <span class="hljs-variable language_">this</span>.<span class="hljs-property">easingFunction</span> = λfirstArg; } <span class="hljs-variable language_">this</span>.<span class="hljs-property">dirtyPalette</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> <p>The <strong>colorSpace</strong> and <strong>returnColorAs</strong> attributes get passed through to the Palette’s Color object</p> </div> <div class="content"><div class='highlight'><pre>G.<span class="hljs-property">colorSpace</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getColorSpace</span>(); }; S.<span class="hljs-property">colorSpace</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">item</span>) { <span class="hljs-keyword">if</span> (item.<span class="hljs-property">substring</span>) { <span class="hljs-keyword">const</span> <span class="hljs-variable constant_">ITM</span> = item.<span class="hljs-title function_">toUpperCase</span>(); <span class="hljs-keyword">const</span> itm = item.<span class="hljs-title function_">toLowerCase</span>(); <span class="hljs-keyword">if</span> ([<span class="hljs-string">&#x27;RGB&#x27;</span>, <span class="hljs-string">&#x27;HSL&#x27;</span>, <span class="hljs-string">&#x27;HWB&#x27;</span>, <span class="hljs-string">&#x27;XYZ&#x27;</span>, <span class="hljs-string">&#x27;LAB&#x27;</span>, <span class="hljs-string">&#x27;LCH&#x27;</span>, <span class="hljs-string">&#x27;OKLAB&#x27;</span>, <span class="hljs-string">&#x27;OKLCH&#x27;</span>].<span class="hljs-title function_">includes</span>(<span class="hljs-variable constant_">ITM</span>)) { <span class="hljs-keyword">const</span> oldColors = <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">assign</span>({}, <span class="hljs-variable language_">this</span>.<span class="hljs-property">colors</span>); <span class="hljs-keyword">const</span> oldSpace = <span class="hljs-variable language_">this</span>.<span class="hljs-property">factory</span>.<span class="hljs-property">colorSpace</span>; <span class="hljs-variable language_">this</span>.<span class="hljs-property">factory</span>.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">colorSpace</span>: <span class="hljs-variable constant_">ITM</span> }); <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> [key, value] <span class="hljs-keyword">of</span> <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">entries</span>(oldColors)) { <span class="hljs-keyword">const</span> color = <span class="hljs-variable language_">this</span>.<span class="hljs-property">factory</span>.<span class="hljs-title function_">buildColorString</span>(...value, oldSpace); <span class="hljs-variable language_">this</span>.<span class="hljs-property">factory</span>.<span class="hljs-title function_">setColor</span>(color); <span class="hljs-variable language_">this</span>.<span class="hljs-property">colors</span>[key].<span class="hljs-property">length</span> = <span class="hljs-number">0</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">colors</span>[key].<span class="hljs-title function_">push</span>(...<span class="hljs-variable language_">this</span>.<span class="hljs-property">factory</span>[itm]); } <span class="hljs-variable language_">this</span>.<span class="hljs-property">dirtyPalette</span> = <span class="hljs-literal">true</span>; } } } G.<span class="hljs-property">returnColorAs</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getReturnColorAs</span>(); }; S.<span class="hljs-property">returnColorAs</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">item</span>) { <span class="hljs-variable language_">this</span>.<span class="hljs-property">factory</span>.<span class="hljs-title function_">set</span>({ <span class="hljs-attr">returnColorAs</span>: item, }); <span class="hljs-variable language_">this</span>.<span class="hljs-property">dirtyPalette</span> = <span class="hljs-literal">true</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><strong>precision</strong> - a positive integer Number value between 0 and 50. If value is <code>0</code> (default) no easing will be applied to the gradient; values above 0 apply the easing to the gradient; higher values will give a quicker, but less precise, mapping.</p> </div> <div class="content"><div class='highlight'><pre>S.<span class="hljs-property">precision</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">item</span>) { item = <span class="hljs-built_in">parseInt</span>(item, <span class="hljs-number">10</span>); <span class="hljs-keyword">if</span> (<span class="hljs-built_in">isNaN</span>(item) || item &lt; <span class="hljs-number">0</span>) item = <span class="hljs-number">0</span>; <span class="hljs-keyword">if</span> (item &gt; <span class="hljs-number">50</span>) item = <span class="hljs-number">50</span>; <span class="hljs-variable language_">this</span>.<span class="hljs-property">precision</span> = item; <span class="hljs-variable language_">this</span>.<span class="hljs-property">dirtyPalette</span> = <span class="hljs-literal">true</span>; };</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>stops</strong> - Do nothing. The stops array needs to be kept private, its values set only via the <code>recalculate</code> function, which happens whenever the <code>dirtyPalette</code> attribute is set to true.</p> </div> <div class="content"><div class='highlight'><pre>S.<span class="hljs-property">stops</span> = λ<span class="hljs-literal">null</span>;</pre></div></div> </li> <li id="section-25"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-25">&#x00a7;</a> </div> <h4 id="prototype-functions">Prototype functions</h4> </div> </li> <li id="section-26"> <div class="annotation"> <div class="sswrap "> <a class="ss" href="#section-26">&#x00a7;</a> </div> <p><code>getColorSpace</code> - returns the color factory’s current colorSpace value</p> </div> <div class="content"><div class='highlight'><pre>P.<span class="hljs-property">getColorSpace</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { <span class="hljs-keyword">if</span>