Linearly increasing color darkness algorithm - css

I want to write a function in ruby that given a number between 1 and 500 will output a 6 digit hex color code that gets linearly darker for higher numbers. This doesn't seem that hard but I'm not sure where to begin. How can I implement this?
edit
Hue seems like a more reliable way to go. I'd like to give a reference color, say a shade of green, and then darken or lighten it based on the input number.
input: 10
output: color code (in rgb or HSV) that is a light shade of the reference color
input: 400
output: color code (in rgb or HSV) that is a fairly dark shade of the reference color
edit 2
The only reason I need to use between 1 and 500 is because that's the input I have to work with. It's alright if some numbers that are close together map to the same color.

The 6 digit hex color code is in RGB.
What you want is to work in HSV: pick a Hue and Saturation, and gradually decrease the Value.
Convert from HSV to RGB to output the color.
See here for an example.

Basic linear interpolation?
// Pseudocode
function fade_colour(source, factor)
const max = 500
const min = 1
foreach component in source
output[component] = round(source[component] * (max - value) / (max - min))
endforeach
return output
endfunction

Why not just return a gray level then, #ffffff to #000000? 500 levels of darkness aren't really distinguishable anyway, and grays give you 256 levels.

If you only want to darken your reference color, it's easy. Given an R,G,B color that is the brightest you want to go, multiply each of the 3 values by (500-input) and divide by 499. Convert each of the values to 2 hex digits and append them with a # at the front.

Related

Why does RGB use 6 hex digits?

I understand that RGB encodes a color with two hex digits corresponding to the Red, Green, and Blue components. For instance, #ff0000 is pure red. And I understand that each hex digit represents a number from 0-15, or 4-bits of information. But how is it possible to represent every color with 32-bits? Why use two digits for Red and Green and Blue? Why aren't there, for instance, three digits per color?
I dont really know if any of this is related to hardware and whether we can even make colors to such detail but a third hex digit for colors means we will have colors with 4096 times more detail, (meaning if we have X color combinations currently, then we will have 4096 * X colors) which we simply dont need, since human eye wont be able to notice the difference, even in our current color system, let alone one much bigger.
So you'd be sacrificing efficiency for nothing in that case, like watching a movie on 600 frames per second while your eye can only process 60.

Domain coloring (color wheel) plots of complex functions in Octave (Matlab)

