EN
JavaScript - HSV color space visualization
4
points
In this article, we would like to show how using JavaScript, visualize HSV color space.
Practical example:
// ONLINE-RUNNER:browser;
<!doctype html>
<html>
<head>
<style>
#space { border: 1px solid silver; }
</style>
</head>
<body>
<canvas id="space" width="520" height="150"></canvas>
<script>
// Utils:
function toRgb$1(hsv) {
var d = 0.0166666666666666 * hsv.hue;
var c = hsv.value * hsv.saturation;
var x = c - c * Math.abs(d % 2.0 - 1.0);
var m = hsv.value - c;
c += m;
x += m;
switch (d >>> 0) {
case 0: return {red: c, green: x, blue: m};
case 1: return {red: x, green: c, blue: m};
case 2: return {red: m, green: c, blue: x};
case 3: return {red: m, green: x, blue: c};
case 4: return {red: x, green: m, blue: c};
}
return {red: c, green: m, blue: x};
}
function toRgb$2(hsv) {
var rgb = toRgb$1(hsv);
return {
red: Math.round(255 * rgb.red),
green: Math.round(255 * rgb.green),
blue: Math.round(255 * rgb.blue)
};
}
function drawPixel(data, width, x, y, rgb) {
var roundedX = Math.round(x);
var roundedY = Math.round(y);
var index = 4 * (width * roundedY + roundedX);
data[index + 0] = rgb.red;
data[index + 1] = rgb.green;
data[index + 2] = rgb.blue;
data[index + 3] = 255;
}
// Example:
var canvas = document.querySelector('#space');
var context = canvas.getContext('2d');
var image = context.createImageData(canvas.width, canvas.height);
var hLimit = canvas.width - 1;
var sLimit = canvas.height - 1;
for (var x = 0; x < canvas.width; x += 1) {
for (var y = 0; y < canvas.height; y += 1) {
var hsv = {
hue: 360.0 * (x / hLimit),
saturation: 1.0 * (y / sLimit),
value: 1.0 // HSV value component (from 0 to 1)
};
var rgb = toRgb$2(hsv);
drawPixel(image.data, canvas.width, x, y, rgb);
}
}
context.putImageData(image, 0, 0);
</script>
</body>
</html>
Configurable HSV space example
In this section, value component is configurable.
// ONLINE-RUNNER:browser;
<!doctype html>
<html>
<head>
<style>
#space { border: 1px solid silver; }
.field { margin: 20px 0 0 0; display: block; }
.label { display: block; }
.input { width: 520px; }
</style>
</head>
<body>
<canvas id="space" width="520" height="150"></canvas>
<script>
// Utils:
function toRgb$1(hsv) {
var d = 0.0166666666666666 * hsv.hue;
var c = hsv.value * hsv.saturation;
var x = c - c * Math.abs(d % 2.0 - 1.0);
var m = hsv.value - c;
c += m;
x += m;
switch (d >>> 0) {
case 0: return {red: c, green: x, blue: m};
case 1: return {red: x, green: c, blue: m};
case 2: return {red: m, green: c, blue: x};
case 3: return {red: m, green: x, blue: c};
case 4: return {red: x, green: m, blue: c};
}
return {red: c, green: m, blue: x};
}
function toRgb$2(hsv) {
var rgb = toRgb$1(hsv);
return {
red: Math.round(255 * rgb.red),
green: Math.round(255 * rgb.green),
blue: Math.round(255 * rgb.blue)
};
}
function drawPixel(data, width, x, y, rgb) {
var roundedX = Math.round(x);
var roundedY = Math.round(y);
var index = 4 * (width * roundedY + roundedX);
data[index + 0] = rgb.red;
data[index + 1] = rgb.green;
data[index + 2] = rgb.blue;
data[index + 3] = 255;
}
// Example:
var canvas = document.querySelector('#space');
var context = canvas.getContext('2d');
var image = context.createImageData(canvas.width, canvas.height);
var hLimit = canvas.width - 1;
var sLimit = canvas.height - 1;
function drawSpace(vValue) {
for (var x = 0; x < canvas.width; x += 1) {
for (var y = 0; y < canvas.height; y += 1) {
var hsv = {
hue: 360.0 * (x / hLimit),
saturation: 1.0 * (y / sLimit),
value: vValue
};
var rgb = toRgb$2(hsv);
drawPixel(image.data, canvas.width, x, y, rgb);
}
}
context.putImageData(image, 0, 0);
}
drawSpace(1.0);
</script>
<label class="field">
<span class="label">HSV value component (form 0 to 1):</span>
<input
class="input"
type="range"
value="1"
min="0"
max="1"
step="0.01"
oninput="drawSpace(parseFloat(this.value))"
/>
</label>
</body>
</html>