Tighten rope links and expose render type per scene
This commit is contained in:
61
main.js
61
main.js
@@ -17,7 +17,14 @@
|
|||||||
minChain: 3,
|
minChain: 3,
|
||||||
palette: ["#ff595e", "#ffca3a", "#8ac926", "#1982c4", "#6a4c93"],
|
palette: ["#ff595e", "#ffca3a", "#8ac926", "#1982c4", "#6a4c93"],
|
||||||
ballRadius: 18,
|
ballRadius: 18,
|
||||||
link: { stiffness: 0.6, lengthScale: 0.5, damping: 0.08, lineWidth: 3 },
|
link: {
|
||||||
|
stiffness: 0.85,
|
||||||
|
lengthScale: 1.05, // max stretch factor; slack below this
|
||||||
|
damping: 0.08,
|
||||||
|
lineWidth: 3,
|
||||||
|
rope: true,
|
||||||
|
renderType: "line",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const scenes = [
|
const scenes = [
|
||||||
@@ -30,7 +37,14 @@
|
|||||||
minChain: 3,
|
minChain: 3,
|
||||||
palette: ["#ff595e", "#ffca3a", "#8ac926", "#1982c4", "#6a4c93"],
|
palette: ["#ff595e", "#ffca3a", "#8ac926", "#1982c4", "#6a4c93"],
|
||||||
ballRadius: 38,
|
ballRadius: 38,
|
||||||
link: { stiffness: 0.6, lengthScale: 0.5, damping: 0.08, lineWidth: 3 },
|
link: {
|
||||||
|
stiffness: 0.85,
|
||||||
|
lengthScale: 1.05,
|
||||||
|
damping: 0.08,
|
||||||
|
lineWidth: 3,
|
||||||
|
rope: true,
|
||||||
|
renderType: "line",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
createBodies: (w, h) => [
|
createBodies: (w, h) => [
|
||||||
Bodies.rectangle(w / 2, h + 40, w, 80, {
|
Bodies.rectangle(w / 2, h + 40, w, 80, {
|
||||||
@@ -58,7 +72,14 @@
|
|||||||
minChain: 3,
|
minChain: 3,
|
||||||
palette: ["#fb7185", "#fbbf24", "#34d399", "#38bdf8"],
|
palette: ["#fb7185", "#fbbf24", "#34d399", "#38bdf8"],
|
||||||
ballRadius: 22,
|
ballRadius: 22,
|
||||||
link: { stiffness: 0.6, lengthScale: 1.2, damping: 0.01, lineWidth: 4 },
|
link: {
|
||||||
|
stiffness: 0.6,
|
||||||
|
lengthScale: 1,
|
||||||
|
damping: 0.01,
|
||||||
|
lineWidth: 4,
|
||||||
|
rope: false,
|
||||||
|
renderType: "spring",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
createBodies: (w, h) => [
|
createBodies: (w, h) => [
|
||||||
Bodies.rectangle(w / 2, h + 50, w, 100, {
|
Bodies.rectangle(w / 2, h + 50, w, 100, {
|
||||||
@@ -90,7 +111,14 @@
|
|||||||
minChain: 3,
|
minChain: 3,
|
||||||
palette: ["#e879f9", "#38bdf8", "#f97316", "#22c55e"],
|
palette: ["#e879f9", "#38bdf8", "#f97316", "#22c55e"],
|
||||||
ballRadius: 16,
|
ballRadius: 16,
|
||||||
link: { stiffness: 1, lengthScale: 0.85, damping: 0.15, lineWidth: 3 },
|
link: {
|
||||||
|
stiffness: 1,
|
||||||
|
lengthScale: 0.85,
|
||||||
|
damping: 0.15,
|
||||||
|
lineWidth: 3,
|
||||||
|
rope: false,
|
||||||
|
renderType: "line",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
createBodies: (w, h) => {
|
createBodies: (w, h) => {
|
||||||
const bodies = [
|
const bodies = [
|
||||||
@@ -368,8 +396,15 @@
|
|||||||
render: {
|
render: {
|
||||||
strokeStyle: chain.color,
|
strokeStyle: chain.color,
|
||||||
lineWidth: linkCfg.lineWidth ?? 3,
|
lineWidth: linkCfg.lineWidth ?? 3,
|
||||||
|
type: linkCfg.renderType || "line",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
constraint.plugin = {
|
||||||
|
restLength: dist * (linkCfg.lengthScale ?? 1),
|
||||||
|
rope: linkCfg.rope ?? false,
|
||||||
|
baseStiffness: linkCfg.stiffness ?? 0.9,
|
||||||
|
maxLength: dist * (linkCfg.lengthScale ?? 1),
|
||||||
|
};
|
||||||
chain.constraints.push(constraint);
|
chain.constraints.push(constraint);
|
||||||
chain.bodies.push(body);
|
chain.bodies.push(body);
|
||||||
setHighlight(body, true);
|
setHighlight(body, true);
|
||||||
@@ -565,6 +600,24 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Events.on(engine, "beforeUpdate", () => {
|
||||||
|
// Rope-like constraint handling: allow shortening without push-back, tension when stretched.
|
||||||
|
chain.constraints.forEach((c) => {
|
||||||
|
if (!c.plugin || !c.plugin.rope) return;
|
||||||
|
const current = Vector.magnitude(
|
||||||
|
Vector.sub(c.bodyA.position, c.bodyB.position),
|
||||||
|
);
|
||||||
|
const maxLen = c.plugin.maxLength ?? c.length;
|
||||||
|
if (current <= maxLen) {
|
||||||
|
c.length = current;
|
||||||
|
c.stiffness = 0;
|
||||||
|
} else {
|
||||||
|
c.length = maxLen;
|
||||||
|
c.stiffness = c.plugin.baseStiffness ?? c.stiffness;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
Events.on(render, "afterRender", () => {
|
Events.on(render, "afterRender", () => {
|
||||||
if (!chain.active || !chain.pointer || chain.bodies.length === 0) return;
|
if (!chain.active || !chain.pointer || chain.bodies.length === 0) return;
|
||||||
const last = chain.bodies[chain.bodies.length - 1];
|
const last = chain.bodies[chain.bodies.length - 1];
|
||||||
|
|||||||
Reference in New Issue
Block a user