Published
Edited
Oct 23, 2019
14 forks
44 stars
Insert cell
Insert cell
canvas = {
const context = DOM.context2d(width, height);
const line = d3.lineRadial()
.context(context)
.curve(d3.curveLinearClosed)
.angle((r, i) => i * 2 * Math.PI / n)
.radius(r => r);
while (true) {
context.clearRect(0, 0, width, height);
context.save();
context.translate(width / 2, height / 2);
context.lineWidth = 10;
context.lineJoin = "round";
context.globalCompositeOperation = "darken";
colors.forEach((color, j) => {
context.beginPath();
line(Float64Array.from({length: n}, (_, i) => {
const a = i * 2 * Math.PI / n;
const t = performance.now() * speed;
const c = Math.cos(a * frequency - j * shift + t);
const p = Math.pow((1 + Math.cos(a - t)) / 2, 3);
return radius + amplitude * c * p;
}));
context.strokeStyle = color;
context.stroke();
});
context.restore();
yield context.canvas;
}
}
Insert cell
colors = ["cyan", "magenta", "yellow"]
Insert cell
shift = 2 * Math.PI / 3
Insert cell
speed = 1 / 1000
Insert cell
frequency = 8
Insert cell
amplitude = 32
Insert cell
radius = Math.min(width, height) / 2 - amplitude * 2
Insert cell
height = 640
Insert cell
n = 360
Insert cell
d3 = require("d3-shape@1")
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