HaJaeKyung / KittyExtension

Fan add-on for https://www.cryptokitties.co
MIT License
232 stars 88 forks source link

Change to non-fixed colours #2

Closed neuhaus closed 6 years ago

neuhaus commented 6 years ago

Hi,

using a HSV palette you could make the colours reflect exactly how rare the trait is.

Here's a function you can use, i converted it from Java code to javascript:

/**
* HSV to RGB color conversion
*
* H runs from 0 to 360 degrees
* S and V run from 0 to 100
*
* Ported from the excellent java algorithm by Eugene Vishnevsky at:
* http://www.cs.rit.edu/~ncs/color/t_convert.html
*/
function hsvToRgb(h, s, v) {
    var r, g, b;
    var i;
    var f, p, q, t;

    // Make sure our arguments stay in-range
    h = Math.max(0, Math.min(360, h));
    s = Math.max(0, Math.min(100, s));
    v = Math.max(0, Math.min(100, v));

    // We accept saturation and value arguments from 0 to 100 because that's
    // how Photoshop represents those values. Internally, however, the
    // saturation and value are calculated from a range of 0 to 1. We make
    // that conversion here.
    s /= 100;
    v /= 100;

    if(s == 0) {
        // Achromatic (grey)
        r = g = b = v;
        return [
            Math.round(r * 255),
            Math.round(g * 255),
            Math.round(b * 255) ];
    }

    h /= 60; // sector 0 to 5
    i = Math.floor(h);
    f = h - i; // factorial part of h
    p = v * (1 - s);
    q = v * (1 - s * f);
    t = v * (1 - s * (1 - f));

    switch(i) {
        case 0:
            r = v;
            g = t;
            b = p;
            break;

        case 1:
            r = q;
            g = v;
            b = p;
            break;

        case 2:
            r = p;
            g = v;
            b = t;
            break;

        case 3:
            r = p;
            g = q;
            b = v;
            break;

        case 4:
            r = t;
            g = p;
            b = v;
            break;

        default: // case 5:
            r = v;
            g = p;
            b = q;
    }

    return [
        Math.round(r * 255),
        Math.round(g * 255),
        Math.round(b * 255) ];
}

If you want the resulting colors to run from green to red, use a hue value between 120 and 400 (subtract 360 from h if the result is >360 before calling the function)

owap commented 6 years ago

This is an excellent idea. There's also d3.scale if you don't want to do math by hand:

const getColor = d3.scaleLinear()
    .domain([0, 20])  // Max value for trait commonality
    .interpolate(d3.interpolateCool);  // The color scale you want to use

// Now, you can get your colors by saying something like:
const jaguarColor = getColor(tbl.jaguar.count);
neuhaus commented 6 years ago

Consider using log(count) so the most interesting part (the rare ones) are distinguishable

HaJaeKyung commented 6 years ago

Agree with @neuhaus. I like having the top 50% most common be white so they can be ignored easily.

HaJaeKyung commented 6 years ago

Tested it out and much prefer the current method.