{
replay;
let width = 600,
height = 200,
dragging = false,
spring = { k: 0.1, length: 100 },
bob = object({ location: cm.vec(0, spring.length) }),
anchor = object();
function clear(app) {
app.append(cm.clear, { fill: cm.rgb(255) });
}
function draw(app) {
const group = app.append(cm.group, { x: app.prop("width") / 2, y: 0 });
group
.datum(bob)
.call(updateBob, { dragging, spring, anchor })
.call(drawBob, { dragging });
group.datum(anchor).call(drawAnchor);
}
function mouseDown(params) {
dragging = true;
}
function mouseUp(params) {
dragging = false;
}
function dispose(app) {
invalidation.then(() => app.dispose());
}
return cm
.app({ width, height })
.on("update", clear)
.on("update", draw)
.on("mouseDown", mouseDown)
.on("mouseUp", mouseUp)
.call(dispose)
.call(frame)
.start()
.node();
}