Public
Edited
Jun 5, 2022
1 fork
1 star
Insert cell
Insert cell
Insert cell
Insert cell
WIDTH = Math.min(600, width)
Insert cell
HEIGHT = WIDTH
Insert cell
DURATION_MS = 3000
Insert cell
PAUSE_MS = 1000
Insert cell
PATTERNS = [
[50, 50, 50, 50], // chequerboard
[60, 30, 30, 60], // herringbone
[70, 70, 30, 30], // Pythagorean
]
Insert cell
Insert cell
clock = {
while (1) {
const ts = Date.now() % ((DURATION_MS + PAUSE_MS) * PATTERNS.length) / (DURATION_MS + PAUSE_MS);
yield ts;
}
}
Insert cell
a = Math.floor(clock)
Insert cell
b = (a + 1) % PATTERNS.length
Insert cell
t = ease(clock - Math.floor(clock))
Insert cell
A = interpolateArrays(t, PATTERNS[a], PATTERNS[b])
Insert cell
{
const ct = canvas.ct;
const { sin, cos } = Math;

ct.fillStyle = "#f00";
ct.fillRect(-WIDTH/2, -HEIGHT/2, WIDTH, HEIGHT);

for (let i = -20; i < 20; i++) {
for (let j = -20; j < 20; j++) {
const x = i * A[0] + j * A[2];
const y = j * A[1] - i * A[3];

ct.strokeStyle = "#78A";
ct.strokeRect(x, y, A[0], A[1]);

ct.strokeStyle = "rgba(0,0,0,0.5)";
ct.strokeRect(x, y, -A[2], A[3]);

ct.fillStyle = "#346";
ct.fillRect(x, y, A[0], A[1]);
}
}

// ct.beginPath();
// ct.arc(0, 0, 10, 0, 7);
// ct.fillStyle = "#009";
// ct.fill();

return this || html`(<i>the drawing function</i>)`;
}
Insert cell
function easeSin(t) {
return (Math.sin((t - .5)*Math.PI) + 1) / 2;
}
Insert cell
function easePad(p, f) {
return function(t) {
if (t < p) return 0;
if (t > 1-p) return 1;
return f((t-p)/(1-2*p));
};
}
Insert cell
ease = easePad(PAUSE_MS/(DURATION_MS+PAUSE_MS)/2, easeSin);
Insert cell
function interpolateArrays(t, a, b) {
return a.map((_, i) => a[i] * (1-t) + b[i] * t);
}
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