Public
Edited
Jan 1, 2024
Insert cell
Insert cell
Insert cell
{
replay;

const width = 600,
height = 200,
movers = cm.range(20).map(() => ({
location: cm.vec(cm.random(width), cm.random(height)),
velocity: cm.vec(),
acceleration: cm.vec(),
speed: 8
}));

function update(app) {
app.append(cm.clear, { fill: cm.rgb(255) });
app
.data(movers)
.process(cm.each, follow)
.append(cm.circle, {
x: (d) => d.location.x,
y: (d) => d.location.y,
fill: "rgba(175, 175, 175, 0.5)",
stroke: cm.rgb(0),
r: 16
});
}

function dispose(app) {
invalidation.then(() => app.dispose());
}

function border(app) {
app.node().style.border = "solid #000 1px";
}

return cm
.app({ width, height })
.on("update", update)
.call(dispose)
.call(border)
.start()
.node();
}
Insert cell
function follow({ location, velocity, acceleration, speed }, i, data, flow) {
const app = flow.app();

const dir = cm
.vec(app.prop("mouseX"), app.prop("mouseY"))
.sub(location)
.norm()
.mult(0.5);

acceleration.set(dir);

location
.add(velocity.add(acceleration).clamp(speed))
.clampX(app.prop("width"))
.clampY(app.prop("height"));
}
Insert cell
cm = require("@charming-art/charming@0.0.6")
Insert cell
import { quote } from "@pearmini/charming-shared"
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