I have a random color overlay on the media-boxes of this site.
http://www.reportageborsen.se/reportageborsen/wordpress/
I had some really good help from the mates here at stackoverflow wich resulted in this script:
var getRandomInRange = function(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
$('.media-box').each(function() {
var mediaBox = $(this);
var mask = mediaBox.find('.mask');
var hue = 'rgb(' + getRandomInRange(100, 255) + ',' + getRandomInRange(100, 255) + ',' + getRandomInRange(100, 255) + ')';
mask.css({
backgroundColor : hue,
opacity : 0.7
});
mediaBox.hover(function() {
mask.stop(true, true).fadeIn();
}, function() {
mask.stop(true, true).fadeOut();
});
});
Fiddle link: http://jsfiddle.net/b5ZPq/3/
However, I would love to have more of the brighter colors and less of the greyish ones. I understand that it can be done with HSL values instead of RGB values.
So I tried to convert the css background rgb values to hsl values and also converted the script, but I didn't get it to work.
var getRandomInRange = function(min, max) {
return Math.floor(Math.random() * (max - min + 1), 10) + min;
};
$('.media-box').each(function() {
var mediaBox = $(this);
var mask = mediaBox.find('.mask');
var hue = 'hsl(' + getRandomInRange(0, 360) + ',' + getRandomInRange(70, 100) + '%' + getRandomInRange(45, 55) + '%)';
mask.css({
backgroundColor: hue,
opacity: 0.7
});
mediaBox.hover(function() {
mask.stop(true, true).fadeIn();
}, function() {
mask.stop(true, true).fadeOut();
});
});
http://jsfiddle.net/zolana/Kc9U4/5/
(the fiddle, updated, working:
http://jsfiddle.net/zolana/Kc9U4/9/
)
(I'm not looking for a script that converts all the RGB values to HSL values (I know there are scripts with that purpose) rather to have a solid script for this specific task.)
Remember that when you use HSL colors (and others), you need to separate each value with a comma and use the correct notation. In this case, it looks like the following.
hsl ( int hue , int saturation % , int lightness % )
You were missing a comma after the second argument (specifically right after the percent sign).
var hue = 'hsl(' + getRandomInRange(0, 360) + ',' + getRandomInRange(70, 100) + '%,' + getRandomInRange(45, 55) + '%)';
http://jsfiddle.net/b5ZPq/4/
Check out this code I wrote:
function randomColor(){
var h = Math.random();
var s = 0.99;
var v = 0.99;
h = h + 0.618033988749895;
h = h % 1;
var r, g, b;
var i = Math.floor(h * 6);
var f = h * 6 - i;
var p = v * (1 - s);
var q = v * (1 - f * s);
var t = v * (1 - (1 - f) * s);
switch(i % 6){
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;
case 5: r = v, g = p, b = q; break;
}
return "rgba("+Math.floor(r*255)+","+ Math.floor(g*255)+","+ Math.floor(b*255)+","+ 0.2+")";
}
It generates a random Hue value, constant values for s and v. So this returns a random bright rgb color. Also the colors are bright and different because I have used the golden ratio. Try to use this and get back if you get any problems.
Related
Is it possible to "add" another color and essentially have it pick up where it left off? For example, say you start with 30 items to color, but the user adds a 31st item. Is there a way to have it continue with its currently generated set and simply generate a 31st color that adheres to the prior hues and steps?
I found an example, but I don’t understand how it can be used
function rainbow(numOfSteps, step) {
// This function generates vibrant, "evenly spaced" colours (i.e. no clustering). This is ideal for creating easily distinguishable vibrant markers in Google Maps and other apps.
// Adam Cole, 2011-Sept-14
// HSV to RBG adapted from: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
var r, g, b;
var h = step / numOfSteps;
var i = ~~(h * 6);
var f = h * 6 - i;
var q = 1 - f;
switch(i % 6){
case 0: r = 1; g = f; b = 0; break;
case 1: r = q; g = 1; b = 0; break;
case 2: r = 0; g = 1; b = f; break;
case 3: r = 0; g = q; b = 1; break;
case 4: r = f; g = 0; b = 1; break;
case 5: r = 1; g = 0; b = q; break;
}
var c = "#" + ("00" + (~ ~(r * 255)).toString(16)).slice(-2) + ("00" + (~ ~(g * 255)).toString(16)).slice(-2) + ("00" + (~ ~(b * 255)).toString(16)).slice(-2);
return (c);
}
It's not easy to have 32 colors that actually look unique. Especially if all you want to do is change the hue you can see here are 32 colors changing only the hue
const hsl = (h, s, l) => `hsl(${h * 360 | 0},${s * 100}%,${l * 100}%)`;
for (let i = 0; i < 32; ++i) {
const div = document.createElement('div');
div.style.background = hsl(i / 32, 1, 0.5);
div.className = 'b';
document.body.appendChild(div);
}
.b {
width: 32px;
height: 32px;
display: inline-block;
}
You can try using a different color space like HCL but it's just as problematic
for (let i = 0; i < 32; ++i) {
const div = document.createElement('div');
div.style.background = chroma.hcl(i / 32 * 360, 80, 70).css();
div.className = 'b';
document.body.appendChild(div);
}
.b {
width: 32px;
height: 32px;
display: inline-block;
}
<script src="https://cdn.jsdelivr.net/npm/chroma-js#2.1.0/chroma.min.js"></script>
I would suggest you consider changing the brightness as well. For example 16 light colors and 16 dark colors
But more I'd suggest whatever you're doing you consider adding patterns. For example plane vs checked vs vertical stripes vs horizontal stripes vs diagonal stripes vs diamonds, etc...
Or symbols ♠️ ♦️ ♣️ ♥ ◾️ ● ▲ etc..
As for choosing colors with the most distance you can reverse the bits of an int but you need to choose the range upfront. For example if we pick a range of 0 to 255 (8 bits) then by reversing the bits the first 2 items will be the maximum distance apart. (0 and 128). The next 2 will be the the maximum distance between those 2 (64 and 192). The next 4 will be the max between each of those (32, 96, 160, 224), etc...
See this
If you want to keep the hue, it would be easier to start as HSV/HSL and then convert to RGB:
https://mika-s.github.io/javascript/colors/hsl/2017/12/05/generating-random-colors-in-javascript.html
Convert HSB/HSV color to HSL
HSL to RGB color conversion
function generateHslaColors (saturation, lightness, alpha, amount) {
let colors = []
let huedelta = Math.trunc(360 / amount)
for (let i = 0; i < amount; i++) {
let hue = i * huedelta
colors.push(`hsla(${hue},${saturation}%,${lightness}%,${alpha})`)
}
return colors
}
/**
* Converts an HSL color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes h, s, and l are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
*
* #param {number} h The hue
* #param {number} s The saturation
* #param {number} l The lightness
* #return {Array} The RGB representation
*/
function hslToRgb(h, s, l){
var r, g, b;
if(s == 0){
r = g = b = l; // achromatic
}else{
var hue2rgb = function hue2rgb(p, q, t){
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
I found an example, but I don’t understand how it can be used
You need to decide how many different segments you want to split your gradient in. Then you to loop over that total and generate each segment of the gradient like this:
function rainbow(numOfSteps, step) {
// This function generates vibrant, "evenly spaced" colours (i.e. no clustering). This is ideal for creating easily distinguishable vibrant markers in Google Maps and other apps.
// Adam Cole, 2011-Sept-14
// HSV to RBG adapted from: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
var r, g, b;
var h = step / numOfSteps;
var i = ~~(h * 6);
var f = h * 6 - i;
var q = 1 - f;
switch(i % 6){
case 0: r = 1; g = f; b = 0; break;
case 1: r = q; g = 1; b = 0; break;
case 2: r = 0; g = 1; b = f; break;
case 3: r = 0; g = q; b = 1; break;
case 4: r = f; g = 0; b = 1; break;
case 5: r = 1; g = 0; b = q; break;
}
var c = "#" + ("00" + (~ ~(r * 255)).toString(16)).slice(-2) + ("00" + (~ ~(g * 255)).toString(16)).slice(-2) + ("00" + (~ ~(b * 255)).toString(16)).slice(-2);
return (c);
}
const total = 100;
for (let i = 0; i < total; i++) {
const $div = document.createElement('div');
$div.className = 'box';
$div.style.background = rainbow(total, i);
document.body.appendChild($div);
}
.box {
position: relative;
width: 100%;
height: 10px;
}
I've been reading the questions here about how to generate random colors in JS/JQuery. But I want to generate only darken colors avoiding the black, yellow and gray range colors, in order to be able to draw areas in google maps with different colors.
Thanks
var hue = Math.floor(Math.random() * 360),
saturation = Math.floor(Math.random() * 100),
lightness = Math.floor(Math.random() * 50),
color = "hsl(" + hue + ", " + saturation + "%, " + lightness + "%)";
That was to generate a random hsl color. But if you want to darken an existing rgb color the best thing to do is to convert it to hsl and then setting its lightness value according to your needs. Have fun with these functions:
function rgbToHsl(r, g, b) {
var maxRGB = Math.max(r, g, b),
minRGB = Math.min(r, g, b),
tmp, h, s, l;
tmp = maxRGB - minRGB;
l = (maxRGB + minRGB)/255;
if (tmp) {
s = Math.round(tmp/(l < 1 ? l : 2 - l))/255;
if (r === maxRGB) h = (g - b)/tmp;
else if (g === maxRGB) h = 2 + (b - r)/tmp;
else h = 4 + (r - g)/tmp;
h = (h < 0 ? h + 6 : h)*60 % 360;
} else h = s = 0;
l /= 2;
return [h, s, l];
}
function hslToRgb(h, s, l) {
if (!s) return r = g = b = l*255;
var q = l < .5 ? l*(1 + s) : l + s - l*s,
p = 2*l - q;
for (var i = 120, t, c = []; i >= -120; i -= 120) {
t = h + i;
if (t < 0) t += 360;
else if (t >= 360) t -= 360;
if (t < 60) c.push(p + (q - p)*t/60);
else if (t < 180) c.push(q);
else if (t < 240) c.push(p + (q - p)*(240 - t)/60);
else c.push(p);
}
return [c[0]*255, c[1]*255, c[2]*255];
}
Here, s and l ranges from 0 to 1, r, g and b from 0 to 255 and h from 0 to 359.
According to duplicate taken from comment of jj__?
function getGMapRandomColor() {
return 'hsla(' + Math.floor(Math.random()*360) + ', 100%, 70%, 1)';
}
First define the RGB ranges you do want, and once you have those defines just generate random values within those ranges. Or define the ranges you don't want and keep looping till you find a colour that fits those criteria, a lot less efficient, but quite a bit easier to program if efficiency is not an issue.
Where's the problem? Just generate 3 random numbers, maybe in the range from, let's say 30 to 150, so you will only get relatively low values for R, G and B, and block "black-like" colors. Then you would just have to check if these three values fall into the range of your defined blacklisted color ranges like yellow or gray.
For simplicity of implementation and thoroughness, I can't recommend this script highly enough:
David Merfeld's randomColor
Choose between hex or rgb, add in some alpha, specify light or dark palettes, avoid repeats, etc.
I would like to change pixels of an HTML5 canvas to an hsl value. It could be any hsl value that is chosen by the user.
I can get the canvas imageData with var imageData = canvas.getImageData(0, 0, 200, 200);
But the imageData.data array contains values in rgba. Actually each value in the array is a byte so -
data[0] = r, data[1] = b, data[2] = g, data[3] = a, data[4] = r, data[5] = b, data[6] = g, data[7] = a etc.
Is there an api that can be used to manipulate imageData? An api that would abstract the raw data so that - data[0] = rgba, data[1] = rgba etc?
And that might have methods like - data[0].setValueHSL(60, 100%, 50%);
If this api does not exist is there a class that can create/represent an hsl value and which can convert the value to rgb?
I am not sure if you are still looking for the answer since this was asked a long time ago. But I was trying to do the same and encountered the answer on Why doesn't this Javascript RGB to HSL code work?, this should do the trick :
function rgbToHsl(r, g, b) {
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b);
var min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if (max == min) {
h = s = 0; // achromatic
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return 'hsl(' + Math.floor(h * 360) + ',' + Math.floor(s * 100) + '%,' + Math.floor(l * 100) + '%)';
}
You could write one its as simple as this
parseImageData = function(imageData) {
var newImageData = [];
for ( var i = imageData - 1; i>0; i-4) {
newImageData.push([ imageData[i],
imageData[i-1],
imageData[i-2],
imageData[i-3] ]);
}
return newImageData;
}
then if you want to convert it back
parseNewImageData = function ( newImageData ) {
var imageData = [];
for ( var i = newImageData - 1; i>=0; --i) {
imageData.push( imageData[i][0] );
imageData.push( imageData[i][1] );
imageData.push( imageData[i][2] );
imageData.push( imageData[i][3] );
}
return imageData;
}
super easy and you can make it do specifically what you need it to!
I hope this helps!
I want to take a color and generate random deviations from that color with JavaScript. For example, say I have a color #33CCFF, I want to feed that number into the script and get numbers like #8AE2FF, #00AAE2, and #7BDEFF. Basically, the hue should stay the same, but the saturation/brightness should fluctuate a bit.
What's the fastest and simplest way to generate these numbers?
Convert your RGB color to HSL, keep the Hue, derive Saturation and Lightness(Brightness) with a small random number, for instance, then convert back to RGB.
For converting: http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSL
Bonus, the code for conversion: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
Honestly I don't know how Hex codes work out saturation/brightness, so I would convert to HSL:
http://serennu.com/colour/rgbtohsl.php
change up the ones you want, and change it back. The only major drawback I see is the possibility that the HSL doesn't exist in the Hex field after you've changed it.
As in,
HSL colour space has only 360 x 100 x 100 = 3,600,000
colours in it whilst the RGB colour space has 256 x 256 x 256 =
16,77,216 colours in it, That's four half times as many.
I know this question is one year old, but I was looking around for a solution and couldn't find it.
But basing on suggestions here and there (mainly on SO) I created ready to use script.
NOTICE 1: colorToRGB function is unreliable. I found it in SO (source attached). I changed hex values for some colors but I didn't want to check it for all of them. For best results always use hex value.
NOTICE 2: deviation in generateSimilarColor function is set just for my purposes. You can change it for better results.
NOTICE 3: Many functions are found on SO. I've just gathered them together and I'm providing links to corresponding questions.
JavaScript code below (testing environment on the bottom of the post):
/**
* Generates similar color based on passed one
*
* #param color accepts few formats, e.g. white, #ffffff or [255, 255, 255]
* #return hex value, e.g. #ffffff
*
* #author Carlos (StackOverflow)
*/
function generateSimilarColor(color) {
var rand = generateRandomInt(-5, 5);
if(rand < 0) rand -= 5;
else rand += 5;
var deviation = rand / 100;
if(!isArray(color) || color.length != 3) { // this is not [r, g, b] array
var hexNotation = colorToRGB(color);
if(!hexNotation) { // we couldn't find HEX value of this string based on color name
if(!isString(color) || color.length != 7 || color[0] != '#') { // this is not string in this format: #ffffff
return false;
}
else {
hexNotation = color;
}
}
color = hexToRgb(hexNotation);
if(!color) {
return false;
}
}
var hsl = rgbToHsl(color[0], color[1], color[2]);
// saturation
hsl[1] += deviation;
if(hsl[1] > 1) hsl[1] = 1 - Math.abs(deviation);
else if(hsl[1] < 0) hsl[1] = Math.abs(deviation);
// lightness
hsl[2] += deviation;
if(hsl[2] > 1) hsl[2] = 1 - Math.abs(deviation);
else if(hsl[2] < 0) hsl[2] = Math.abs(deviation);
color = hslToRgb(hsl[0], hsl[1], hsl[2]);
var hex = rgbToHex(color[0], color[1], color[2]);
return hex;
}
/**
* Returns a random integer between min and max
* Using Math.round() will give you a non-uniform distribution!
*
* #source http://stackoverflow.com/questions/1527803/generating-random-numbers-in-javascript-in-a-specific-range
*/
function generateRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
/**
* #source: [slightly changed] http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
*/
function componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
/**
* #source: [slightly changed] http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
*/
function rgbToHex(r, g, b) {
r = parseInt(r);
g = parseInt(g);
b = parseInt(b);
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
/**
* #source http://stackoverflow.com/questions/1058427/how-to-detect-if-a-variable-is-an-array
*/
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
/**
* #source http://stackoverflow.com/questions/4059147/check-if-a-variable-is-a-string
*/
function isString(str) {
return (typeof str == 'string' || str instanceof String);
}
/**
* #source: http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb slightly change
*/
function hexToRgb(hex) {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? [
parseInt(result[1], 16),
parseInt(result[2], 16),
parseInt(result[3], 16)
] : false;
}
/**
* Converts an RGB color value to HSL. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes r, g, and b are contained in the set [0, 255] and
* returns h, s, and l in the set [0, 1].
*
* #param Number r The red color value
* #param Number g The green color value
* #param Number b The blue color value
* #return Array The HSL representation
*
* #source http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
*/
function rgbToHsl(r, g, b) {
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
}else{
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h, s, l];
}
/**
* Converts an HSL color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes h, s, and l are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
*
* #param Number h The hue
* #param Number s The saturation
* #param Number l The lightness
* #return Array The RGB representation
*/
function hslToRgb(h, s, l) {
var r, g, b;
if(s == 0){
r = g = b = l; // achromatic
}else{
function hue2rgb(p, q, t){
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return [r * 255, g * 255, b * 255];
}
/**
* #source [slightly changed] http://stackoverflow.com/questions/1573053/javascript-function-to-convert-color-names-to-hex-codes
*/
function colorToRGB(color) {
var colors = {"aliceblue":"#f0f8ff","antiquewhite":"#faebd7","aqua":"#00ffff","aquamarine":"#7fffd4","azure":"#f0ffff",
"beige":"#f5f5dc","bisque":"#ffe4c4","black":"#000000","blanchedalmond":"#ffebcd","blue":"#0000ff","blueviolet":"#8a2be2","brown":"#603311","burlywood":"#deb887",
"cadetblue":"#5f9ea0","chartreuse":"#7fff00","chocolate":"#d2691e","coral":"#ff7f50","cornflowerblue":"#6495ed","cornsilk":"#fff8dc","crimson":"#dc143c","cyan":"#00ffff",
"darkblue":"#00008b","darkcyan":"#008b8b","darkgoldenrod":"#b8860b","darkgray":"#a9a9a9","darkgreen":"#006400","darkkhaki":"#bdb76b","darkmagenta":"#8b008b","darkolivegreen":"#556b2f",
"darkorange":"#ff8c00","darkorchid":"#9932cc","darkred":"#8b0000","darksalmon":"#e9967a","darkseagreen":"#8fbc8f","darkslateblue":"#483d8b","darkslategray":"#2f4f4f","darkturquoise":"#00ced1",
"darkviolet":"#9400d3","deeppink":"#ff1493","deepskyblue":"#00bfff","dimgray":"#696969","dodgerblue":"#1e90ff",
"firebrick":"#b22222","floralwhite":"#fffaf0","forestgreen":"#228b22","fuchsia":"#ff00ff",
"gainsboro":"#dcdcdc","ghostwhite":"#f8f8ff","gold":"#ffd700","goldenrod":"#daa520","gray":"#808080","green":"#008000","greenyellow":"#adff2f",
"honeydew":"#f0fff0","hotpink":"#ff69b4",
"indianred ":"#cd5c5c","indigo ":"#4b0082","ivory":"#fffff0","khaki":"#f0e68c",
"lavender":"#e6e6fa","lavenderblush":"#fff0f5","lawngreen":"#7cfc00","lemonchiffon":"#fffacd","lightblue":"#add8e6","lightcoral":"#f08080","lightcyan":"#e0ffff","lightgoldenrodyellow":"#fafad2",
"lightgrey":"#d3d3d3","lightgreen":"#90ee90","lightpink":"#ffb6c1","lightsalmon":"#ffa07a","lightseagreen":"#20b2aa","lightskyblue":"#87cefa","lightslategray":"#778899","lightsteelblue":"#b0c4de",
"lightyellow":"#ffffe0","lime":"#00ff00","limegreen":"#32cd32","linen":"#faf0e6",
"magenta":"#ff00ff","maroon":"#800000","mediumaquamarine":"#66cdaa","mediumblue":"#0000cd","mediumorchid":"#ba55d3","mediumpurple":"#9370d8","mediumseagreen":"#3cb371","mediumslateblue":"#7b68ee",
"mediumspringgreen":"#00fa9a","mediumturquoise":"#48d1cc","mediumvioletred":"#c71585","midnightblue":"#191970","mintcream":"#f5fffa","mistyrose":"#ffe4e1","moccasin":"#ffe4b5",
"navajowhite":"#ffdead","navy":"#000080",
"oldlace":"#fdf5e6","olive":"#808000","olivedrab":"#6b8e23","orange":"#ffa500","orangered":"#ff4500","orchid":"#da70d6",
"palegoldenrod":"#eee8aa","palegreen":"#98fb98","paleturquoise":"#afeeee","palevioletred":"#d87093","papayawhip":"#ffefd5","peachpuff":"#ffdab9","peru":"#cd853f","pink":"#ffc0cb","plum":"#dda0dd","powderblue":"#b0e0e6","purple":"#800080",
"red":"#ff0000","rosybrown":"#bc8f8f","royalblue":"#4169e1",
"saddlebrown":"#8b4513","salmon":"#fa8072","sandybrown":"#f4a460","seagreen":"#2e8b57","seashell":"#fff5ee","sienna":"#a0522d","silver":"#c0c0c0","skyblue":"#87ceeb","slateblue":"#6a5acd","slategray":"#708090","snow":"#fffafa","springgreen":"#00ff7f","steelblue":"#4682b4",
"tan":"#d2b48c","teal":"#008080","thistle":"#d8bfd8","tomato":"#ff6347","turquoise":"#40e0d0",
"violet":"#8F00FF",
"wheat":"#f5deb3","white":"#ffffff","whitesmoke":"#f5f5f5",
"yellow":"#ffff00","yellowgreen":"#9acd32"};
if (typeof colors[color.toLowerCase()] != 'undefined')
return colors[color.toLowerCase()];
return false;
}
Testing environment (with jQuery required):
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Color Test</title>
<script type="text/javascript" src="js/libs/jquery.js"></script>
<script type="text/javascript" src="js/color.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var i, j, colors = ['blue', 'orange', 'green', 'red', 'yellow', 'brown', 'violet'];
for(i = 0; i < colors.length; i++) {
for(j = 0; j < 3; j++) {
$("body").append('<div style="height: 20px; background-color: ' + generateSimilarColor(colors[i]) + ';"></div>');
}
$("body").append('<div style="height: 20px;"></div>');
}
});
</script>
</head>
<body></body>
</html>
Any bugs or suggestions - please write.
I have an HTML5 canvas with a large amount of objects and images being drawn and moved around. One of these things happens to be a rectangle with a single solid color (yellow) that I would like to make fade out and disappear.
Should I use timers, clear the whole page and redraw everything and make box a little faded each time or is there a way to not clear the whole canvas and redraw?
Redrawing needs to be done anyhow, since <canvas> has been designed that way. It's pixel-based, so you can't just say 'make that rectangle lighter' or something like that.
An interval would be appropriate: http://jsfiddle.net/pimvdb/eGjak/84/.
function fadeOutRectangle(x, y, w, h, r, g, b) {
var steps = 50,
dr = (255 - r) / steps, // how much red should be added each time
dg = (255 - g) / steps, // green
db = (255 - b) / steps, // blue
i = 0, // step counter
interval = setInterval(function() {
ctx.fillStyle = 'rgb(' + Math.round(r + dr * i) + ','
+ Math.round(g + dg * i) + ','
+ Math.round(b + db * i) + ')';
ctx.fillRect(x, y, w, h); // will redraw the area each time
i++;
if(i === steps) { // stop if done
clearInterval(interval);
}
}, 30);
}
fadeOutRectangle(10, 10, 100, 100, 123, 213, 50);
Here is a fun little code snippet I wrote to get all the steps using rgb or hex colors and you specify the steps.
`
/* to and from are rgb or hex color strings
steps is an integer specifying the number of steps it should take to get to the color */
var getTransitionSteps = function(colorFrom, colorTo, steps) {
var stepList = [],
from = parseColor(colorFrom),
to = parseColor(colorTo);
var stepAmountR = Math.floor((to.R - from.R) / steps);
var stepAmountG = Math.floor((to.G - from.G) / steps);
var stepAmountB = Math.floor((to.B - from.B) / steps);
stepList.push(colorFrom);
for (var i = 0; i <= steps; i++) {
var minMax;
// Red
minMax = stepAmountR > 0 ? Math.min : Math.max;
from.R = minMax(from.R + stepAmountR, to.R);
// Green
minMax = stepAmountG > 0 ? Math.min : Math.max;
from.G = minMax(from.G + stepAmountG, to.G);
// Blue
minMax = stepAmountB > 0 ? Math.min : Math.max;
from.B = minMax(from.B + stepAmountB, to.B);
stepList.push(from.isHex ? rgbToHex(from.R, from.G, from.B) : "rgb(" + from.R + ", " + from.G + ", " + from.B + ")");
}
stepList.push(colorTo);
return stepList;
};
var parseColor = function(color) {
var isHex = color.indexOf("#") != -1;
if (isHex) {
return { isHex: true, R: hexToR(color), G: hexToG(color), B: hexToB(color) };
} else {
var parsed = color
.substring(4, color.length - 1)
.replace(/ /g, '')
.split(',');
return {
R: parseInt(parsed[0]),
G: parseInt(parsed[1]),
B: parseInt(parsed[2])
};
}
};
var hexToR = function(h) { return parseInt((cutHex(h)).substring(0, 2), 16); };
var hexToG = function(h) { return parseInt((cutHex(h)).substring(2, 4), 16); };
var hexToB = function(h) { return parseInt((cutHex(h)).substring(4, 6), 16); };
var cutHex = function(h) { return (h.charAt(0) == "#") ? h.substring(1, 7) : h; };
function componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
function rgbToHex(r, g, b) {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
`
then you can use them in a setTimeout or interval to transition the background color between two colors.