<!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: ColorMap.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">ColorMap.js</h1></header><article><pre class="prettyprint source lang-js"><code>import * as util from './utils.js'
import Color from './Color.js'
// /** @module */
// /** @exports ColorMap */

/**
 * A colormap is simply an array of typedColors with several utilities such
 * as randomColor, closestColor etc.
 * This allows the colors to be simple integer indices
 * into the Array. They are also designed to be webgl-ready, being
 * composed of typedColors.
 */

/** @namespace */
const ColorMap = {
    // ### Color Array Utilities
    // Several utilities for creating color arrays

    /**
     * Ask the browser to use the canvas gradient feature
     * to create nColors given the gradient color stops and locs.
     * See Mozilla [Gradient Doc](
     * https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createLinearGradient),
     *
     * This is a powerful browser feature, can be
     * used to create all the MatLab colormaps.
     *
     * Stops are css strings.
     * Locs are floats from 0-1, default is equally spaced.
     *
     * @param {number} nColors integer number of colors to be returned
     * @param {Array} stops Array of nColors css colors, placed at locs below
     * @param {Array} locs Array of nColors floats in [0.1]. Default to even distribution
     * @returns {Array} Returns Array of nColors rgba color arrays
     */
    gradientImageData(nColors, stops, locs) {
        const ctx = util.createCtx(nColors, 1)
        // Install default locs if none provide
        if (!locs) locs = util.floatRamp(0, 1, stops.length)

        // Create a new gradient and fill it with the color stops
        const grad = ctx.createLinearGradient(0, 0, nColors, 0)
        util.repeat(stops.length, i => grad.addColorStop(locs[i], stops[i]))

        // Draw the gradient, returning the image colors typed arrays
        ctx.fillStyle = grad
        ctx.fillRect(0, 0, nColors, 1)
        return util.ctxImageColors(ctx)
    },

    // ### Array Conversion Utilities

    // Convert a Uint8Array into Array of 4 element typedColors.
    // Useful for converting ImageData objects like gradients to colormaps.
    // WebGL ready: the array.typedArray is suitable for Uniforms.
    // typedArraytoColors(typedArray) {
    //     const array = []
    //     util.step(
    //         typedArray.length,
    //         4,
    //         // Note: can't share subarray as color's typed array:
    //         // it's buffer is for entire array, not just subarray.
    //         i => array.push(Color.typedColor(...typedArray.subarray(i, i + 4)))
    //     )
    //     array.typedArray = typedArray
    //     return array
    // },
    // Convert an Array of Arrays to an Array of typedColors.
    // Webgl ready as above.
    // arraysToColors(array) {
    //     const typedArray = new Uint8ClampedArray(array.length * 4)
    //     util.repeat(array.length, i => {
    //         const a = array[i]
    //         if (a.length === 3) a.push(255)
    //         typedArray.set(a, i * 4)
    //     })
    //     return this.typedArraytoColors(typedArray)
    // },

    /**
     * Convert an Array of rgba color arrays into Array of 4 element typedColors.
     *
     * @param {Array} Array of rgba color arrays
     * @returns  Array of the rgba arrays to Color.typedColors
     */
    arrayToTypedColors(array) {
        return array.map(a => Color.toTypedColor(a))
    },

    // Permute the values of 3 arrays. Ex:
    //
    // [1,2],[3],[4,5] -> [ [1,3,4],[1,3,5],[2,3,4],[2,3,5] ]
    permuteArrays(A1, A2 = A1, A3 = A1) {
        const array = []
        for (const a3 of A3) {
            // sorta odd const works with ths, but...
            for (const a2 of A2) for (const a1 of A1) array.push([a1, a2, a3])
        }
        return array
    },
    // Use permuteArrays to create uniformly spaced color ramp permutation.
    // Ex: if numRs is 3, permuteArrays's A1 would be [0, 127, 255]
    permuteRGBColors(numRs, numGs = numRs, numBs = numRs) {
        const toRamp = num => util.integerRamp(0, 255, num)
        const ramps = [numRs, numGs, numBs].map(toRamp)
        return this.permuteArrays(...ramps)
    },

    // ### ColorMaps

    // ColorMaps are Arrays of TypedColors with these additional methods.
    // Used to be memory effecent (shared colors), webgl compatible,  and for
    // MatLab-like color-as-data.
    ColorMapProto: {
        // Inherit from Array
        __proto__: Array.prototype,
        // Create a [sparse array](https://goo.gl/lQlq5k) of index[pixel] = pixel.
        // Used by indexOf below for exact match of a color within the colormap.
        createIndex() {
            this.index = []
            util.repeat(this.length, i => {
                const px = this[i].getPixel()
                this.index[px] = i
                if (this.cssNames) this.index[this.cssNames[i]] = i
            })
        },
        // Return a random color within the colormap
        randomColor() {
            return this[util.randomInt(this.length)]
        },

        // Set alpha of all the colors ih the map
        // Note this will be shared by all users of this map!
        // Use clone() to have your own copy of a shared map.
        setAlpha(alpha) {
            util.forLoop(this, color => color.setAlpha(alpha))
        },

        // Clone this colorMap
        clone() {
            return this.cloneColorMap(this)
        },

        // Return the color at index of this array.
        // Wrap the index to be within the array.
        atIndex(index) {
            return this[index % this.length]
        },
        // Return the index of a typedColor within the colormap,
        // undefined if no exact match.
        // Use the `closest` methods below for nearest, not exact, match.
        indexOf(color) {
            if (this.index) return this.index[color.getPixel()]
            for (let i = 0; i &lt; this.length; i++) {
                if (color.equals(this[i])) return i
            }
            return undefined
        },
        // Return color scaled by number within [min, max].
        // A linear interpolation (util.lerp) in [0, length-1].
        // Used to match data directly to a color as in MatLab.
        //
        // Ex: scaleColor(25, 0, 50) returns the color in the middle of the colormap
        scaleColor(number, min = 0, max = this.length - 1) {
            // number = util.clamp(number, min, max)
            if (min === max) return this[min]
            const scale = util.lerpScale(number, min, max)
            const index = Math.round(util.lerp(0, this.length - 1, scale))
            return this[index]
        },
        // Return the Uint8 array used to create the typedColors,
        // undefined if not webgl ready.
        // webglArray() {
        //     return this.typedArray
        // },

        // Debugging: Return a string with length and array of colors
        toString() {
            return `${this.length} ${util.arraysToString(this)}`
        },

        // Iterate through the colormap colors, returning the index of the
        // min typedColor.rgbDistance value from r, g, b
        rgbClosestIndex(r, g, b) {
            let minDist = Infinity
            let ixMin = 0
            for (var i = 0; i &lt; this.length; i++) {
                const d = this[i].rgbDistance(r, g, b)
                if (d &lt; minDist) {
                    minDist = d
                    ixMin = i
                    if (d === 0) return ixMin
                }
            }
            return ixMin
        },
        // Return the color with the rgbClosestIndex value
        rgbClosestColor(r, g, b) {
            return this[this.rgbClosestIndex(r, g, b)]
        },

        // Calculate the closest cube index for the given r, g, b values.
        // Faster than rgbClosestIndex, does direct calculation, not iteration.
        cubeClosestIndex(r, g, b) {
            const cube = this.cube
            if (!cube) throw Error('cubeClosestIndex: requires the cube arrays')
            const rgbSteps = cube.map(c => 255 / (c - 1))
            const rgbLocs = [r, g, b].map((c, i) => Math.round(c / rgbSteps[i]))
            const [rLoc, gLoc, bLoc] = rgbLocs
            return rLoc + gLoc * cube[0] + bLoc * cube[0] * cube[1]
        },
        cubeClosestColor(r, g, b) {
            return this[this.cubeClosestIndex(r, g, b)]
        },

        // Choose the appropriate method for finding closest index.
        // Lets the user specify any color, and let the colormap
        // use the best match.
        closestIndex(r, g, b) {
            return this.cube
                ? this.cubeClosestIndex(r, g, b)
                : this.rgbClosestIndex(r, g, b)
        },
        // Choose the appropriate method for finding closest color
        closestColor(r, g, b) {
            return this[this.closestIndex(r, g, b)]
        },
    },

    // ### Utilities for constructing ColorMaps

    // Convert an array of colors to a colormap.
    // The colors can be strings, numbers, rgb arrays
    // They are converted to typedColors.
    basicColorMap(colors) {
        // colors = this.arraysToColors(colors)
        colors = this.arrayToTypedColors(colors)
        Object.setPrototypeOf(colors, this.ColorMapProto)
        return colors
    },
    // Create a gray map (gray: r=g=b)
    // These are typically 256 entries but can be smaller
    // by passing a size parameter and the min/max range.
    grayColorMap(min = 0, max = 255, size = max - min + 1) {
        const ramp = util.integerRamp(min, max, size)
        return this.basicColorMap(ramp.map(i => [i, i, i]))
    },

    // Create a colormap by permuted rgb values.
    //
    // numRs, numGs, numBs are numbers, the number of steps beteen 0-255.
    // Ex: numRs = 3, corresponds to 0, 128, 255.
    // NOTE: the defaults: rgbColorCube(6) creates a `6 * 6 * 6` cube.
    rgbColorCube(numRs, numGs = numRs, numBs = numRs) {
        const array = this.permuteRGBColors(numRs, numGs, numBs)
        const map = this.basicColorMap(array)
        // Save the parameters for fast color calculations.
        map.cube = [numRs, numGs, numBs]
        return map
    },
    // Create a colormap by permuting the values of the given arrays.
    // Similar to above but with arrays that may have arbitrary values.
    rgbColorMap(R, G, B) {
        const array = this.permuteArrays(R, G, B)
        return this.basicColorMap(array)
    },

    // Create an hsl map, inputs are arrays to be permutted like rgbColorMap.
    // Convert the HSL values to Color.colors, default to bright hue ramp (L=50).
    hslColorMap(num = 360, S = 100, L = 50) {
        const hues = util.integerRamp(1, 360, num)
        const colors = hues.map(h => Color.hslCssColor(h))
        const typedColors = colors.map(c => Color.toTypedColor(c))
        return this.basicColorMap(typedColors)
    },

    transparentColorMap(num = 1) {
        // const array = Array(num).fill(0)
        // return this.basicColorMap(array)
        return this.staticColorMap(0, num)
    },
    staticColorMap(color, num = 1) {
        color = Color.toTypedColor(color)
        const array = Array(num).fill(color)
        return this.basicColorMap(array)
    },

    // Use gradient to build an rgba array, then convert to colormap.
    // Stops are css strings or typedColors.
    // locs defaults to evenly spaced, probably what you want.
    //
    // This easily creates all the MatLab colormaps like "jet" below.
    gradientColorMap(nColors, stops, locs) {
        stops = stops.map(c => c.css || c) // convert stops to css strings

        // get gradient colors as typed arrays &amp; convert them to typedColors
        const uint8arrays = this.gradientImageData(nColors, stops, locs)
        const typedColors = this.arrayToTypedColors(uint8arrays)

        Object.setPrototypeOf(typedColors, this.ColorMapProto)
        return typedColors
    },
    // The most popular MatLab gradient, "jet":
    jetColors: [
        'rgb(0, 0, 127)',
        'rgb(0, 0, 255)',
        'rgb(0, 127, 255)',
        'rgb(0, 255, 255)',
        'rgb(127, 255, 127)',
        'rgb(255, 255, 0)',
        'rgb(255, 127, 0)',
        'rgb(255, 0, 0)',
        'rgb(127, 0, 0)',
    ],
    // Two other popular MatLab 'ramp' gradients are:
    // * One color: from black/white to color, optionally back to white/black.
    // stops = ['black', 'red'] or ['white', 'orange', 'black']
    // The NetLogo map is a concatenation of 14 of these.
    // * Two colors: stops = ['red', 'orange'] (blends the two, center is white)

    // The 16 unique [CSS Color Names](https://goo.gl/sxo36X), case insensitive.
    // In CSS 2.1, the color 'orange' was added to the 16 colors as a 17th color
    // Aqua == Cyan and Fuchsia == Magenta, 19 total color names.
    // These sorted by hue/saturation/light, hue in 0-300 degrees.
    // See [Mozilla Color Docs](https://goo.gl/tolSnS) for *lots* more!

    basicColorNames:
        'white silver gray black red maroon yellow orange olive lime green cyan teal blue navy magenta purple'.split(
            ' '
        ),
    brightColorNames:
        'white silver red maroon yellow orange olive lime green cyan teal blue navy magenta purple'.split(
            ' '
        ),
    // Create a named colors colormap
    cssColorMap(cssArray, createNameIndex = false) {
        const array = cssArray.map(str => Color.cssToUint8Array(str))
        const map = this.basicColorMap(array)
        map.cssNames = cssArray
        // REMIND: kinda tacky? Maybe map.name.yellow? Maybe generalize for other
        // map types: map.closest(name)
        if (createNameIndex) {
            cssArray.forEach((name, ix) => {
                map[name] = map[ix]
            })
            if (map.cyan) map.aqua = map.cyan
            if (map.magenta) map.fuchsia = map.magenta
        }
        return map
    },

    // Clone a colorMap. Useful if you want to mutate an existing shared map
    cloneColorMap(colorMap) {
        const keys = Object.keys(colorMap)
        const clone = this.basicColorMap(colorMap)
        util.forLoop(keys, (val, i) => {
            if (clone[i] === undefined) clone[val] = colorMap[val]
        })
        return clone
    },

    // ### Shared Global ColorMaps
    // NOTE: Do NOT modify one of these, they are shared and would
    // surprise anyone useing them. Use cloneColorMap() to have your own
    // private one, or call any of the map factories above .. see below.

    // The shared global colormaps are lazy evaluated to minimize memory use.
    // NOTE: these are shared, so any change in them are seen by all users!
    LazyMap(name, map) {
        Object.defineProperty(this, name, { value: map, enumerable: true })
        return map
    },
    get Gray() {
        return this.LazyMap('Gray', this.grayColorMap())
    },
    get Hue() {
        return this.LazyMap('Hue', this.hslColorMap())
    },
    get LightGray() {
        return this.LazyMap('LightGray', this.grayColorMap(200))
    },
    get DarkGray() {
        return this.LazyMap('DarkGray', this.grayColorMap(0, 100))
    },
    get Jet() {
        return this.LazyMap('Jet', this.gradientColorMap(256, this.jetColors))
    },
    get Rgb256() {
        return this.LazyMap('Rgb256', this.rgbColorCube(8, 8, 4))
    },
    get Rgb() {
        return this.LazyMap('Rgb', this.rgbColorCube(16))
    },
    get Transparent() {
        return this.LazyMap('Transparent', this.transparentColorMap())
    },
    get Basic16() {
        // 17 unique + 2 "aliases" = 19 names. "16" historic
        return this.LazyMap(
            'Basic16',
            this.cssColorMap(this.basicColorNames, true)
        )
    },
    // get Bright16() {
    //     // Basic16 w/o grays: white, black
    //     return this.LazyMap(
    //         'Bright16',
    //         this.cssColorMap(this.brightColorNames, true)
    //     )
    // },
}

export default ColorMap
</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>