AVINN
← Back to Blog
2025-04-10Tutorial2 min read

Physics-Based UI with Matter.js

What if your UI elements had weight? What if buttons could fall, bounce, and collide? That's exactly what Matter.js enables — and it's more practical than you might think.

Why Physics in UI?

Physics-based interactions create a sense of tangibility. When a user drags an element and it has momentum, when badges pile up with gravity — it feels real. This kind of micro-delight is what separates memorable websites from forgettable ones.

The Approach: DOM-Synced Physics

Most Matter.js tutorials use canvas rendering. But for a portfolio website, we want real DOM elements (for accessibility, SEO, and styling flexibility). The trick is:

  1. Create Matter.js bodies that match your DOM elements' dimensions
  2. Run the physics simulation
  3. On each frame, sync the DOM elements' positions to their physics bodies
// Create a body matching a DOM badge
const body = Matter.Bodies.rectangle(x, y, width, height, {
  restitution: 0.4,  // bounciness
  friction: 0.3,
  chamfer: { radius: height / 2 },  // rounded corners
});

// Sync DOM position on each physics update
Matter.Events.on(engine, "afterUpdate", () => {
  badges.forEach(({ body, element }) => {
    element.style.transform = `
      translate(${body.position.x - w/2}px, ${body.position.y - h/2}px)
      rotate(${body.angle}rad)
    `;
  });
});

Making It Interactive

The magic happens when users can interact with the physics world:

const mouse = Matter.Mouse.create(container);
const mouseConstraint = Matter.MouseConstraint.create(engine, {
  mouse,
  constraint: { stiffness: 0.2 },
});
Matter.Composite.add(engine.world, mouseConstraint);

Now users can grab, drag, and throw elements around. It's surprisingly satisfying.

Performance Considerations

  • Dynamic import Matter.js to avoid SSR issues in Next.js
  • Pause the engine when the section isn't visible (IntersectionObserver)
  • Limit body count — 15-20 bodies is plenty for a smooth experience
  • Use Runner instead of manual Engine.update() for consistent timing

The Result

On my portfolio, the tech stack section uses this exact technique. Technology badges fall from the top, pile up naturally, and visitors can drag them around. It's a conversation starter and demonstrates technical capability simultaneously.

Physics-based UI isn't just a gimmick — it's a tool for creating memorable, interactive experiences that make your work stand out.