Skip to content

Instantly share code, notes, and snippets.

@0x263b
Last active June 30, 2025 09:26
Show Gist options
  • Save 0x263b/2bdd90886c2036a1ad5bcf06d6e6fb37 to your computer and use it in GitHub Desktop.
Save 0x263b/2bdd90886c2036a1ad5bcf06d6e6fb37 to your computer and use it in GitHub Desktop.

Revisions

  1. 0x263b revised this gist Jul 17, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion colors.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # Random color form string in javascript
    # Random color from string in javascript

    Consider a list of strings you need to permanently assign a random color.

  2. 0x263b revised this gist Jul 17, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion colors.md
    Original file line number Diff line number Diff line change
    @@ -73,7 +73,7 @@ The issue is this can potentially spit out *any* color value. Ideally we'd want

    ### Color from array

    What if we hand pick some colors, and assign each string one of those? [(fiddle)](https://jsfiddle.net/wg6ymyyz/)
    What if we hand pick some colors, and assign each string one of those? [(fiddle)](https://jsfiddle.net/wg6ymyyz/1/)

    ```js
    String.prototype.toColor = function() {
  3. 0x263b revised this gist Jul 17, 2016. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions colors.md
    Original file line number Diff line number Diff line change
    @@ -47,7 +47,7 @@ String.prototype.toRGB = function() {
    "string".toRGB() // rgb(17, 96, 213)
    ```

    Or a hexadecimal string
    Or a hexadecimal string [(fiddle)](https://jsfiddle.net/8v6ys4x1/)

    ```js
    String.prototype.toHex = function() {
    @@ -73,7 +73,7 @@ The issue is this can potentially spit out *any* color value. Ideally we'd want

    ### Color from array

    What if we hand pick some colors, and assign each string one of those?
    What if we hand pick some colors, and assign each string one of those? [(fiddle)](https://jsfiddle.net/wg6ymyyz/)

    ```js
    String.prototype.toColor = function() {
    @@ -97,7 +97,7 @@ This method is better if we want to be very particular over what colors are allo

    ### HSL

    How about we use the hash to pick a hue, then hardcode the intensity/lightness.
    How about we use the hash to pick a hue, then hardcode the intensity/lightness. [(fiddle)](https://jsfiddle.net/u3vc2efy/)

    ```js
    String.prototype.toHue = function() {
    @@ -114,7 +114,7 @@ String.prototype.toHue = function() {
    ```
    **Note:** This can result in a negative value. CSS's `hsl()` handles values outside of `0..360` perfectly, but not everything does.

    For the sake of engineering, lets expand this out a bit more to include range values.
    For the sake of engineering, lets expand this out a bit more to include range values. [(fiddle)](https://jsfiddle.net/7zky3rbu/)

    ```js
    String.prototype.toHSL = function(opts) {
  4. 0x263b created this gist Jul 17, 2016.
    154 changes: 154 additions & 0 deletions colors.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,154 @@
    # Random color form string in javascript

    Consider a list of strings you need to permanently assign a random color.

    First you should turn the string into a hash.


    ```js
    var string = "string"
    var hash = 0

    for (var i = 0; i < string.length; i++) {
    hash = string.charCodeAt(i) + ((hash << 5) - hash);
    hash = hash & hash;
    }

    console.log(hash) // -891985903
    ```

    * `string.charCodeAt(i)` returns the UTF-16 code for the character at index `i`
    * Bit operators work on 32 bits numbers. Any numeric operand in the operation is converted into a 32 bit number.
    * `hash << 5` is equivalent to `hash * Math.pow(2, 5)` (`hash * 32`), except the bit operator `<<` makes sure our result is a 32 bit number.
    * `hash & hash` again, makes sure we only return a 32 bit number.

    Now we have something to play around with.

    ### RGB

    The simplest method is to turn our hash into an RGB string:

    ```js
    String.prototype.toRGB = function() {
    var hash = 0;
    if (this.length === 0) return hash;
    for (var i = 0; i < this.length; i++) {
    hash = this.charCodeAt(i) + ((hash << 5) - hash);
    hash = hash & hash;
    }
    var rgb = [0, 0, 0];
    for (var i = 0; i < 3; i++) {
    var value = (hash >> (i * 8)) & 255;
    rgb[i] = value;
    }
    return `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;
    }

    "string".toRGB() // rgb(17, 96, 213)
    ```

    Or a hexadecimal string

    ```js
    String.prototype.toHex = function() {
    var hash = 0;
    if (this.length === 0) return hash;
    for (var i = 0; i < this.length; i++) {
    hash = this.charCodeAt(i) + ((hash << 5) - hash);
    hash = hash & hash;
    }
    var color = '#';
    for (var i = 0; i < 3; i++) {
    var value = (hash >> (i * 8)) & 255;
    color += ('00' + value.toString(16)).substr(-2);
    }
    return color;
    }

    "string".toHex() // #1160d5
    ```

    The issue is this can potentially spit out *any* color value. Ideally we'd want to filter out values too similar to our background color, and some gray/bland colors.


    ### Color from array

    What if we hand pick some colors, and assign each string one of those?

    ```js
    String.prototype.toColor = function() {
    var colors = ["#e51c23", "#e91e63", "#9c27b0", "#673ab7", "#3f51b5", "#5677fc", "#03a9f4", "#00bcd4", "#009688", "#259b24", "#8bc34a", "#afb42b", "#ff9800", "#ff5722", "#795548", "#607d8b"]

    var hash = 0;
    if (this.length === 0) return hash;
    for (var i = 0; i < this.length; i++) {
    hash = this.charCodeAt(i) + ((hash << 5) - hash);
    hash = hash & hash;
    }
    hash = ((hash % colors.length) + colors.length) % colors.length;
    return colors[hash];
    }

    "string".toColor() // #e91e63
    ```

    This method is better if we want to be very particular over what colors are allowed, but selecting a large number colors can get tedious.


    ### HSL

    How about we use the hash to pick a hue, then hardcode the intensity/lightness.

    ```js
    String.prototype.toHue = function() {
    var hash = 0;
    if (this.length === 0) return hash;
    for (var i = 0; i < this.length; i++) {
    hash = this.charCodeAt(i) + ((hash << 5) - hash);
    hash = hash & hash;
    }
    return hash % 360;
    }

    "string".toHue() // -223
    ```
    **Note:** This can result in a negative value. CSS's `hsl()` handles values outside of `0..360` perfectly, but not everything does.

    For the sake of engineering, lets expand this out a bit more to include range values.

    ```js
    String.prototype.toHSL = function(opts) {
    var h, s, l;
    opts = opts || {};
    opts.hue = opts.hue || [0, 360];
    opts.sat = opts.sat || [75, 100];
    opts.lit = opts.lit || [40, 60];

    var range = function(hash, min, max) {
    var diff = max - min;
    var x = ((hash % diff) + diff) % diff;
    return x + min;
    }

    var hash = 0;
    if (this.length === 0) return hash;
    for (var i = 0; i < this.length; i++) {
    hash = this.charCodeAt(i) + ((hash << 5) - hash);
    hash = hash & hash;
    }

    h = range(hash, opts.hue[0], opts.hue[1]);
    s = range(hash, opts.sat[0], opts.sat[1]);
    l = range(hash, opts.lit[0], opts.lit[1]);

    return `hsl(${h}, ${s}%, ${l}%)`;
    }

    "string".toHSL() // hsl(137, 97%, 57%)

    "string".toHSL({
    hue: [-45, 45],
    sat: [75, 95],
    lit: [45, 55]
    }) // hsl(2, 92%, 52%)
    ```