<!DOCTYPE html><html lang="en" style="font-size:16px"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="../favicon.ico"><title>Source: Color.js</title><!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]--><script src="scripts/third-party/hljs.js" defer="defer"></script><script src="scripts/third-party/hljs-line-num.js" defer="defer"></script><script src="scripts/third-party/popper.js" defer="defer"></script><script src="scripts/third-party/tippy.js" defer="defer"></script><script src="scripts/third-party/tocbot.min.js"></script><script>var baseURL="/",locationPathname="";baseURL=(locationPathname=document.location.pathname).substr(0,locationPathname.lastIndexOf("/")+1)</script><link rel="stylesheet" href="styles/clean-jsdoc-theme.min.css"><svg aria-hidden="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none"><defs><symbol id="copy-icon" viewbox="0 0 488.3 488.3"><g><path d="M314.25,85.4h-227c-21.3,0-38.6,17.3-38.6,38.6v325.7c0,21.3,17.3,38.6,38.6,38.6h227c21.3,0,38.6-17.3,38.6-38.6V124    C352.75,102.7,335.45,85.4,314.25,85.4z M325.75,449.6c0,6.4-5.2,11.6-11.6,11.6h-227c-6.4,0-11.6-5.2-11.6-11.6V124    c0-6.4,5.2-11.6,11.6-11.6h227c6.4,0,11.6,5.2,11.6,11.6V449.6z"/><path d="M401.05,0h-227c-21.3,0-38.6,17.3-38.6,38.6c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5c0-6.4,5.2-11.6,11.6-11.6h227    c6.4,0,11.6,5.2,11.6,11.6v325.7c0,6.4-5.2,11.6-11.6,11.6c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5c21.3,0,38.6-17.3,38.6-38.6    V38.6C439.65,17.3,422.35,0,401.05,0z"/></g></symbol><symbol id="search-icon" viewBox="0 0 512 512"><g><g><path d="M225.474,0C101.151,0,0,101.151,0,225.474c0,124.33,101.151,225.474,225.474,225.474    c124.33,0,225.474-101.144,225.474-225.474C450.948,101.151,349.804,0,225.474,0z M225.474,409.323    c-101.373,0-183.848-82.475-183.848-183.848S124.101,41.626,225.474,41.626s183.848,82.475,183.848,183.848    S326.847,409.323,225.474,409.323z"/></g></g><g><g><path d="M505.902,476.472L386.574,357.144c-8.131-8.131-21.299-8.131-29.43,0c-8.131,8.124-8.131,21.306,0,29.43l119.328,119.328    c4.065,4.065,9.387,6.098,14.715,6.098c5.321,0,10.649-2.033,14.715-6.098C514.033,497.778,514.033,484.596,505.902,476.472z"/></g></g></symbol><symbol id="font-size-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11.246 15H4.754l-2 5H.6L7 4h2l6.4 16h-2.154l-2-5zm-.8-2L8 6.885 5.554 13h4.892zM21 12.535V12h2v8h-2v-.535a4 4 0 1 1 0-6.93zM19 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></symbol><symbol id="add-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></symbol><symbol id="minus-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5 11h14v2H5z"/></symbol><symbol id="dark-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938 7.999 7.999 0 0 0 4 12z"/></symbol><symbol id="light-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/></symbol><symbol id="reset-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M18.537 19.567A9.961 9.961 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 2.136-.67 4.116-1.81 5.74L17 12h3a8 8 0 1 0-2.46 5.772l.997 1.795z"/></symbol><symbol id="down-icon" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.7803 6.21967C13.0732 6.51256 13.0732 6.98744 12.7803 7.28033L8.53033 11.5303C8.23744 11.8232 7.76256 11.8232 7.46967 11.5303L3.21967 7.28033C2.92678 6.98744 2.92678 6.51256 3.21967 6.21967C3.51256 5.92678 3.98744 5.92678 4.28033 6.21967L8 9.93934L11.7197 6.21967C12.0126 5.92678 12.4874 5.92678 12.7803 6.21967Z"></path></symbol><symbol id="codepen-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M16.5 13.202L13 15.535v3.596L19.197 15 16.5 13.202zM14.697 12L12 10.202 9.303 12 12 13.798 14.697 12zM20 10.869L18.303 12 20 13.131V10.87zM19.197 9L13 4.869v3.596l3.5 2.333L19.197 9zM7.5 10.798L11 8.465V4.869L4.803 9 7.5 10.798zM4.803 15L11 19.131v-3.596l-3.5-2.333L4.803 15zM4 13.131L5.697 12 4 10.869v2.262zM2 9a1 1 0 0 1 .445-.832l9-6a1 1 0 0 1 1.11 0l9 6A1 1 0 0 1 22 9v6a1 1 0 0 1-.445.832l-9 6a1 1 0 0 1-1.11 0l-9-6A1 1 0 0 1 2 15V9z"/></symbol><symbol id="close-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></symbol><symbol id="menu-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z"/></symbol></defs></svg></head><body data-theme="dark"><div class="sidebar-container"><div class="sidebar" id="sidebar"><a href="/" class="sidebar-title sidebar-title-anchor">Home</a><div class="sidebar-items-container"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="AgentArray.html">AgentArray</a></div><div class="sidebar-section-children"><a href="AgentList.html">AgentList</a></div><div class="sidebar-section-children"><a href="AgentSet.html">AgentSet</a></div><div class="sidebar-section-children"><a href="Animator.html">Animator</a></div><div class="sidebar-section-children"><a href="DataSet.html">DataSet</a></div><div class="sidebar-section-children"><a href="GUI.html">GUI</a></div><div class="sidebar-section-children"><a href="GeoDataSet.html">GeoDataSet</a></div><div class="sidebar-section-children"><a href="Keyboard.html">Keyboard</a></div><div class="sidebar-section-children"><a href="Link.html">Link</a></div><div class="sidebar-section-children"><a href="Links.html">Links</a></div><div class="sidebar-section-children"><a href="Model.html">Model</a></div><div class="sidebar-section-children"><a href="Model3D.html">Model3D</a></div><div class="sidebar-section-children"><a href="Mouse.html">Mouse</a></div><div class="sidebar-section-children"><a href="Patch.html">Patch</a></div><div class="sidebar-section-children"><a href="Patches.html">Patches</a></div><div class="sidebar-section-children"><a href="RGBDataSet.html">RGBDataSet</a></div><div class="sidebar-section-children"><a href="ThreeDraw.html">ThreeDraw</a></div><div class="sidebar-section-children"><a href="Turtle.html">Turtle</a></div><div class="sidebar-section-children"><a href="Turtle3D.html">Turtle3D</a></div><div class="sidebar-section-children"><a href="Turtles.html">Turtles</a></div><div class="sidebar-section-children"><a href="TwoDraw.html">TwoDraw</a></div><div class="sidebar-section-children"><a href="World.html">World</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-src_geojson.html">src/geojson</a></div><div class="sidebar-section-children"><a href="module-src_gis.html">src/gis</a></div><div class="sidebar-section-children"><a href="module-src_utils.html">src/utils</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-tutorials"><div>Tutorials</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="tutorial-1 - AgentScript.html">1 - AgentScript</a></div><div class="sidebar-section-children"><a href="tutorial-2 - JavaScript.html">2 - JavaScript</a></div><div class="sidebar-section-children"><a href="tutorial-3 - Browser.html">3 - Browser</a></div><div class="sidebar-section-children"><a href="tutorial-4 - Model.html">4 - Model</a></div><div class="sidebar-section-children"><a href="tutorial-5 - View.html">5 - View</a></div><div class="sidebar-section-children"><a href="tutorial-6.1 - AnimatorController.html">6.1 - AnimatorController</a></div><div class="sidebar-section-children"><a href="tutorial-6.2 - KeyboardController.html">6.2 - KeyboardController</a></div><div class="sidebar-section-children"><a href="tutorial-6.3 - GuiController.html">6.3 - GuiController</a></div><div class="sidebar-section-children"><a href="tutorial-6.4 - MouseController.html">6.4 - MouseController</a></div><div class="sidebar-section-children"><a href="tutorial-7 - CodePenServer.html">7 - CodePenServer</a></div></div></div></div></div><div class="navbar-container" id="VuAckcnZhf"><nav class="navbar"><div class="navbar-left-items"><div class="navbar-item"><a id="github" href="https://github.com/backspaces/agentscript" target="">Github</a></div><div class="navbar-item"><a id="AgentScript" href="https://code.agentscript.org" target="">AgentScript.org</a></div><div class="navbar-item"><a id="npm" href="https://www.npmjs.com/package/agentscript" target="">npm</a></div><div class="navbar-item"><a id="unpkg" href="https://unpkg.com/browse/agentscript/" target="">unpkg</a></div></div><div class="navbar-right-items"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#light-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div><nav></nav></nav></div><div class="toc-container"><div class="toc-content"><span class="bold">On this page</span><div id="eed4d2a0bfd64539bb9df78095dec881"></div></div></div><div class="body-wrapper"><div class="main-content"><div class="main-wrapper"><section id="source-page" class="source-page"><header><h1 id="title" class="has-anchor">Color.js</h1></header><article><pre class="prettyprint source lang-js"><code>import * as util from './utils.js'

