Public
Edited
Nov 4, 2022
Insert cell
Insert cell
{
const canvas = d3.create("canvas").node();
const ctx = canvas.getContext("2d");
canvas.width = w;
canvas.height = h;

let inc = 0;
let isClicked = false;

let curX = w * 0.5;
let curY = h * 0.34;
let mouseX, mouseY;

while (true) {
d3.select(canvas)
.on("mousedown", (e) => {
isClicked = true;
mouseX = e.pageX;
mouseY = e.pageY;
})
.on("mouseup", () => {
isClicked = false;
});

if (isClicked) {
curX += (mouseX - curX) / 10;
curY += (mouseY - curY) / 10;
} else {
curX += (w * 0.5 - curX) / 10;
curY += (h * 0.34 - curY) / 10;
}

loop(ctx, inc, canvas, curX, curY);
yield canvas;
}
}
Insert cell
Insert cell
loop = (ctx, inc, canvas, curX, curY) => {
ctx.clearRect(0, 0, w, h);
ctx.lineWidth = 2;
ctx.strokeStyle = "green";

const radius1 = w * 0.45;
const radius2 = w * 0.16;

inc = new Date().getTime();
inc = inc / 1000;
inc = inc / 60;
inc = inc * 360;

for (let angle = 0; angle < 360; angle += 5) {
const x1 = radius1 * Math.cos(((inc + angle) / 180) * Math.PI) + w / 2;
const y1 = radius1 * Math.sin(((inc + angle) / 180) * Math.PI) + h / 2;

const handle1 = w * 0.3;
const hx1 = handle1 * Math.cos(((inc + angle + 90) / 180) * Math.PI) + x1;
const hy1 = handle1 * Math.sin(((inc + angle + 90) / 180) * Math.PI) + y1;

let x2 = radius2 * Math.cos(((inc + angle) / 180) * Math.PI) + curX;
let y2 = radius2 * Math.sin(((inc + angle) / 180) * Math.PI) + curY;

const handle2 = w * 0.2;
const hx2 = handle2 * Math.cos(((inc + angle - 90) / 180) * Math.PI) + x2;
const hy2 = handle2 * Math.sin(((inc + angle - 90) / 180) * Math.PI) + y2;

ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.bezierCurveTo(hx1, hy1, hx2, hy2, x2, y2);
ctx.stroke();
}
}
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