Skip to content

Latest commit

 

History

History
110 lines (85 loc) · 5.82 KB

File metadata and controls

110 lines (85 loc) · 5.82 KB

Draggable RigidBody Component

A flexible drag-and-drop component for React Three Fiber + react-three-rapier

GitHub stars

demo

Features

  • Drag-and-Drop Physics: Physics-based dragging built on the react-three-rapier physics engine and a custom drag-controls implementation (CustomDragControls).
  • Customizable Bounding Box: Restrict object movement within defined boundaries.
  • Wobbly effect: Optional spring joints provide "wobbly" effects for objects during and after drag events.
  • Invisible Mesh for Control: Uses a hidden mesh to improve the precision and fluidity of dragging.
  • Flexible Configuration: Easily configurable parameters for drag limits, joint stiffness, damping, and more.

Installation

This is not a published npm package. Download DraggableRigidBody.tsx and CustomDragControls.tsx from this repo and import them into your project.

The two files rely on the following runtime dependencies, which must already be installed in your project:

npm install three @react-three/fiber @react-three/rapier @react-three/drei @use-gesture/react
  • @use-gesture/react powers the dragging logic in CustomDragControls.tsx.
  • @react-three/drei is used only for a TypeScript type helper (ForwardRefComponent); drei's own DragControls is not used.

Important

CustomDragControls is a modified version of drei's DragControls that fixes overlaps (see this issue and this PR for additional info).

const DraggableRigidBodyProps: Partial<DraggableRigidBodyProps> = {
  dragControlsProps: {
    preventOverlap: true,
  },
};

Usage

Here's an example of how you can use the DraggableRigidBody component in your React Three Fiber scene:

function MyScene() {
  const DraggableRigidBodyProps: Partial<DraggableRigidBodyProps> = {
    rigidBodyProps: {
      gravityScale: 3.5,
      linearDamping: 5,
      angularDamping: 0.2,
    },
    boundingBox: [
      [-8, 8],
      [0.5, 8],
      [-8, 8],
    ],
    dragControlsProps: {
      preventOverlap: true,
    },
  };

  return (
    <Canvas>
      <Physics>
        <DraggableRigidBody
          {...DraggableRigidBodyProps}
          visibleMesh={
            <mesh castShadow receiveShadow>
              <boxGeometry args={[1, 1, 1]} />
              <meshStandardMaterial color={"gray"} wireframe={false} />
            </mesh>
          }
        />
      </Physics>
    </Canvas>
  );
}

Props

Prop Name Type Description
visibleMesh ReactElement<ThreeElements['mesh']> The mesh visible in the scene.
groupProps GroupProps Set position, rotation.
boundingBox [[number, number], ...] Define min/max boundaries for dragging on the X, Y, and Z axes.
dragControlsProps Partial<CustomDragControlsProps> Customize drag control behavior; set preventOverlap to true to avoid overlaps.
rigidBodyProps RigidBodyProps Pass properties to the RigidBody component (e.g., mass, friction).
invisibleMesh ReactElement<ThreeElements['mesh']> A mesh used for precise drag control but hidden in the scene. Defaults to visibleMesh.
enableSpringJoint boolean Enable a spring joint for elastic drag behavior.
jointConfig { restLength, stiffness, damping, springJointCollisionGroups } Configure spring joint properties (rest length, stiffness, and damping).

Tech stack

WARNING

This is a work in progress! Take it as an example for your projects :)