Drawing the colour wheel with JavaScript
A brief follow-up to my earlier post on automatically generating colours using JavaScript, I just couldn't stop! It slightly irritated me that I had to search online for a picture of the colour wheel for the previous article (and found it on Kuler web-site, which is cool and all, but…), while I could easily generate it myself!
So, here's what I came up with, adding some niceties:This is an example of using a scripting language for quick prototyping and demos, so the approach is not the most efficient performance-wise, but gave me a quick result. The main thing I would change if it were needed for actual usage — I would not use the DOM for individual “pixels”, this is a luxury. Canvas is a better candidate for such things.
The Code
Here's the working example of JSFiddle, and the important snippets are below:var dim = 51; // Beware of setting too high var html = ''; for(var i = 0; i < dim; i++) { // Draw row for(var j = 0; j < dim; j++) { // Draw pixel html += '<span class="pixel' + (j == 0 ? ' first' : '') + '" style="background-color: ' + getColour(i,j,dim/2) + '"></span>'; } } $('#wheel').append(html); // Returns colour of pixel based on its offset // and circle's radius (square width / 2) function getColour(i, j, radius) { var angle; var col = '#fff'; var x = j - radius; var y = radius - i; var dist = Math.sqrt(x*x + y*y); // If inside the circle if(dist <= radius) { angle = Math.round(180 * Math.acos(x / dist) / Math.PI * (y < 0 ? 1 : -1)) + 90; col = 'hsl(' + angle + ', ' + (Math.round(dist / radius * 100)) + '%, ' + (80 - Math.round(dist / radius * 20)) + '%)'; } return col; }
And you need this CSS to have the pixels align correctly:
.pixel { display: block; float: left; height: 6px; width: 6px; margin: 0 1px 1px 0; border-radius: 3px; } .first { clear: left; }
Calculations
The logic is simple — remember those trigonometry classes, the ones you couldn't understand why you will ever need them? Why, for drawing colour wheels, of course!I am drawing a square (wait), and for each pixel from its (x, y) coordinates I detect whether it is within the radius of the circle (see?). If not — draw pixel white (could make it transparent too, if I needed). Distance from the circle origin is the square root of sum of squares of the coordinates. This distance also determines saturation of the resulting colour, and a slight variation of lightness (that makes it look nicer).
The hue is the angle of direction to the pixel compared to the vertical. To determine this I use arccosine — inversion of cosine value (school strikes back). Keep in mind that this gives you result in rads (full circle is two Pi), not degrees, so I still need to convert it.
Put angle and distance together to get a colour — and voila, — you get the nice-looking wheel.
Playing Around
With some time, inspiration and luck there can be many variations of the resulting picture:
…or even the “proper” wheel:
Comments
Post a Comment