Docslayout
🌀 PHASE-2 LAYOUT ENGINE (Impulse-FLIP)
VibeDev Motion's layout engine provides a high-performance physical model for spatial transitions, replacing standard linear springs with Physical Impulses.
1. THE CORE HOOK: usePhysicalLayout
The usePhysicalLayout hook captures the DOM's First and Last states and converts the delta into a physical force in the Rapier WASM world.
🧠 Logic Overview
- Capture: Detects the element's position before and after a layout change.
- Solve: Calculates the "Invert" delta (the distance it needs to travel).
- Impulse: Instead of a simple animation, it applies a physical impulse to the rigid body to "launch" it toward its new home.
// Internal hook logic used by vibe components
export function usePhysicalLayout(body: RigidBody | null, options: PhysicalLayoutOptions = {}) {
const { layout, layoutId } = options;
// 1. Capture the change
const lastRect = elementRef.current.getBoundingClientRect();
const invertX = firstRect.left - lastRect.left;
const invertY = firstRect.top - lastRect.top;
// 2. Solve via Physics (Impulse-FLIP)
if (layout === 'physics' && body) {
const impulse = { x: invertX * 0.1, y: invertY * 0.1 };
body.applyImpulse(impulse, true);
}
}
2. API REFERENCE: Layout Props
layout: boolean | "position" | "physics"
true: Standard FLIP (silky smooth springs)."position": Animate movement only, skip size scaling (prevents distortion on text)."physics": Enable the full rigid-body interaction model.
layoutId: string
- Maps two elements across different component trees for shared transitions.
- PERSISTENT MOMENTUM: Velocity from an unmounting element is transferred accurately to the new mounting element.
layoutScroll: boolean
- Essential for elements inside scrollable containers.
- Automatically calculates scroll velocity and applies it as a counter-force during layout shifts to prevent jitter.
3. COMPONENT: <LayoutGroup />
The LayoutGroup component synchronizes layout animations across multiple independent components that affect each other's spatial position.
🛠️ Usage
import { LayoutGroup, vibe } from 'vibedev-motion';
function List() {
return (
<LayoutGroup>
<vibe.div layout="physics">Item 1</vibe.div>
<vibe.div layout="physics">Item 2</vibe.div>
</LayoutGroup>
);
}
4. FEATURE: Automatic Scale Correction
VibeDev Motion eliminates the need to pass layout props to every child. It intelligently uses CSS variables provided by the parent.
🧠 Logic
- Parent
vibecomponent calculates its scale delta. - It sets
--vibe-counter-scale-xand--vibe-counter-scale-y. - All children
vibecomponents automatically consume these variables to prevent visual distortion of children (like text or icons).
5. EXAMPLE USE CASE: "The Solid Modal"
When a grid item expands into a modal:
- The grid item unmounts, saving its velocity to the layoutRegistry.
- The Modal mounts with the same
layoutId. usePhysicalLayoutretrieves the velocity and "launches" the modal visually from the grid item's location.- Because
layout="physics"is active, the expanding modal can physically "push" other dashboard widgets aside as it grows.