While I played with HSV pie and color wheel before, usually I just use the excellent Qt graphics stack to try out various things. This days, I lean towards using web technologies and for that purpose, HTML Canvas suits me just fine. With PhantomJS, I even got the result rendered as PNG image.
The new example I added to PhantomJS is colorwheel.js which produces the above screenshot. The entire script code is as follows (if some parts look cryptic, read about HSL and HSV color space):
if (phantom.state.length === ) {
phantom.state = 1;
phantom.viewportSize = { width: 400, height : 400 };
phantom.content = '<html><body><canvas id="surface">' +
'</canvas></body></html>';
} else {
var el = document.getElementById('surface'),
context = el.getContext('2d'),
width = window.innerWidth,
height = window.innerHeight,
cx = width / 2,
cy = height / 2,
radius = width / 2.3,
imageData,
pixels,
hue, sat, value,
i = , x, y, rx, ry, d,
f, g, p, u, v, w, rgb;
el.width = width;
el.height = height;
imageData = context.createImageData(width, height);
pixels = imageData.data;
for (y = ; y < height; y = y + 1) {
for (x = ; x < width; x = x + 1, i = i + 4) {
rx = x - cx;
ry = y - cy;
d = rx * rx + ry * ry;
if (d < radius * radius) {
hue = 6 * (Math.atan2(ry, rx) + Math.PI) / (2 * Math.PI);
sat = Math.sqrt(d) / radius;
g = Math.floor(hue);
f = hue - g;
u = 255 * (1 - sat);
v = 255 * (1 - sat * f);
w = 255 * (1 - sat * (1 - f));
pixels[i] = [255, v, u, u, w, 255, 255][g];
pixels[i + 1] = [w, 255, 255, v, u, u, w][g];
pixels[i + 2] = [u, u, w, 255, 255, v, u][g];
pixels[i + 3] = 255;
}
}
}
context.putImageData(imageData, , );
document.body.style.backgroundColor = 'white';
document.body.style.margin = '0px';
phantom.render('colorwheel.png');
phantom.exit();
}
Beside the above example, there are few other things which you’ll get in the upcoming PhantomJS 1.1 release, among others support for Unix shebang, file upload for form submission, disable/enable images loading and plugins, as well as support for QUnit integration.