// /** @module  */

/**
 *
 * A general color module, supporting css string colors, canvas2d pixel
 * colors, webgl and canvas2d Uint8ClampedArray r,g,b,a arrays.
 *
 * #### CSS Color Strings.
 *
 * CSS colors in HTML are strings, see [Mozillas Color Reference](
 * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value),
 * taking one of 7 forms:
 *
 * - Names: over 140 color case-insensitive names like
 *   Red, Green, CadetBlue, etc.
 * - Hex, short and long form: #0f0, #ff10a0
 * - RGB: rgb(255, 0, 0), rgba(255, 0, 0, 0.5)
 * - HSL: hsl(120, 100%, 50%), hsla(120, 100%, 50%, 0.8)
 *
 * See [this wikipedia article](https://goo.gl/ev8Kw0)
 * on differences between HSL and HSB/HSV.
 *
 */

/** @namespace */
const Color = {
    /**
     * Convert 4 r,g,b,a ints in [0-255] ("a" defaulted to 255) to a
     * css color string.
     *
     * @param {number} r integer in [0, 255] for red channel
     * @param {number} g integer in [0, 255] for green channel
     * @param {number} b integer in [0, 255] for blue channel
     * @param {number} [a=255] integer in [0, 255] for alpha/opacity channel
     * @returns {string} A rgb(r,g,b) or rgba(r,g,b,a) css color string
     */
    rgbaCssColor(r, g, b, a = 255) {
        a = a / 255
        const a2 = a.toPrecision(2)
        return a === 1 ? `rgb(${r},${g},${b})` : `rgba(${r},${g},${b},${a2})`
    },

    /**
     * Convert 4 ints, h,s,l,a, h in [0-360], s,l in [0-100]% a in [0-255] to a
     * css color string.
     * See [hsl()](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl).
     *
     * NOTE: h=0 and h=360 are the same, use h in 0-359 for unique colors.
     *
     * @param {number} h
     * @param {number} [s=100]
     * @param {number} [l=50]
     * @param {number} [a=255]
     * @returns {string} A css HSL color string
     */
    hslCssColor(h, s = 100, l = 50, a = 255) {
        a = a / 255
        const a4 = a.toPrecision(4)
        return a === 1
            ? `hsl(${h},${s}%,${l}%)`
            : `hsla(${h},${s}%,${l}%,${a4})`
    },
    /**
     * Return a html/css hex color string for an r,g,b opaque color (a=255).
     * Hex strings do not support alpha.
     * Both #nnn and #nnnnnn forms supported.
     * Default is to check for the short hex form.
     * @param {number} r Integer value for red channel
     * @param {number} g Integer value for green channel
     * @param {number} b Integer value for blue channel
     * @returns {string} A css hex color string #nnn or #nnnnnn, n in [0,F] hex
     */
    hexCssColor(r, g, b) {
        return `#${(0x1000000 | (b | (g &lt;&lt; 8) | (r &lt;&lt; 16)))
            .toString(16)
            .slice(-6)}`
    },

    // cssColor is a hybrid string and is our standard.  It returns:
    //
    // * rgbaCssColor if a not 255 (i.e. not opaque)
    // * hexCssColor otherwise
    cssColor(r, g, b, a = 255) {
        return a === 255
            ? this.hexCssColor(r, g, b)
            : this.rgbaCssColor(r, g, b, a)
    },

    randomCssColor() {
        const r255 = () => util.randomInt(256) // random int in [0,255]
        return this.cssColor(r255(), r255(), r255())
    },

    randomGrayCssColor(min = 0, max = 255) {
        const gray = util.randomInt2(min, max) // random int in [min,max]
        return this.cssColor(gray, gray, gray)
    },

    // ### Pixels

    cssToPixel(string) {
        const rgba = this.cssToUint8Array(string)
        return this.rgbaToPixel(...rgba)
    },

    rgbaToPixel(r, g, b, a = 255) {
        const rgba = new Uint8Array([r, g, b, a])
        const pixels = new Uint32Array(rgba.buffer)
        return pixels[0]
    },

    randomPixel() {
        const r255 = () => util.randomInt(256) // random int in [0,255]
        return this.rgbaToPixel(r255(), r255(), r255())
    },

    randomGrayPixel(min = 0, max = 255) {
        const gray = util.randomInt2(min, max) // random int in [min,max]
        return this.rgbaToPixel(gray, gray, gray)
    },

    // ### CSS String Conversions

    // Return 4 element array given any legal CSS string color.
    //
    // Because strings vary widely: CadetBlue, #0f0, rgb(255,0,0),
    // hsl(120,100%,50%), we do not parse strings, instead we let
    // the browser do our work: we fill a 1x1 canvas with the css string color,
    // returning the r,g,b,a canvas ImageData TypedArray.

    // The shared 1x1 canvas 2D context.
    sharedCtx1x1: util.createCtx(1, 1, false, { willReadFrequently: true }),
    // sharedCtx1x1: util.createCtx(1, 1),

    // Convert any css string to 4 element Uint8ClampedArray TypedArray.
    // If you need a JavaScript Array, use `new Array(...TypedArray)`
    // Slow, but works for all css strings: hsl, rgb, .. as well as names.
    cssToUint8Array(string) {
        this.sharedCtx1x1.clearRect(0, 0, 1, 1)
        this.sharedCtx1x1.fillStyle = string
        this.sharedCtx1x1.fillRect(0, 0, 1, 1)
        return this.sharedCtx1x1.getImageData(0, 0, 1, 1).data
    },

    // ### Typed Color
    // A TypedColor is a 4 element ArrayBuffer, with two views:
    //
    // * pixelArray: A single element Uint32Array view
    // * u8array: A 4 element r,g,b,a Uint8ClampedArray view
    //
    // getters/setters are provided for multiple other color types:
    //  'css', 'pixel', 'rgb', 'webgl'
    // If g is undefinec, returns toTypedColor(g)
    typedColor(r, g, b, a = 255) {
        if (g === undefined) return this.toTypedColor(r)
        const u8array = new Uint8ClampedArray([r, g, b, a])
        u8array.pixelArray = new Uint32Array(u8array.buffer) // one element array
        // Make this an instance of TypedColorProto
        Object.setPrototypeOf(u8array, TypedColorProto)
        return u8array
    },

    isTypedColor(any) {
        return any &amp;&amp; any.constructor === Uint8ClampedArray &amp;&amp; any.pixelArray
    },

    // Return a typedColor given a value and optional colorType
    // If the value already is a typedColor, simply return it
    // If colorType not defined, assume css (string) or pixel (number)
    // or array [r,g,b,a=255]
    // The colorType can be: 'css', 'pixel', 'rgb', 'webgl'
    // Note rgb and webgl are int arrays &amp; float arrays respectively.
    toTypedColor(value, colorType) {
        if (this.isTypedColor(value)) return value

        const tc = this.typedColor(0, 0, 0, 0) // "empty" typed color
        if (colorType == null) {
            if (util.isString(value)) tc.css = value
            else if (util.isNumber(value)) tc.pixel = value
            else if (util.isArray(value)) tc.rgb = value
            else if (util.isTypedArray(value)) tc.rgb = value
            else throw Error(`toTypedColor: illegal value ${value}`)
        } else {
            // REMIND: type check value &amp; colorType?
            tc[colorType] = value
        }
        return tc
    },

    // Random typedColor, rgb or gray, alpha = 255 for both:
    randomTypedColor() {
        const r255 = () => util.randomInt(256) // random int in [0,255]
        return this.typedColor(r255(), r255(), r255())
    },
    // Random gray color, alpha = 255
    randomGrayTypedColor(min = 0, max = 255) {
        const gray = util.randomInt2(min, max) // random int in [min,max]
        return this.typedColor(gray, gray, gray)
    },
    // Arrays of random typed colors, very useful for patch colors
    randomColorArray(length) {
        const colors = new Array(length)
        util.forLoop(colors, (c, i) => (colors[i] = this.randomTypedColor()))
        return colors
    },
    randomGrayArray(length, min = 0, max = 255) {
        const grays = new Array(length)
        util.forLoop(
            grays,
            (g, i) => (grays[i] = this.randomGrayTypedColor(min, max))
        )
        return grays
    },
}

