Public
Edited
Oct 21, 2022
1 star
Insert cell
Insert cell
Insert cell
{
restart;
return createCanvas(512, 512, draw, setup)
}
Insert cell
function setup({width, height}) {

// Set up a closure as our frame counter
// (this is just a demo, a simpler approach
// here would be to just return an object
// with a value that we increment ourselves}
let frameCount = 0;
const counter = () => frameCount++;
// Pick a random color for the background
const [r, g, b] = ametameric[Math.random() * ametameric.length | 0];

// return object with initialized state.
return {counter, r, g, b};
}
Insert cell
// The state initialized in setup is passed as
// the second argument to draw.
function draw(p8g, {counter, r, g, b}){

const {
background,
fill,
strokeWeight,
rect,
width,
height,
ellipse,
mouseX,
mouseY
} = p8g;

background(r, g, b)
// change fill color over time, use sinebow colormap
const t = counter() % 0x200 / 0x200;
const {sin, PI} = Math;
fill(
(1 + sin(t * PI * 2)) * 127.5,
(1 + sin((t + 2/3) * PI * 2)) * 127.5,
(1 + sin((t + 1/3) * PI * 2)) * 127.5
)
strokeWeight(2);
rect(width/2 - 100, height/2 - 100, 200, 200);
ellipse(mouseX, mouseY, 50, 50)
}
Insert cell
// Øyvind Kolås's colorblind friendly terminal colors
// https://pippin.gimp.org/ametameric/
ametameric = [
[0x00, 0x00, 0x00],
[0xa0, 0x29, 0x29],
[0x4a, 0xa0, 0x8b],
[0x87, 0x84, 0x53],
[0x24, 0x24, 0xed],
[0xab, 0x4a, 0xdf],
[0x3b, 0x6b, 0xb1],
[0xc3, 0xc3, 0xc3],
[0x6f, 0x6f, 0x6f],
[0xed, 0xac, 0x82],
[0x99, 0xed, 0xba],
[0xe9, 0xd8, 0x08],
[0x82, 0xb4, 0xed],
[0xd6, 0x6f, 0xed],
[0x1d, 0xe1, 0xed],
[0xff, 0xff, 0xff]
]
Insert cell
Insert cell
// The normal p8g approach would be to assign a draw function to
// the p8g object, but because it's imported through skypack
// at runtime the p8g module is read-only. So instead we use
// this workaround.

createCanvas = {
const p8g = await import('https://cdn.skypack.dev/p8g.js@0.8.1?min');

let canvas = null;
let _draw = () => {};
let _setup = () => {};
let request = null;
let state = null;
return async function createCanvas(width, height, draw = _draw, setup = _setup, opts = {}) {

const {
css
} = opts
// cancel previous loop
if (request) cancelAnimationFrame(request);

if(typeof _setup !== "function") throw new Error("setup is not a function!");
if(typeof _draw !== "function") throw new Error("draw is not a function!")

_setup = setup;
_draw = draw;

if (!canvas) {
canvas = await html`${p8g.createCanvas(width, height)}`;
}
if (typeof css === "string") canvas.style = css;

state = setup(p8g);

// Draw Loop
request = requestAnimationFrame(function tick() {
draw(p8g, state);
request = requestAnimationFrame(tick);
});

invalidation.then(() => cancelAnimationFrame(request));

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