javascript - I need a function that outputs a hexadecimal value for a given floating point number that belongs to a range - Stac

I'm sorry for the bad title (edit if you wish), but I don't know how to put this request. I a

I'm sorry for the bad title (edit if you wish), but I don't know how to put this request. I attached an image from Photoshop that illustrates things a little bit better.

The request itself is quite simple: You have a numeric range from 10.0 to 0.0. 10 stands for the color #00ff00 (deep green) and 0.0 for the color #ff0000 (deep red).

Now, when you hand over the number 10.0 it will output #00ff00. When you give it something like 8.2 it would output something like #00cc33 so that you have a floating gradient all the way down but always float from #00ff00 over orange #ff9900 to #ff0000 (orange in the middle could also be omitted).

I'm sorry for the bad title (edit if you wish), but I don't know how to put this request. I attached an image from Photoshop that illustrates things a little bit better.

The request itself is quite simple: You have a numeric range from 10.0 to 0.0. 10 stands for the color #00ff00 (deep green) and 0.0 for the color #ff0000 (deep red).

Now, when you hand over the number 10.0 it will output #00ff00. When you give it something like 8.2 it would output something like #00cc33 so that you have a floating gradient all the way down but always float from #00ff00 over orange #ff9900 to #ff0000 (orange in the middle could also be omitted).

Share Improve this question edited Jan 28, 2013 at 12:20 asked Jan 27, 2013 at 19:40 user659025user659025 2
  • 3 I don't think there is a single answer to your question. It really depends on how you want to go from one color range to another, because in the example you gave, there isn't a single range, there are two, for Red and Green. Therefore, you need to define the rules by which you want to transition from one range to another. According to your screenshot, these rules might be defined by the Gradient Type and the Smoothness. And you need rules that can acodate three ranges, one for each color (Red, Green, and Blue). In some cases, you might even need four ranges (CMYK). – Ismael Ghalimi Commented Jan 27, 2013 at 19:45
  • It may be helpful for us if you told us why you need to do this in the first place, also. – jeremy Commented Jan 27, 2013 at 19:46
Add a ment  | 

5 Answers 5

Reset to default 4

One way is to think of the colours like a segment of a circle and then make use of Math.cos or Math.sin.

function toColour(x) {
    var pad = function (x) {
        x = x.toString(16);
        if (x.length === 1) {
            return '0' + x;
        }
        return x;
    }, r, g, b;
    r = ~~(255 * Math.cos(Math.PI * x / 20)); // cos(0) = 1, cos(π/2) = 0
    g = ~~(255 * Math.sin(Math.PI * x / 20)); // sin(0) = 0, sin(π/2) = 1
    b = 0;
    return '#' + pad(r) + pad(g) + pad(b);
}

// test the gradient produced
for (var i = 0; i <= 10; ++i) {
    document.body.appendChild(
        document.createElement('div')
    ).setAttribute('style', 'width: 400px;height: 5px;background: '+toColour(i)+';');
}

See this fiddle for test results (thanks to MikeM)

Just for fun:

function toHex( n ) {
    var r = 255 - ( n / 10 * 255 | 0 ); 
        g = n / 10 * 255 | 0;  

    return '#' + 
        ( r ? ( r = r.toString(16), r.length == 2 ? r : '0' + r ) : '00' ) +
        ( g ? ( g = g.toString(16), g.length == 2 ? g : '0' + g ) : '00' ) + '00'
}

See it here (for what its worth): http://jsfiddle/xD6Uf/

Update

Inspired by Samuel Edwin Ward's use of HSL, the following function adapts hslToRgb from Brian Grinstead's MIT Licensed tinycolor.js:

Note: this function is not intended to be the finished article or represent good practice, it is a proof of concept only. There is no bounds checking and few concessions to readability.

n is a value from 0 to 10, and start, middle and end are each a hue value from 0 - 360.
See Mother-effing hsl to select hue, saturation and lightness values to experiment with.