I understand that domain or color wheel plotting is typical for complex functions.
Incredibly, I can't find a million + returns on a web search to easily allow me to reproduce some piece of art as this one in Wikipedia:
There is this online resource that reproduces plots with zeros in black - not bad at all... However, I'd like to ask for some simple annotated code in Octave to produce color plots of functions of complex numbers.
Here is an example:
I see here code to plot a complex function. However, it uses a different technique with the height representing the Re part of the image of the function, and the color representing the imaginary part:
Peter Kovesi has some fantastic color maps. He provides a MATLAB function, called colorcet, that we can use here to get the cyclic color map we need to represent the phase. Download this function before running the code below.
Let's start with creating a complex-valued test function f, where the magnitude increases from the center, and the phase is equal to the angle around the center. Much like the example you show:
% A test function
[xx,yy] = meshgrid(-128:128,-128:128);
z = xx + yy*1i;
f = z;
Next, we'll get its phase, convert it into an index into the colorcet C2 color map (which is cyclic), and finally reshape that back into the original function's shape. out here has 3 dimensions, the first two are the original dimensions, and the last one is RGB. imshow shows such a 3D matrix as a color image.
% Create a color image according to phase
cm = colorcet('C2');
phase = floor((angle(f) + pi) * ((size(cm,1)-1e-6) / (2*pi))) + 1;
out = cm(phase,:);
out = reshape(out,[size(f),3]);
The last part is to modulate the intensity of these colors using the magnitude of f. To make the discontinuities at powers of two, we take the base 2 logarithm, apply the modulo operation, and compute the power of two again. A simple multiplication with out decreases the intensity of the color where necessary:
% Compute the intensity, with discontinuities for |f|=2^n
magnitude = 0.5 * 2.^mod(log2(abs(f)),1);
out = out .* magnitude;
That last multiplication works in Octave and in the later versions of MATLAB. For older versions of MATLAB you need to use bsxfun instead:
out = bsxfun(#times,out,magnitude);
Finally, display using imshow:
% Display
imshow(out)
Note that the colors here are more muted than in your example. The colorcet color maps are perceptually uniform. That means that the same change in angle leads to the same perceptual change in color. In the example you posted, for example yellow is a very narrow, bright band. Such a band leads to false highlighting of certain features in the function, which might not be relevant at all. Perceptually uniform color maps are very important for proper interpretation of the data. Note also that this particular color map has easily-named colors (purple, blue, green, yellow) in the four cardinal directions. A purely real value is green (positive) or purple (negative), and a purely imaginary value is blue (positive) or yellow (negative).
There is also a great online tool made by Juan Carlos Ponce Campuzano for color wheel plotting.
In my experience it is much easier to use than the Octave solution. The downside is that you cannot use perceptually uniform coloring.

Is there a formula to get distinct colors in RGB representation

A color can be represented as mixture of Red,Green and Blue.
Ex: (255,51,153)=pink
Is there an any good formula to get distinct colors by changing one variable?
such as (10x,22x,2x^2). So when x=1,2,3,4,.... It will give separate colors like Red,Green,Cyan,Blue.....etc.
Perhaps you'd be more interested in using HSL/HSV colors. Define the saturation and lightness and adjust the hue to get different colors. Check out the HSL and HSV wiki to learn more. A 15 to 30 degree adjustment of hue will result in a distinctly different color without messing with saturation or lightness.
An example of hsl in CSS is as follows.
<h1 style="color:hsl(0,50%,100%);">HSL Test</h1> //this will be red
The first value at 0 is red and advancing by 120 degrees will bring you to green and another 120 will bring you to blue and the last 120 will bring you back to red since the degree system is based on the 360 degrees of a circle. So 0 and 360 are the same just 60 & 420. The next two values are percentage based from 0% to 100% to define the intensity of that property. They're hard to explain so I made a quick fiddle that demonstrates this.
So to answer your question there is a good formula to adjust color it just depends on how exactly you want to change it. In the RGB world you can make things darker by lowering values uniformly and the opposite by heightening them. You can increase the different color presences by adjusting the individual color values as expected. However if you're trying to cycle the entire color wheel then this is difficult (although entirely possible) using RGB values. The real lesson to take away is that there are a number of ways to define a specific color and with each one different ways to traverse the spectrum. HSL and HSLA are very intuitive for many people since it's values don't really have to be guessed at. Pick a specific hue off the color wheel, Remember ROYGBIV as you imagine a value from 0-359. Define a saturation based on how bold you want the color to be and then a lightness based on how bright. It's far more useful then RGB in the large majority of cases as you'll see in that fiddle. Making a subset of the entire color spectrum with javascript only takes a few lines of code.
There is a similar question here
This javascript library can help you Name the Color Javascript Lib
A Demo of the library

In CSS, can HSL values be floats?

The CSS3 spec only specifies that:
The format of an HSLA color value in the functional notation is ‘hsla(’ followed by the hue in degrees, saturation and lightness as a percentage, and an , followed by ‘)’.
So am I to understand that these values would be interpreted not as integers but as floats? Example:
hsla(200.2, 90.5%, 10.2%, .2)
That would dramatically expand the otherwise small (relative to RGB) range of colors covered by HSL.
It seems to render fine in Chrome, though I don't know if they simply parse it as an INT value or what.
HSL values are converted to hexadecimal RGB values before they are handed off to the system. It's up to the device to clip any resulting RGB value that is outside the "device gamut" - the range of colors that can be displayed - to a displayable value. RGB values are denoted in Hexadecimal. This is the specified algorithm for browsers to convert HSL values to RGB values. Rounding behavior is not specified by the standard - and there are multiple ways of doing rounding since there doesn't appear to be a built-in rounding function in either C or C++.
HOW TO RETURN hsl.to.rgb(h, s, l):
SELECT:
l<=0.5: PUT l*(s+1) IN m2
ELSE: PUT l+s-l*s IN m2
PUT l*2-m2 IN m1
PUT hue.to.rgb(m1, m2, h+1/3) IN r
PUT hue.to.rgb(m1, m2, h ) IN g
PUT hue.to.rgb(m1, m2, h-1/3) IN b
RETURN (r, g, b)
From the proposed recommendation
In other words, you should be able to represent the exact same range of colors in HSLA as you can represent in RGB using fractional values for HSLA.
AFAIK, every browser casts them to INTs. Maybe. If I'm wrong you won't be able to tell the difference anyway. If it really matters, why not just go take screenshots an open them in photoshop or use an on-screen color meter. Nobody here is going to have a definitive answer without testing it, and it takes 2 minutes to test... so...
I wouldn't know exactly, but it makes sense to just put in some floating numbers and see if it works? it takes two seconds to try with a decimal, and without..

Get hex codes for all colors between two colors?

I want to have buttons that are switching from one color to another.
Eg. 1000 buttons where the first one is yellow and the last one is green and all the between will slowly move from yellow to green.
How can I generate all the hex codes for colors (eg. #8a3a3a) between these two colors?
Split the two input colors into red, green, blue components and convert them to float. Subtract source components from destination components, divide each by 1000 and call them f.ex. deltaRed, deltaGreen, deltaBlue. Start with source components, convert those into a "#rrggbb" string 1000 times, each loop adding the deltas. If you want to actually reach the destination color, you have to loop from 0 to 1000, ie. 1001 times.
Yes, it is. You can compute it as follows:
Imagine the colors are points in a three-dimensional space, with each component (red, green, blue) representing one dimension. Depending on how many color tones you want between the two colors, you can try to evenly divide the differences between the two colors, for each component separately. For instance, if rA is the red component of color A, and rB the red component of color B, and if you want 10 steps in between, then the red component of the second step is r2 = (rB - rA) * 2 / 10.
Convert the components to decimal first (e.g. 8a => 138), and you should probably write a small program for the computation. I don't think you need so many tones though, because each component has only a range from 0 to 255 (rounding necessary), and the human eye cannot differentiate between so many colors anyway.
This may be what you need: http://sandbox.leigeber.com/fader/fader.html
Code: http://www.leigeber.com/wp-content/uploads/2008/05/fader.zip

Resources