Public
Edited
Mar 31, 2024
1 star
Insert cell
Insert cell
createRegl = require("regl@2.1.0/dist/regl.js")
Insert cell
Insert cell
Insert cell
Insert cell
canvas = gradientMaker({ width: 500, height: 500 });
Insert cell
{
let c =
gradientType == "3 colors"
? [colors.c0, colors.c2, colors.c3]
: [colors.c0, colors.c1, colors.c2, colors.c3];
c = c.map((color) => {
let { r, g, b } = d3.rgb(color);
return [r / 255, g / 255, b / 255, 1];
});
const lrgb = mode == "lrgb";
canvas.gradient(c, lrgb);
}
Insert cell
function gradientMaker(options = {}) {
const { width = 500, height = 500 } = options;
const canvas = html`<canvas width=500 height=500>`;
const regl = createRegl({
canvas: canvas,
extensions: ["webgl_draw_buffers", "oes_texture_float"]
});
const grad3 = gradient3(regl);
const grad4 = gradient4(regl);
canvas.gradient = (colors, lrgb = true) => {
lrgb = +lrgb;
regl.clear({
color: [0, 0, 0, 0],
depth: 1
});
if (colors.length == 3) {
grad3({
positions: [
[0, 1],
[-1, -1],
[1, -1]
],
colors,
lrgb
});
} else {
grad4({
colors,
lrgb
});
}
return canvas;
};
return canvas;
}
Insert cell
Insert cell
function gradient4(regl) {
return regl({
frag: `
precision highp float;
uniform vec4 color0;
uniform vec4 color1;
uniform vec4 color2;
uniform vec4 color3;
uniform vec2 iResolution;
uniform float lrgb;
float fnToRgb (float c) {
float tmp = abs(c);
if (tmp > 0.0031308) {
return 1.055 * pow(tmp, 1. / 2.4) - 0.055;
}
return c * 12.92;
}
vec4 toRgb(vec4 color) {
return vec4 (fnToRgb(color.r), fnToRgb(color.g), fnToRgb(color.b), color.a);
}
float fnToLrgb (float c) {
float tmp = abs(c);
if (tmp <= 0.04045) {
return c / 12.92;
}
return pow((tmp + 0.055) / 1.055, 2.4);
}
vec4 toLrgb(vec4 color) {
return vec4 (fnToLrgb(color.r), fnToLrgb(color.g), fnToLrgb(color.b), color.a);
}
void main () {
vec2 uv = gl_FragCoord.xy / iResolution.xy;
if (lrgb != 0.) {
vec4 colorLeft = mix(toLrgb(color2),toLrgb(color0),uv.y);
vec4 colorRight = mix(toLrgb(color3),toLrgb(color1),uv.y);
vec4 color = toRgb(mix(colorLeft,colorRight,uv.x));
gl_FragColor = color;
} else {
vec4 colorLeft = mix(color2,color0,uv.y);
vec4 colorRight = mix(color3,color1,uv.y);
vec4 color = mix(colorLeft,colorRight,uv.x);
gl_FragColor = color;
}

}`,
vert: `
attribute vec2 position;
void main () {
gl_Position = vec4(position, 1, 1.0);
}`,

// These are the vertex attributes that will be passed
// on to the vertex shader
attributes: {
position: [
[-1, -1],
[1, -1],
[1, 1],
[1, 1],
[-1, 1],
[-1, -1]
]
},

uniforms: {
iResolution: (_) => [_.viewportWidth, _.viewportHeight],
color0: (_, props) => props.colors[0],
color1: (_, props) => props.colors[1],
color2: (_, props) => props.colors[2],
color3: (_, props) => props.colors[3],
lrgb: (_, props) => props.lrgb || 0.0
},

// The depth buffer
depth: {
enable: false,
mask: false
},
count: 6
});
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more