Public
Edited
Aug 26, 2024
Importers
7 stars
Insert cell
Insert cell
Insert cell
viewof regl = reglCanvas(this, {
width: width * 0.7,
height: width * 0.2,
attributes: { antialias: true },
extensions: ["OES_standard_derivatives"],
style: { backgroundColor: "red" }
})
Insert cell
draw = {
// Don't forget to poll if outside a `regl.frame` loop!
regl.poll();
regl.clear({ color: [0.4, 0.3, 0.8, 1] });
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function reglCanvas(currentCanvas, opts) {
opts = opts || {};
const w = opts.width || width;
const h = opts.height || Math.floor(w * 0.5);
const createREGL = opts.createREGL || createREGLLatest;

function normalizeConfig(opts) {
const normalized = Object.assign(
{},
{
pixelRatio: devicePixelRatio,
attributes: {},
extensions: [],
optionalExtensions: [],
profile: false
},
opts || {}
);
delete normalized.width;
delete normalized.height;
return normalized;
}

const config = normalizeConfig(opts);

function preserveExisting(canvas, newConfig) {
const currentConfig = canvas.config;
if (JSON.stringify(currentConfig) !== JSON.stringify(newConfig)) {
return false;
}
return canvas;
}

function resizeCanvas(canvas, width, height) {
if (width) {
canvas.width = Math.floor(width * config.pixelRatio);
canvas.style.width = `${Math.floor(width)}px`;
}
if (height) {
canvas.height = Math.floor(height * config.pixelRatio);
canvas.style.height = `${Math.floor(height)}px`;
}
}

if (currentCanvas) {
if (!(currentCanvas instanceof HTMLCanvasElement)) {
throw new Error(
"Unexpected first argument type. Did you forget to pass `this` as the first argument?"
);
}
resizeCanvas(currentCanvas, w, h);
const existing = preserveExisting(currentCanvas, config);
if (existing) return existing;
}

const canvas = DOM.element("canvas");
// Clone the options since canvas creation mutates the `attributes` object,
// causing false positives when we then use it to detect changed config.
const style = config.style;
delete config.style;
const regl = createREGL({ canvas, ...JSON.parse(JSON.stringify(config)) });
resizeCanvas(canvas, w, h);
canvas.value = regl;
canvas.config = config;

if (style) {
for (const [prop, value] of Object.entries(style)) {
if (canvas.style[prop] !== value) canvas.style[prop] = value;
}
}

return canvas;
}
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