function toHex( n ) {
    var r, g, b, p, q,
        start = 0,          // 0 - 360 (red 0)
        middle = 36,        // 0 - 360 (orange 36, use 0 or null for no middle)
        end = 120,          // 0 - 360 (green 120)
        saturation = 1,     // 0 - 1
        lightness = 0.5,    // 0 - 1
        hue = ( middle ?
            n > 5 ? ( n -= 5, n / 5 * ( end - middle ) ) + middle :
                ( n / 5 * ( middle - start ) ) + start :
                    ( n / 10 * ( end - start ) ) + start ) / 360;

    function hue2hex( p, q, h ){
        if ( h < 0 ) h++;
        else if ( h > 1 ) h--;
        h = ( h < 1/6 ? p + ( q - p ) * 6 * h : h < 1/2 ? q :
            h < 2/3 ? p + ( q - p ) * ( 2/3 - h ) * 6 : p ) * 255 | 0;
        return h ? ( h = h.toString(16), h.length > 1 ? h : '0' + h ) : '00';
    }

    if ( saturation === 0 ) {
        n = lightness * 255 | 0;
        r = g = b = n ?
            ( n = n.toString(16), n.length > 1 ? n : '0' + n ) : '00'; 
    } else {
        q = lightness < 0.5 ? lightness * ( 1 + saturation ) :
            lightness + saturation - lightness * saturation;
        p = 2 * lightness - q;
        r = hue2hex( p, q, hue + 1/3 );
        g = hue2hex( p, q, hue );
        b = hue2hex( p, q, hue - 1/3 );
    }

    return '#' + r + g + b;
}

Example

toHex(0);    // "#ff0000"
toHex(5);    // "#ff9900"
toHex(10);   // "#00ff00"

jsfiddle

It looks like you want to interpolate between colors.

You could just take the color values to be numbers and do an interpolation between them, but I think the results would be very odd.

You'll probably want to convert your colors from RGB to another color space and scale the hue ponent(s). HSL would be a nice choice because CSS3 supports specifying colors in that space.

I put code for both approaches up on jsfiddle.

These are the important parts:

/* numeric interpolation */
for (var value = 0; value < 10; value += 10/40) {
    var color = (10-value)/10*(0xff0000-0xff00)+(0x00ff00),
        hex = Math.floor(color).toString(16);

    while (hex.length < 6) {
        hex = "0" + hex;
    }

    /* hex now holds the hex code */
  }

/* hue interpolation */

for (var value = 0; value < 10; value += 10/40) {
    var hue = value/10*120, /* red is 0; green is 120 */
        color = 'hsl(' + hue + ', 100%, 50%)';

    /* hsl now holds the hsl color specification */
}

If you like you can use a fancier approach to interpolating the values than the simple linear formula I used (where x is the input scale and y is the output scale):

y = (x - minX) / (maxX - minX) * (maxY-minY) + minY

So basically you have some range in hex with two variables:

var startHex = "0x00ff00";
var endHex = "0xff0000"
int startInt = parseInt(startHex, 16);
int endInt = parseInt(endHex, 16);
int newInt = startInt + (endInt-startInt)/100 * floatValue; // floatValue is number between 10.0 and 0.0
var newHex = newDec.ToString(16);

I am assuming you intended for 100 increments possible between start and end. This could be done much more cleanly, but for illustration I broke it all out. In practice I would write this in 1-2 lines.

If you want to rely on the browser's rendering engine, you could use HTML5's canvas and createLinearGradient. One advantage of this approach is the ability to use color stops (though you could do this mathematically if you really wanted also).

var canvas = document.createElement('canvas'),
    context = canvas.getContext('2d');

canvas.height = 100; canvas.width = 1;

var gradient = context.createLinearGradient(0,0,0,100);

// color stops
gradient.addColorStop(0, '#00ff00');
gradient.addColorStop(0.5, '#ff9900');
gradient.addColorStop(1, '#ff0000');

context.fillStyle = gradient;
context.fillRect(0,0,1,100);

var point = 10.0,
    colorData = context.getImageData(0, parseInt(point*canvas.height*.1, 10), 1, 1).data;

// rgba ( colorData[0], colorData[1], colorData[2], colorData[3] )

You can find the exact rgba coordinates of the color in colorData[0] (red), colorData[1] (blue), colorData[2] (green) and then easily convert those to hex values.

If you end up using this solution, set point to a number in the range of 0 to 9.9.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745121794a4612457.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信