Drag Gesture
Relevant source files
The following files were used as context for generating this wiki page:
The Drag Gesture module in @pcstyle/motion provides a set of pre-configured objects and animation targets designed to simplify the implementation of draggable elements within a React application using Framer Motion. It encapsulates common patterns such as directional locking, constrained movement, and slider-specific physics, ensuring consistent interaction behavior across the project.
This module works in conjunction with Transitions to define how elements behave during and after a drag interaction, particularly concerning momentum and elasticity.
Sources: src/gestures/drag.ts:1-73, src/index.ts:1-20
Configuration Presets
The library exports several constants that define the physical behavior of a drag interaction. These configurations manage the axes of movement, the degree of "elasticity" (how much an element can be pulled past its bounds), and whether momentum is applied when the user releases the element.
Drag Types and Physics
Different presets are available based on the desired UX pattern:
| Constant | Drag Axis | Elasticity | Momentum | Description |
|---|---|---|---|---|
dragFree | All | 0.2 | True | Standard multidirectional drag. |
dragX | Horizontal | 0.2 | True | Movement restricted to the X-axis. |
dragY | Vertical | 0.2 | True | Movement restricted to the Y-axis. |
dragConstrained | All | 0.1 | N/A | Bound to specific coordinates (defaults to 0). |
dragSnap | All | 0 | False | Moves strictly with the pointer; no momentum. |
dragSlider | Horizontal | 0.05 | True | Specialized for sliders with custom bounce settings. |
Sources: src/gestures/drag.ts:8-51
Slider-Specific Transition
The dragSlider configuration includes a specific dragTransition object to control the "snap back" effect when hitting bounds:
- bounceStiffness: 300
- bounceDamping: 20
Sources: src/gestures/drag.ts:46-51
Visual Feedback
To enhance the user experience, the module provides TargetAndTransition objects intended for the whileDrag prop in Framer Motion. These styles apply automatically while the user is actively interacting with the element.
- whileDragScale: Increases the element scale to 1.05 and changes the cursor to
grabbing. - whileDragShadow: Slightly scales the element (1.02) and applies a deep box shadow (
0 10px 30px rgba(0, 0, 0, 0.3)) to simulate the element lifting off the page.
Sources: src/gestures/drag.ts:56-65
Physics and Inertia
When a drag gesture ends, the library utilizes inertia transitions to calculate the "glide" or "bounce" of the element. These settings are defined in the transitions sub-module and are often used by the drag gesture logic to finalize movement.
The diagram above shows the logic flow when a drag interaction is terminated by the user.
Sources: src/gestures/drag.ts:10-51, src/transitions/inertia.ts:1-35
Physics Configurations
Relevant physics parameters used for draggable elements include:
| Transition Name | Type | Key Properties |
|---|---|---|
springDrag | Spring | Stiffness: 300, Damping: 30, Mass: 0.8 |
inertiaScroll | Inertia | Power: 0.8, TimeConstant: 700 |
inertiaBounce | Inertia | bounceStiffness: 300, bounceDamping: 10 |
Sources: src/transitions/spring.ts:46-52, src/transitions/inertia.ts:8-35
Implementation Example
The gesture configurations are designed to be spread directly into Framer Motion's motion components.
import { motion } from "framer-motion";
import { dragFree, whileDragScale } from "@pcstyle/motion/gestures";
export const DraggableComponent = () => (
<motion.div
{...dragFree}
whileDrag={whileDragScale}
>
Drag Me
</motion.div>
);
Sources: src/gestures/drag.ts:8-12, src/gestures/drag.ts:56-59
Summary
The Drag Gesture module provides a standardized way to implement draggable UI components by separating the physical configuration (momentum, elasticity, constraints) from visual state transitions (scaling, shadows). By leveraging predefined transitions like springDrag and inertiaScroll, the system ensures that user interactions feel responsive and adhere to the project's specific aesthetic and technical requirements.
Sources: src/gestures/drag.ts, src/transitions/spring.ts, src/transitions/inertia.ts