JS : from RGB Blue to RGB Red - javascript

I'm trying to convert RGB color from blue (rgba(0,0,255)) to red (rgba(255,0,0)) on JS mouseenter, progressively.
So, each time the mouse enter an element, it "increments" its background color, from blue to green and then to red.
With a WIP live demo : http://codepen.io/enguerranws/pen/ZQOBwe
Here's what I've done so far :
function onGridDone(){
var gridders = document.querySelectorAll('.gridder');
for(var i = 0; i < gridders.length; i++){
gridders[i].addEventListener('mouseenter', onHover );
}
}
function onHover () {
var currentColor = this.style.backgroundColor,
currentColorArr = currentColor.replace(/[^\d,]/g, '').split(',');
R = currentColorArr[0],
G = currentColorArr[1],
B = currentColorArr[2];
console.log(R,G,B);
if(B > 0) B = B-10;
var indic = 255-B;
G = indic/2;
R = indic;
this.style.backgroundColor = "rgb("+R+","+G+","+B+")";
}
I've tried multiple things, but basically, I want my color to go from rgba(0,0,255), then rgba(0,255,130), then rgba(255,130,0) and finally rgba(255,0,0) (so, from blue to green then green to red).
I know I could do multiple if/else statements to check each case, but I'm just wandering if there'is a more efficient way using maths ?
I'm not trying to do any animations / transitions.

To make use of a mathematical formula, it is helpful to have some numeric indicator of progress, e.g., from 0 to 255 and then calculate the colors from that.
It is not exactly what you "basically" asked for but it illustrates what I mean: Let's say the red component would increase linearly from 0 to 255 during the process. Then you could look at an existing field's red value and know immediately where you are. If you wanted to move through green, this should be close to what you want to do:
// assume r,g,b are the current values
var progress = r;
progress += 1; // of course you can increment faster
r = progress;
g = 255 - (255 * (Math.abs(progress-127)/128))
b = 255 - progress;
This way you will not pass the color rgba(255,130,0) as in your question. However, I think it might still solve your problem. r increases linearly, b decreases linearly and g first increases and then decreases after 50% of the process.

Related

Calculating part of area inside zone. Fabric.js/Canvas

I have an area (in this case, the Kitchen area with yellow borders), inside this area there are other shapes (numbered 1 and 2 light blue color) that divide the kitchen area into several parts (A, B, C). I need to calculate separately the area of each Green part.
I use a js worker to calculate the area of the blue and green zone(in total). But I need to somehow calculate these divided green zones separately.
To calculate area I use getImageData() where I get pixels of the entire kitchen area. Then I loop the pixels and filter. Depending on the color of the pixel, I add it to the area result of either the blue or green zone.
Are there ready-made solutions in Fabric.js or Canvas for counting a part of a zone in another zone? If not, do you have any ideas how to implement it?
Here is a small piece of code with a pixel cycle:
calculateCoverage: function (options) {
options.oversampling = options.oversampling || 1;
var result = {},
pixel = new app.Color(),
oversamplingArea = Math.pow(options.oversampling, 2),
pixelCoverage, value,
i;
for (i = 0; options.imageData && i < options.imageData.data.length; i += 4) {
pixel.x = options.imageData.data[i];
pixel.y = options.imageData.data[i + 1];
pixel.z = options.imageData.data[i + 2];
pixel.a = options.imageData.data[i + 3];
// Apply binary filtering to the pixel value.
pixel.filter(app.Color.BinaryFilter).filter(app.Color.BinaryFilterAlpha);
// Ignore low alpha pixels.
if (!pixel.a) {
continue;
}
pixelCoverage = this.getPixelCoverageType(pixel, options.types);
value = pixel.a / 255 / oversamplingArea;
if (!result[pixelCoverage]) {
result[pixelCoverage] = 0;
}
// Iterate pixel coverage data.
result[pixelCoverage] += value;
}
return result;
}

Obtain 50% of a color hex value without using transparency

