Published
Edited
Oct 12, 2019
9 stars
Insert cell
Insert cell
Insert cell
{
const context = DOM.context2d(width, width);

const lines = [];
for (let i = 0; i < points.length - 1; ++i) {
lines.push([points[i], points[i + 1]]);
}

yield context.canvas;

let t = 0;
let trace = [];
while (true) {
await Promises.delay(50);
context.clearRect(0, 0, width, width);
t = (t + 0.01) % 1;

for (let l of lines) {
line(...l, context);
}

const l = drawIteration(lines, points.length - 1, t, context);
const pt = pointOnLine(...l, t);
circle([...pt, 4], context, { color: "red" });
trace.push(pt);

if (t >= 0.99) trace = [];

for (let i = 0; i < trace.length - 1; ++i) {
line(trace[i], trace[i + 1], context, { color: "red", lineWidth: 2 });
}
}
}
Insert cell
function drawIteration(lines, n, t, context) {
if (n <= 1) return lines;

const c = 100 + (points.length - 1 - n) * points.length;
const color = `rgb(${c}, ${c}, ${c})`;

const p1s = [];
for (let l of lines) {
circle([...l[0], 3], context, { color });
const p1 = pointOnLine(l, t);
circle([...p1, 3], context, { color });
p1s.push(p1);
}
circle([...lines[lines.length - 1][1], 3], context, { color });

const nextLines = [];
for (let i = 0; i < p1s.length - 1; ++i) {
const nl = line(p1s[i], p1s[i + 1], context, { color });
nextLines.push(nl);
}

return drawIteration(nextLines, n - 1, t, context);
}
Insert cell
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