JSFiddle - React, Tailwind, and code Playground
HTML
<html>
<head>
<title>oRGB demo</title>
<meta charset="utf-8" />
</head>
<body>
<div id="square"></div>
<div id="controls">
<label for="l">dark</label><input type="range" id="l" name="l" min="0" max="1000" value="0"><label for="l">light</label><br />
<label for="cyb">blue</label><input type="range" id="cyb" name="cyb" min="-500" max="500" value="0"><label for="cyb">yellow</label><br />
<label for="crg">green</label><input type="range" id="crg" name="crg" min="-500" max="500" value="0"><label for="crg">red</label><br />
</div>
</body>
</html>
CSS
#square {
border: 1px solid black;
height: 250px;
width: 250px;
background-color: black;
}
JavaScript
var l = 0;
var cyb = 0;
var crg = 0;
function toHex(v) {
let s = v.toString(16);
return s.length < 2 ? "0" + s : s;
}
function updateSquare() {
let theta0 = Math.atan2(crg, cyb);
let theta = theta0 < (Math.PI / 2)
? (2*theta0 / 3)
: (Math.PI / 3) + ((4/3)*(theta0 - (Math.PI / 2)));
let c1 = cyb*Math.cos(theta-theta0) - crg*Math.sin(theta-theta0);
let c2 = cyb*Math.sin(theta-theta0) + crg*Math.cos(theta-theta0);
let red = Math.round((l + 0.1140 * c1 + 0.7436*c2) * 255);
let green = Math.round((l + 0.1140 * c1 - 0.4111*c2) * 255);
let blue = Math.round((l - 0.8860 * c1 + 0.1663*c2) * 255);
if(red > 255) red = 255;
if(green > 255) green = 255;
if(blue > 255) blue = 255;
if(red < 0) red = 0;
if(green < 0) green = 0;
if(blue < 0) blue = 0;
let color = "#" + toHex(red) + toHex(green) + toHex(blue);
console.log("(theta,theta0) = (" + theta + "," + theta0 + ")");
console.log("(l,cyb,crg) = (" + l + "," + cyb + "," + crg + ")");
console.log("(l,c1,c2) = (" + l + "," + c1 + "," + c2 + ")");
console.log("(r,g,b) = (" + red + "," + green + "," + blue + ")");
document.getElementById("square").style.backgroundColor = color;
}
function onLChange(e) {
l = parseInt(e.target.value) / 1000;
updateSquare();
}
function onCybChange(e) {
cyb = parseInt(e.target.value) / 500;
updateSquare();
}
function onCrgChange(e) {
crg = parseInt(e.target.value) / 500;
updateSquare();
}
document.getElementById("l").onchange = onLChange;
document.getElementById("cyb").onchange = onCybChange;
document.getElementById("crg").onchange = onCrgChange;