Public
Edited
Jan 1, 2024
Insert cell
Insert cell
{
const mover = {
location: cm.vec(),
velocity: cm.vec(),
acceleration: cm.vec(),
mass: 1
};

function update(app) {
app.append(cm.clear, { fill: cm.rgb(255) });
app
.datum(mover)
.process(cm.each, toMouse)
.process(cm.each, move)
.process(cm.each, checkEdges)
.append(cm.rect, {
x: (d) => d.location.x,
y: (d) => d.location.y,
width: 30,
height: 10,
fill: cm.rgb(175),
stroke: cm.rgb(0),
rotate: (d) => d.velocity.angle()
});
}

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

return cm
.app({ width: 600, height: 200 })
.on("update", update)
.call(dispose)
.call(frame)
.start()
.node();
}
Insert cell
function move(d) {
d.velocity.add(d.acceleration);
d.location.add(d.velocity);
d.acceleration.mult(0);
}
Insert cell
function toMouse(d, i, data, flow) {
const app = flow.app();
const mouse = cm.vec(app.prop("mouseX"), app.prop("mouseY"));
const force = mouse.sub(d.location).mag(0.5);
applyForce(d, force);
}
Insert cell
function checkEdges(d, i, data, flow) {
const app = flow.app();
d.location.clampX(app.prop("width")).clampY(app.prop("height"));
d.velocity.clamp(4);
}
Insert cell
function applyForce(d, f) {
const a = cm.vecDiv(f, d.mass);
d.acceleration.add(a);
}
Insert cell
function frame(app) {
app.node().style.border = "solid #000 1px";
}
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