// Prototype for Color. Getters/setters for usability, may be slower.
const TypedColorProto = {
    // Inherit from Uint8ClampedArray
    __proto__: Uint8ClampedArray.prototype,

    // Set the Color to new rgba values.
    setColor(r, g, b, a = 255) {
        this.checkColorChange()
        this[0] = r
        this[1] = g
        this[2] = b
        this[3] = a
    },
    // No real need for getColor, it *is* the typed Uint8 array
    set rgb(rgbaArray) {
        this.setColor(...rgbaArray)
    },
    get rgb() {
        return this
    },

    // Set opacity to a value in 0-255
    setAlpha(alpha) {
        this.checkColorChange()
        this[3] = alpha // Uint8ClampedArray will clamp to 0-255
    },
    getAlpha() {
        return this[3]
    },
    get alpha() {
        return this.getAlpha()
    },
    set alpha(alpha) {
        this.setAlpha(alpha)
    },

    // Set the Color to a new pixel value
    setPixel(pixel) {
        this.checkColorChange()
        this.pixelArray[0] = pixel
    },
    // Get the pixel value
    getPixel() {
        return this.pixelArray[0]
    },
    get pixel() {
        return this.getPixel()
    },
    set pixel(pixel) {
        this.setPixel(pixel)
    },

    // Set pixel/rgba values to equivalent of the css string.
    // 'red', '#f00', 'ff0000', 'rgb(255,0,0)', etc.
    //
    // Does *not* set the chached this.string, which will be lazily evaluated
    // to its common cssColor by getCss(). The above would all return '#f00'.
    setCss(string) {
        return this.setColor(...Color.cssToUint8Array(string))
    },
    // Return the cssColor for this Color, cached in the @string value
    getCss() {
        if (this.string == null) this.string = Color.cssColor(...this)
        return this.string
    },
    get css() {
        return this.getCss()
    },
    set css(string) {
        this.setCss(string)
    },

    // Note: webgl colors are 3 RGB floats (no A)
    setWebgl(array) {
        if (array.length !== 3)
            throw Error(
                'setWebgl array length must be 3, length:',
                array.length
            )
        this.setColor(
            // OK if float * 255 non-int, setColor stores into uint8 array
            array[0] * 255,
            array[1] * 255,
            array[2] * 255
        )
    },
    getWebgl() {
        return [this[0] / 255, this[1] / 255, this[2] / 255]
    },
    get webgl() {
        return this.getWebgl()
    },
    set webgl(array) {
        this.setWebgl(array)
    },

    // Housekeeping when the color is modified.
    checkColorChange() {
        // Reset string &amp; webgl on color change.
        this.string = null // will be lazy evaluated via getCss.
        // this.floatArray = null
    },
    // Return true if color is same value as myself, comparing pixels
    equals(color) {
        return this.getPixel() === color.getPixel()
    },
    toString() {
        return `[${Array.from(this).toString()}]`
    },
    // Return a [distance metric](
    // http://www.compuphase.com/cmetric.htm) between two colors.
    // Max distance is roughly 765 (3*255), for black &amp; white.
    // For our purposes, omitting the sqrt will not effect our results
    rgbDistance(r, g, b) {
        const [r1, g1, b1] = this
        const rMean = Math.round((r1 + r) / 2)
        const [dr, dg, db] = [r1 - r, g1 - g, b1 - b]
        const [dr2, dg2, db2] = [dr * dr, dg * dg, db * db]
        const distanceSq =
            (((512 + rMean) * dr2) >> 8) +
            4 * dg2 +
            (((767 - rMean) * db2) >> 8)
        return distanceSq // Math.sqrt(distanceSq)
    },
}

