Gravity
godui/gravityFreeComponent
A physics playground where elements fall, pile, collide, and can be dragged and flung.
Install it
npx shadcn@latest add https://godui.design/r/gravity.jsonSource
1"use client";23import Matter from "matter-js";4import * as React from "react";56type Vec2 = { x: number; y: number };78type RegisteredBody = {9 element: HTMLElement;10 body: Matter.Body;11 isDraggable: boolean;12};1314type GravityContextValue = {15 register: (16 id: string,17 element: HTMLElement,18 config: {19 x: number | string;20 y: number | string;21 angle: number;22 bodyType: "rectangle" | "circle";23 isDraggable: boolean;24 options?: Matter.IChamferableBodyDefinition;25 },26 ) => void;27 unregister: (id: string) => void;28 reduced: boolean;29};3031const GravityContext = React.createContext<GravityContextValue | null>(null);3233export type GravityProps = React.HTMLAttributes<HTMLDivElement> & {34 /** World gravity vector. `y: 1` falls down; `{ x: 0, y: 0 }` floats. */35 gravity?: Vec2;36 /** Start the simulation immediately (default) or wait for the API. */37 autoStart?: boolean;38 /** Close the top so flung bodies can't escape upward. */39 addTopWall?: boolean;40 /** Bounciness of the walls and bodies, 0–1. */41 restitution?: number;42};4344/** Resolve a percentage/px position string against a container dimension. */45function resolve(value: number | string, size: number): number {46 if (typeof value === "number") return value;47 if (value.endsWith("%")) return (parseFloat(value) / 100) * size;48 return parseFloat(value);49}5051const Gravity = React.forwardRef<HTMLDivElement, GravityProps>(52 (53 {54 gravity = { x: 0, y: 1 },55 autoStart = true,56 addTopWall = true,57 restitution = 0.4,58 className,59 children,60 ...props61 },62 forwardedRef,63 ) => {64 const reduced = useReducedMotionSafe();65 const canvasRef = React.useRef<HTMLDivElement>(null);66 React.useImperativeHandle(67 forwardedRef,68 () => canvasRef.current as HTMLDivElement,69 );7071 // Create the engine at render, not in an effect: child `MatterBody` effects72 // run before the parent's effect, so the engine must already exist when they73 // register their bodies.74 const [engine] = React.useState(() => Matter.Engine.create());75 const bodiesRef = React.useRef(new Map<string, RegisteredBody>());76 const wallsRef = React.useRef<Matter.Body[]>([]);7778 // Keep gravity in sync without rebuilding the world (which would drop the79 // bodies the children registered).80 React.useEffect(() => {81 engine.gravity.x = gravity.x;82 engine.gravity.y = gravity.y;83 }, [engine, gravity.x, gravity.y]);8485// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from godui
All 105 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | godui | Components | Free | 1 dep | |
| Agent Flowagent-flow | godui | Components | Free | 1 dep | |
| Agent Timelineagent-timeline | godui | Components | Free | 1 dep | |
| Animated Beamanimated-beam | godui | Components | Free | 1 dep | |
| Animated Testimonialsanimated-testimonials | godui | Components | Free | 1 dep | |
| Animated Tooltipanimated-tooltip | godui | Components | Free | 1 dep | |
| App Showcaseapp-showcase | godui | Components | Free | 1 dep | |
| Aurora Textaurora-text | godui | Components | Free | no deps |
