Reputation: 347
The problem: I have a four stop gradient with colour values at 0%, 33%, 66% and 100%. I want to find out the colour value at any point in this gradient using a percentage.
I think I require some kind of multi stop hue interpolation but was wondering if there was a simple JavaScript way of doing it before I dive in head first and start trying to write my own.
The colour stops I am working with:
//0%
var stop1 = { r: 25, g: 47, b: 97 };
//33%
var stop2 = { r: 75, g: 183, b: 183 };
//66%
var stop3 = { r: 237, g: 120, b: 87 };
//100%
var stop4 = { r: 209, g: 74, b: 88 };
Upvotes: 3
Views: 1057
Reputation: 347
I also found this nice little library for playing about with colours: chroma.js
Upvotes: 0
Reputation: 386858
You could use the delta of the interval of the steps and calculate the color with the right ratio.
How it works.
For example we are looking for the color of 70 % and first, we get the interval of
[66, 100]
Then build the ratio by
the delta of percent and the left interval (
left
)70 - 66 => 4
the delta of the right interval and percent (
right
)100 - 70 => 30
delta of right and left interval (
delta
)100 - 66 => 34
with the above generated ratios, it is possible to calculate the right color inbetween of two colors with the parts.
(color of left interval * right + color of right interval * left) / delta => color
Repeat the last step for all colors and return the result.
Working example:
* denotes given colors, hover shows percent value and RGB value.
function getColor(percent) {
function getInterval(range) {
function getRatio(color) {
return Math.floor((colors[range[0]][color] * right + colors[range[1]][color] * left) / delta);
}
var left = percent - range[0],
right = range[1] - percent,
delta = range[1] - range[0];
return { r: getRatio('r'), g: getRatio('g'), b: getRatio('b') };
}
return colors[percent] || getInterval(stops.reduce(function (r, a, i, aa) {
return a < percent ? [a, aa[i + 1]] : r;
}, [0, 0]));
}
var stops = [0, 33, 66, 100],
colors = { 0: { r: 25, g: 47, b: 97 }, 33: { r: 75, g: 183, b: 183 }, 66: { r: 237, g: 120, b: 87 }, 100: { r: 209, g: 74, b: 88 } },
i, color, rgb;
for (i = 0; i <= 100; i++) {
color = getColor(i),
rgb = ['r', 'g', 'b'].map(function (k) { return color[k]; });
document.body.innerHTML += '<span style="color: #fff; background-color: rgb(' + rgb + ');" title="' + (colors[i] ? '* ' : '') + i + ' % rgb(' + rgb.join(', ') + ')">' + (colors[i] ? '* ' : ' ') + '</span>';
}
Upvotes: 2