export default Color
</code></pre></article></section><footer class="footer" id="PeOAagUepe"><div class="wrapper">AgentScript version: 0.10.20 using clean-jsdoc-theme</div></footer></div></div></div><div class="search-container" id="PkfLWpAbet" style="display:none"><div class="wrapper" id="iCxFxjkHbP"><button class="icon-button search-close-button" id="VjLlGakifb" aria-label="close search"><svg><use xlink:href="#close-icon"></use></svg></button><div class="search-box-c"><svg><use xlink:href="#search-icon"></use></svg> <input type="text" id="vpcKVYIppa" class="search-input" placeholder="Search..." autofocus></div><div class="search-result-c" id="fWwVHRuDuN"><span class="search-result-c-text">Type anything to view search result</span></div></div></div><div class="mobile-menu-icon-container"><button class="icon-button" id="mobile-menu" data-isopen="false" aria-label="menu"><svg><use xlink:href="#menu-icon"></use></svg></button></div><div id="mobile-sidebar" class="mobile-sidebar-container"><div class="mobile-sidebar-wrapper"><a href="/" class="sidebar-title sidebar-title-anchor">Home</a><div class="mobile-nav-links"><div class="navbar-item"><a id="github-mobile" href="https://github.com/backspaces/agentscript" target="">Github</a></div><div class="navbar-item"><a id="AgentScript-mobile" href="https://code.agentscript.org" target="">AgentScript.org</a></div><div class="navbar-item"><a id="npm-mobile" href="https://www.npmjs.com/package/agentscript" target="">npm</a></div><div class="navbar-item"><a id="unpkg-mobile" href="https://unpkg.com/browse/agentscript/" target="">unpkg</a></div></div><div class="mobile-sidebar-items-c"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="AgentArray.html">AgentArray</a></div><div class="sidebar-section-children"><a href="AgentList.html">AgentList</a></div><div class="sidebar-section-children"><a href="AgentSet.html">AgentSet</a></div><div class="sidebar-section-children"><a href="Animator.html">Animator</a></div><div class="sidebar-section-children"><a href="DataSet.html">DataSet</a></div><div class="sidebar-section-children"><a href="GUI.html">GUI</a></div><div class="sidebar-section-children"><a href="GeoDataSet.html">GeoDataSet</a></div><div class="sidebar-section-children"><a href="Keyboard.html">Keyboard</a></div><div class="sidebar-section-children"><a href="Link.html">Link</a></div><div class="sidebar-section-children"><a href="Links.html">Links</a></div><div class="sidebar-section-children"><a href="Model.html">Model</a></div><div class="sidebar-section-children"><a href="Model3D.html">Model3D</a></div><div class="sidebar-section-children"><a href="Mouse.html">Mouse</a></div><div class="sidebar-section-children"><a href="Patch.html">Patch</a></div><div class="sidebar-section-children"><a href="Patches.html">Patches</a></div><div class="sidebar-section-children"><a href="RGBDataSet.html">RGBDataSet</a></div><div class="sidebar-section-children"><a href="ThreeDraw.html">ThreeDraw</a></div><div class="sidebar-section-children"><a href="Turtle.html">Turtle</a></div><div class="sidebar-section-children"><a href="Turtle3D.html">Turtle3D</a></div><div class="sidebar-section-children"><a href="Turtles.html">Turtles</a></div><div class="sidebar-section-children"><a href="TwoDraw.html">TwoDraw</a></div><div class="sidebar-section-children"><a href="World.html">World</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-src_geojson.html">src/geojson</a></div><div class="sidebar-section-children"><a href="module-src_gis.html">src/gis</a></div><div class="sidebar-section-children"><a href="module-src_utils.html">src/utils</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-tutorials"><div>Tutorials</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="tutorial-1 - AgentScript.html">1 - AgentScript</a></div><div class="sidebar-section-children"><a href="tutorial-2 - JavaScript.html">2 - JavaScript</a></div><div class="sidebar-section-children"><a href="tutorial-3 - Browser.html">3 - Browser</a></div><div class="sidebar-section-children"><a href="tutorial-4 - Model.html">4 - Model</a></div><div class="sidebar-section-children"><a href="tutorial-5 - View.html">5 - View</a></div><div class="sidebar-section-children"><a href="tutorial-6.1 - AnimatorController.html">6.1 - AnimatorController</a></div><div class="sidebar-section-children"><a href="tutorial-6.2 - KeyboardController.html">6.2 - KeyboardController</a></div><div class="sidebar-section-children"><a href="tutorial-6.3 - GuiController.html">6.3 - GuiController</a></div><div class="sidebar-section-children"><a href="tutorial-6.4 - MouseController.html">6.4 - MouseController</a></div><div class="sidebar-section-children"><a href="tutorial-7 - CodePenServer.html">7 - CodePenServer</a></div></div></div><div class="mobile-navbar-actions"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#light-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div></div></div><script type="text/javascript" src="scripts/core.min.js"></script><script src="scripts/search.min.js" defer="defer"></script><script src="scripts/third-party/fuse.js" defer="defer"></script><script type="text/javascript">var tocbotInstance=tocbot.init({tocSelector:"#eed4d2a0bfd64539bb9df78095dec881",contentSelector:".main-content",headingSelector:"h1, h2, h3",hasInnerContainers:!0,scrollContainer:".main-content",headingsOffset:130,onClick:bringLinkToView})</script></body></html>