Matter.js Physics · How it works & code
Realistic rigid body engine: gravity, impulse collisions, elasticity, and friction.
Runtime logic
Visiting `/physics/matter`, DemoHost lazy-loads `demos/kits/kit-physics.js` (registry `mod: 'kit-physics'`) and calls `mount(host, { variant: 'matter' })`. mount resolves the variant to family `matter`; `withControls` builds the control panel (5 presets + sliders). `createCanvasStage` creates the `<canvas>` (HiDPI ≤ 2×, ResizeObserver) and the info panel. Loads matter-js@0.20.0 from CDN on demand (jsDelivr → npmmirror → unpkg). The family’s `build(S)` initialises state and returns the per-frame callback. Every `requestAnimationFrame`: read controls, advance a speed-scaled clock (dt ≤ 50 ms), run the frame callback; returned readouts go to the info panel. Pointer down/drag/move updates the interaction (drag handles, hover readouts); when untouched and auto-demo is on, the pointer follows a Lissajous path. Changing parameters: colour/speed/size apply live; structural ones remount; leaving the page cancels rAF, removes listeners and frees resources.
Environment
Canvas 2D: 2D canvas drawing; requestAnimationFrame: Display-synced animation loop; ResizeObserver: Canvas follows container size; Pointer Events: Unified mouse/touch/pen events; devicePixelRatio: Crisp HiDPI rendering (capped at 2×) · react 18.3.1, react-router-dom 6.30.6, vite 5.4.21
Dependencies
react 18.3.1, matter-js 0.20.0
Imported APIs
withControls — Wraps the demo in the shared control panel (presets, sliders, reset); hot-updates or remounts on change; paramsFromSpec — Turns the spec (colour/speed/size/count/extras) into control-panel parameter definitions; createCanvasStage — Shared Canvas 2D stage: canvas + info panel, HiDPI, one rAF loop, pointer state, idle auto-pointer; rng — Seeded deterministic PRNG (same seed, same result); hueOf — Hue of a colour (0–360°); clamp — Clamps a value to a range; TAU — Constant 2π; fmt — Number formatting (fixed decimals); F — Formula block HTML; libs — Loads third-party libraries from CDN on demand (jsDelivr → npmmirror → unpkg); S.onResize — Canvas resized; S.onDown — Pointer down; S.onUp — Pointer up; S.clear — Clears with the background colour (translucent = trails); S.get — Reads current control values; S.onFrame — Registers a per-frame callback; its return value feeds the info panel; Matter.Engine.create — Creates the physics engine; Matter.Events.on — Subscribes to engine events (collisions); Matter.Query.point — Finds bodies under a point; Matter.Constraint.create — Creates a constraint (spring/hinge/drag); Matter.Composite.add — Adds bodies/constraints to the world; Matter.Composite.remove — Removes bodies from the world; Matter.World.clear — Clears the world; Matter.Engine.clear — Clears the engine
Source code
frontend/src/demos/kits/kit-physics.js: FAM.matter (L37-L100)
Code walkthrough
L39-39: Control definitions (colour/speed/size/count/extras): Object primary color, Object Size, Number of objects, Elasticity coefficient e, Gravity multiplier, Friction coefficient μ. L40-40: Preset buttons: name → parameter overrides (5). L41-49: Info-panel content: live rows(v), formula, notes, params, steps. L50-99: Init function: sets up state and returns the per-frame callback: registers pointer handlers `S.onDown`, `S.onUp`; draws with Canvas 2D `fillText`, `beginPath`, `moveTo`, `lineTo`, `closePath`, `fill` …; calls Matter.js `Engine.create`, `Events.on`, `Query.point`, `Constraint.create`, `Composite.add` …; math via `Math.min`, `Math.round`, `Math.abs`, `Math.max`; returns readouts `n`, `ke`, `vm`, `col`, `e`, `fr`, `g` … to the info panel.
Principles
Newton's second law: m·a = Σ F (Gravity + Exposure) Collision impulse j = − (1 + e) · v_rel · n / (1 / m₁ + 1 / m₂) Friction |F_f| ≤ μ · |F_n| It's a real Gono physics engine Matter.js :每个圆、方块、多边形都有质量、速度和角速度,每一步先按重力积分,再检测相互穿透并用 Impulse Push them away. Escalation factor e Determination of how much relative speed to keep after collision 1 = Full elasticity 0 = 粘在一起);摩擦让物体在接触面上减速、能堆起来。 There is a slowly rotating mixer in the middle, and the pointer itself is an invisible disc that pushes the object away. Press the object to catch it and throw it out.