OKLCH
by phloe
HTML
<canvas id="canvas" width="45" height="45"></canvas>
<input id="hueInput" type="range" value="0" min="0" step="0.001" max="360" />
<span id="hueValue">0</span>
CSS
#canvas {
width: 360px;
height: 360px;
_image-rendering: pixelated;
}
JavaScript
const context = canvas.getContext("2d", { colorSpace: "display-p3" });
const maxL = 1;
const maxC = 0.4;
const maxH = 360;
let h = 0, l = 0, c = 0.2;
function update() {
const { width, height } = canvas;
for (var y = 0; y < height; y++) {
l = (1 - (y / height)) * maxL;
for (var x = 0; x < width; x++) {
c = (1 - (x / width)) * maxC;
context.fillStyle = `oklch(${l} ${c} ${h})`;
context.fillRect(x, y, 1, 1);
}
}
}
var timer;
let maxRes = 0;
let res = maxRes;
let minRes = 3;
let maxSize = 360;
function setRes() {
const size = maxSize / Math.pow(2, res);
canvas.width = size;
canvas.height = size;
}
function upRes() {
if (timer) {
timer = clearTimeout(timer);
}
if (res > maxRes) {
setRes();
update();
timer = setTimeout(upRes, 16);
res--;
}
else {
update();
}
}
hueInput.addEventListener('input', (event) => {
if (timer) {
timer = clearTimeout(timer);
}
if (res < minRes) {
res = minRes;
setRes();
}
timer = setTimeout(upRes, 300);
h = parseFloat(event.target.value);
hueValue.innerText = h.toFixed(2);
update();
});
update();