Files
mixbox/javascript/examples/gradients.js
2022-09-21 05:05:21 +02:00

148 lines
4.0 KiB
JavaScript

let colorPicker_A;
let colorPicker_B;
let color_A;
let color_B;
function setup() {
createCanvas(650, 465);
background(255);
colorMode(RGB);
colorPicker_A = createColorPicker('#002185');
colorPicker_A.parent('picker-A');
color_A = colorPicker_A.color();
colorPicker_B = createColorPicker('#fcd200');
colorPicker_B.parent('picker-B');
color_B = colorPicker_B.color();
drawGradient("Mixbox", color_A, color_B, 50, 200, 65, 465);
drawGradient("RGB", color_A, color_B, 250, 400, 65, 465);
drawGradient("OkLab", color_A, color_B, 450, 600, 65, 465);
}
function draw() {
if(color_A.toString() != colorPicker_A.color().toString() || color_B.toString() != colorPicker_B.color().toString())
{
background(255);
color_A = colorPicker_A.color();
color_B = colorPicker_B.color();
drawGradient("Mixbox", color_A, color_B, 50, 200, 65, 465);
drawGradient("RGB", color_A, color_B, 250, 400, 65, 465);
drawGradient("OkLab", color_A, color_B, 450, 600, 65, 465);
}
}
function drawGradient(method, color1, color2, x1, x2, y1, y2)
{
textSize(28);
textStyle(BOLD);
fill(79, 118, 123);
text(method, x1 + (x2-x1)/2 - textWidth(method)/2, y1-30);
let mixedColor;
for (let y = y1; y <= y2; y++)
{
let t = (y-y1)/(y2-y1);
if(match(method, 'Mixbox'))
{
mixedColor = mixbox.lerp(color1, color2, t);
}
else if(match(method, 'RGB'))
{
mixedColor = lerpColor(color1, color2, t);
}
else if(match(method, 'OkLab'))
{
let c1 = [red(color1), green(color1), blue(color1)];
let c2 = [red(color2), green(color2), blue(color2)];
let tmp = linear_to_rgb (oklab_to_linear_srgb(linearMix(linear_srgb_to_oklab(rgb_to_linear(c1)),linear_srgb_to_oklab(rgb_to_linear(c2)),t)));
mixedColor = color(tmp[0], tmp[1], tmp[2]);
}
strokeWeight(2);
stroke(mixedColor);
line(x1, y, x2, y);
noStroke();
}
}
/* THE FOLLOWING CODE IS HANDLING THE CONVERSION TO OkLAB SPACE */
/* https://bottosson.github.io/posts/oklab/ */
function linear_srgb_to_oklab(c)
{
let l = 0.4122214708 * c[0] + 0.5363325363 * c[1] + 0.0514459929 * c[2];
let m = 0.2119034982 * c[0] + 0.6806995451 * c[1] + 0.1073969566 * c[2];
let s = 0.0883024619 * c[0] + 0.2817188376 * c[1] + 0.6299787005 * c[2];
let l_ = Math.cbrt(l);
let m_ = Math.cbrt(m);
let s_ = Math.cbrt(s);
var lab = [ 0.2104542553*l_ + 0.7936177850*m_ - 0.0040720468*s_,
1.9779984951*l_ - 2.4285922050*m_ + 0.4505937099*s_,
0.0259040371*l_ + 0.7827717662*m_ - 0.8086757660*s_ ];
return lab;
}
function oklab_to_linear_srgb(c)
{
let l_ = c[0] + 0.3963377774 * c[1] + 0.2158037573 * c[2];
let m_ = c[0] - 0.1055613458 * c[1] - 0.0638541728 * c[2];
let s_ = c[0] - 0.0894841775 * c[1] - 1.2914855480 * c[2];
let l = l_*l_*l_;
let m = m_*m_*m_;
let s = s_*s_*s_;
var lrgb = [ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
-0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s];
return lrgb;
}
function rgb_to_linear(rgb) // receiving Color object, returning array of 3 linear RGB values in range 0-1
{
var res = [0,0,0];
var float_rgb = [rgb[0]/255, rgb[1]/255, rgb[2]/255];
for (let i = 0; i < 3; ++i)
{
let c = float_rgb[i];
if (c >= 0.04045)
res[i] = pow((c + 0.055)/(1 + 0.055), 2.4);
else
res[i] = c / 12.92;
}
return res;
}
function linear_to_rgb(lrgb) // receiving array of 3 linear RGB values, returning an array of gamma encoded RGB values in range 0-255
{
var res = [0,0,0];
for (let i = 0; i < 3; ++i)
{
let c = lrgb[i];
if (c >= 0.0031308)
res[i] = 1.055 * pow(c, 1.0/2.4) - 0.055;
else
res[i] = 12.92 * c;
}
return [round(res[0]*255), round(res[1]*255), round(res[2]*255)];
}
function linearMix (a, b, t)
{
var res = [0,0,0];
for(let i=0; i<3; i++)
{
res[i] = a[i] * (1-t) + b[i]*t;
}
return res;
}