I need to obtain the color value of a 50% lighter version of an existing color hex. However it has to be 100% opaque, I cannot use opacity, rgba, hexa or hsla.
The scenario:
I draw routes on a map, each one with a different color, based on a hardcoded array of 48 possible hex values.
When one of these routes is being edited it should be shown as "disabled" (50% of the original color).
In the screen design, the reference values were #9775fa for the route color (one of the colors in the array) and #d5c7fd for the disabled color. This second color was obtained by the designer drawing a white layer with 50% opacity on top of the base color.
I tried to obtain this same value via JS, first using a lighten function, then an HSL one and finally lightening manually each of the RGB values of the base color. None of them really worked.
Using lighten, adding 62 of light I got a near value, but not the exact one.
Using HSL and lightening manually with 50% didn't work either.
These are the values I've got:
Base color: #9775fa
"Disabled color": #d5c7fd
Lighten by 62: #d5b3ff
HSL 50%: #e3b0ff
Ligheting 50% by hand: #e3b0ff
So, by the end, the real question is, Is it possible to be achieved?
Here is a "playground" and the full code of my experiments (the second column is the reference "disabled" color.
Thanks a lot!
I managed to get more accurate results by mixing the color with white at your given percentage.
I changed lightenByPercentage as follows:
let p = percentage / 100;
var r = "0x" + hex[0] + hex[1];
var g = "0x" + hex[2] + hex[3];
var b = "0x" + hex[4] + hex[5];
r = Math.ceil(256 * (1-p) + (r * p));
g = Math.ceil(256 * (1-p) + (g * p));
b = Math.ceil(256 * (1-p) + (b * p));
r = r <= 255 ? r : 255;
g = g <= 255 ? g : 255;
b = b <= 255 ? b : 255;
I'm not sure if your percentage was supposed to be how light it is or how dark it is, so if I got it the wrong way around swap p with 1-p here.

Javascript - Generate Different Shades of the Same Color

I would like to be able to call a function that takes a base color and returns an array of values that correspond to different shades of the same color. The array can contain either hex values or rgba() values. I would like to be able to input the amount of desired shades as well. The amount of shades would then also be able to be used as a metric to increment the shade. For example if I wanted the output have 3 different shades, the 1st shade would be 1/3 of the base.. however that math would work... Additionally, In some situations the 1st shade may need to be 100% transparent so I would like to accept an argument for the initial alpha. I've organized what I think would be the basic logic of the function but the math is unclear to me.
var buildColorStops = function (baseColor,numberOfValues,initialAlpha) {
var b = baseColor;
var n = numberOfValues //expected number of colors in the output. If n was 3 results would be [light blue, blue(base), dark blue] (# or rgba will work)
var d = 1 / n; // if number of values was 5 d would represent 1/5 of the base.
var ia = initialAlpha; // some situations may require the first color to be 100% transparent
var outputArray = [];
var i = 0;
while (i < n) {
if (i == 0) {
//...math on base color & incorporate initial alpha
outputArray.push("result of math on base")
}
else {
//...math on base color by incrementing d or 1/n
outputArray.push("result of math on base")
}
}
return outputArray;
}// end of buildColorStops
Shades can be generated by maintaining the ratio of the colors same. Suppose that your base color has (r,g,b) red, green, blue values.
So the ratio between the components is r:g:b. If you want to generate 10 shades then your shades would be.
(r/10, g/10, b/10)
(2*r/10, 2*g/10, 2*b/10)
(3*r/10, 3*g/10, 3*b/10)
(4*r/10, 4*g/10, 4*b/10) and so on
That's for the darker shades.
for lighter shades
(11*r/10, 11*g/10, 11*b/10)
(12*r/10, 12*g/10, 12*b/10)
(13*r/10, 13*g/10, 13*b/10) and so on
Check resulting values of r,g, b to not be more than 255 as lightening them increases their values.
In fact to avoid going over 255, you can check whichever of r,g,b is maximum and use that value to generate shades.
var max = Math.max(Math.max(r, Math.max(g,b)), 1);
var step = 255 / (max * 10)
(r * step, g * step, b * step)
(r * step * 2, g * step * 2, b * step * 2)
(r * step * 3, g * step * 3, b * step * 3)

Javascript algorithm/function to generate RGB values for a color along the visible light spectrum

I'm looking for a Javascript function/algorithm that will generate an RGB value for a color that's p% along the "visible light" spectrum.
For example - given the visible light spectrum...
... and given p=0, the function should return the RGB of red (0% across this spectrum. Given p=50, the function should approximately return the RBG of green (50% across the spectrum). Finally, given p=100, the function would return the RBG of violet.
The function doesn't need to be technically/scientifically precise - I'm just looking for a reasonably close approximation, with reasonable sensitivity. (E.g., the RGB for p=76 should be different than for p=77).
Ideally, I'm looking for a pure math formula. I.e., I'd like to avoid actually loading the image below onto a Canvas, than using context.getImageData to find the color of a pixel p% across the image.
Of course, I have no idea if that's possible...
You can use the HSVtoRGB function from this answer to create something easily.
function HSVtoRGB(h, s, v) {
var r, g, b, i, f, p, q, t;
if (arguments.length === 1) {
s = h.s, v = h.v, h = h.h;
}
i = Math.floor(h * 6);
f = h * 6 - i;
p = v * (1 - s);
q = v * (1 - f * s);
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 {
r: Math.round(r * 255),
g: Math.round(g * 255),
b: Math.round(b * 255)
};
}
function rainbow(p) {
var rgb = HSVtoRGB(p/100.0*0.85, 1.0, 1.0);
return 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')';
}
for(var i=0; i<100; i++) {
var span = document.createElement('span');
span.style.backgroundColor = span.style.color = rainbow(i);
span.textContent = 'i';
document.body.appendChild(span);
}
You can use this lib https://github.com/moagrius/Color to set a color and change hue (https://en.wikipedia.org/wiki/Hue).
Example:
var color = new Color('#FF0000'); // red
color.hue(150);
color.getRGB(); // rgb(0, 255, 128) cerulean
color.hue(300);
color.getRGB(); // rgb(255, 0, 255) violet
color.hue(0);
color.getRGB(); // rgb(255, 0, 0) red
Ideally, I'm looking for a pure math formula. I.e., I'd like to avoid
actually loading the image below onto a Canvas, than using
context.getImageData to find the color of a pixel p% across the image.
The visible light spectrum can't be put into a formula, because which color we see at a specific wavelength doesn't follow a mathematical term. The human eye and brain are much too complicated for that!
Yes, you can display every color using a red, green and blue light bulb like a PC screen. But that doesn't mean that yellow, cyan and magenta divide the light spectrum into accurate thirds! In computer science, however, this is easily assumed to be true.
This makes it easy to calculate on the colors:
Color hue [°] r g b hex
------------------------------------------
red 0 1 0 0 FF0000
yellow 60 1 1 0 FFFF00
green 120 0 1 0 00FF00
cyan 180 0 1 1 00FFFF
blue 240 0 0 1 0000FF
magenta 300 1 0 1 FF00FF
You can display the colors on a wheel: the left on is the one a programmer would prefer, the right one is more like a visible light spectrum:
Now you can easily see why the rgb value can't be calculated if you want to use the visible light spectrum: It doesn't follow any rule. Apart from that, there isn't just one visible light spectrum: Google it, you'll see that every image is slightly different.
I'd like to know what's the specific reason for getting the rgb value of a specific light wavelength: You can instead use the hue as the other answers suggest, but be aware that the hue has different proportions than the visible light spectrum.
If real proportions are important, you will have to load an image into a canvas (an image height of 1 pixel would be enough ;) ) or you can store all the values in a JSON array.

What code would I use to get the value of a color when an alpha at about half transparency is applied? [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
What code would I use to get the hex value of a color when an alpha at about half transparency is applied?
If I have a visual element (could be text or div with color fill, doesn't matter) and the color is set to black, 0x000000, and it's alpha is set to .4 or .5 and the background is solid white, 0xFFFFFF, the result would be a gray color. We can test this in Photoshop.
What I would like to know is what code would I use to get to that result?
I'm looking for something such as an equation:
newColor = foregroundColor * alpha * backgroundColor
Or something like in JavaScript, ActionScript or VBScript:
var color:uint = (0x888888 * .5) * 0x000000;
Part of the difficulty is solving this issue is the lack of fully understanding enough about hexadecimal and how it relates to color to solve it on my own.
UPDATE
Based on the answer below I've come up with this:
// set values
var topColorValue:uint = 0x000000;
var topColorAlphaValue:Number = .5;
var bottomColorValue:uint = 0xFFFFFF;
// get RGB
var redMix:int = ((topColorValue >> 16) & 0xFF);
var greenMix:int = ((topColorValue >> 8) & 0xFF);
var blueMix:int = (topColorValue & 0xFF);
// apply alpha to top color
if (alphaValue<1) {
var colorPlusAlpha:uint = combineRGB((redMix * (1-alphaValue)), (greenMix*(1-alphaValue)), (blueMix * (1-alphaValue)));
}
else {
colorPlusAlpha = topColorValue;
}
redMix = ((bottomColorValue >> 16) & 0xFF);
greenMix = ((bottomColorValue >> 8) & 0xFF);
blueMix = (bottomColorValue & 0xFF);
var secondColorPlusAlpha:uint = combineRGB((redMix * (alphaValue)), (greenMix*(alphaValue)), (blueMix * (alphaValue)));
var firstColorPlusSecondColor:uint = colorPlusAlpha + secondColorPlusAlpha;
The problem with the above solution is that it is off by 1. If the top color is 0x999999 and it's alpha is .5 and the bottom color is 0xFFFFFF then the result is 0xCBCBCB. When getting that pixel or using eye dropper in Photoshop the value is 0xCCCCCC.
IIU the functioning of the alpha channel correctly, it gives the mixing fraction between the color before and the color now added. This would mean:
colorVisible=colorNew*(1-alpha)+colorOld*alpha
A rough sanity check:
alpha=0% gives colorVisible=colorNew which sounds OK
alpha=100%=1 gives colorVisible=colorOld which sounds OK too

Categories

Resources