0
# Gestures and Interactions
1
2
Comprehensive gesture system for handling drag, pan, hover, and tap interactions with physics-based animations and constraint support.
3
4
## Capabilities
5
6
### Drag Controls
7
8
Imperative drag controls for programmatically managing drag interactions.
9
10
```typescript { .api }
11
/**
12
* Hook for creating drag controls
13
* @returns Drag controls object
14
*/
15
function useDragControls(): DragControls;
16
17
interface DragControls {
18
/** Start dragging from an event */
19
start(event: React.PointerEvent | PointerEvent, options?: DragStartOptions): void;
20
/** Stop current drag operation */
21
stop(): void;
22
/** Check if currently dragging */
23
isDragging(): boolean;
24
}
25
26
interface DragStartOptions {
27
/** Point from which to start drag */
28
point?: Point;
29
/** Snap back to origin after drag */
30
snapToCursor?: boolean;
31
}
32
33
interface Point {
34
x: number;
35
y: number;
36
}
37
```
38
39
**Usage Examples:**
40
41
```typescript
42
import { motion, useDragControls } from "motion/react";
43
44
function DragControlExample() {
45
const dragControls = useDragControls();
46
47
const startDrag = (event: React.PointerEvent) => {
48
dragControls.start(event, { snapToCursor: true });
49
};
50
51
return (
52
<div>
53
<div onPointerDown={startDrag}>
54
Custom drag handle
55
</div>
56
<motion.div
57
drag
58
dragControls={dragControls}
59
dragConstraints={{ left: 0, right: 300, top: 0, bottom: 300 }}
60
>
61
Draggable element
62
</motion.div>
63
</div>
64
);
65
}
66
```
67
68
### Drag Configuration
69
70
Configuration options for drag behavior on motion components.
71
72
```typescript { .api }
73
interface DragProps {
74
/** Enable dragging */
75
drag?: boolean | "x" | "y";
76
/** Drag constraints */
77
dragConstraints?: Partial<Box> | React.RefObject<Element> | false;
78
/** Drag controls object */
79
dragControls?: DragControls;
80
/** Elastic behavior when dragging beyond constraints */
81
dragElastic?: boolean | number | Partial<BoundingBox>;
82
/** Enable drag momentum */
83
dragMomentum?: boolean;
84
/** Minimum distance to start drag */
85
dragDirectionLock?: boolean;
86
/** Threshold for direction lock */
87
dragTransition?: Transition;
88
/** Propagate drag to parent */
89
dragPropagation?: boolean;
90
/** Snap back to origin */
91
dragSnapToOrigin?: boolean;
92
/** Listen for drag on child elements */
93
dragListener?: boolean;
94
}
95
96
interface Box {
97
left: number;
98
right: number;
99
top: number;
100
bottom: number;
101
}
102
103
interface BoundingBox {
104
left: number;
105
right: number;
106
top: number;
107
bottom: number;
108
}
109
```
110
111
### Gesture Event Handlers
112
113
Event handlers for various gesture interactions.
114
115
```typescript { .api }
116
interface GestureHandlers {
117
/** Called when drag starts */
118
onDragStart?: (event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => void;
119
/** Called during drag */
120
onDrag?: (event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => void;
121
/** Called when drag ends */
122
onDragEnd?: (event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => void;
123
/** Called when pan starts */
124
onPanStart?: (event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => void;
125
/** Called during pan */
126
onPan?: (event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => void;
127
/** Called when pan ends */
128
onPanEnd?: (event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => void;
129
/** Called on tap/click */
130
onTap?: (event: MouseEvent | TouchEvent | PointerEvent, info: TapInfo) => void;
131
/** Called when tap starts */
132
onTapStart?: (event: MouseEvent | TouchEvent | PointerEvent, info: TapInfo) => void;
133
/** Called when tap is cancelled */
134
onTapCancel?: (event: MouseEvent | TouchEvent | PointerEvent, info: TapInfo) => void;
135
/** Called on hover start */
136
onHoverStart?: (event: MouseEvent, info: HoverInfo) => void;
137
/** Called on hover end */
138
onHoverEnd?: (event: MouseEvent, info: HoverInfo) => void;
139
}
140
141
interface PanInfo {
142
/** Current pointer position relative to page */
143
point: Point;
144
/** Distance moved since last event */
145
delta: Point;
146
/** Distance moved since gesture start */
147
offset: Point;
148
/** Current velocity */
149
velocity: Point;
150
}
151
152
interface TapInfo {
153
/** Tap position relative to page */
154
point: Point;
155
}
156
157
interface HoverInfo {
158
/** Hover position relative to page */
159
point: Point;
160
}
161
```
162
163
**Usage Examples:**
164
165
```typescript
166
import { motion } from "motion/react";
167
168
function GestureExample() {
169
const handleDrag = (event: any, info: PanInfo) => {
170
console.log("Dragging:", info.offset);
171
};
172
173
const handleDragEnd = (event: any, info: PanInfo) => {
174
console.log("Drag ended with velocity:", info.velocity);
175
};
176
177
const handleTap = (event: any, info: TapInfo) => {
178
console.log("Tapped at:", info.point);
179
};
180
181
return (
182
<motion.div
183
drag
184
onDrag={handleDrag}
185
onDragEnd={handleDragEnd}
186
onTap={handleTap}
187
whileDrag={{ scale: 1.1 }}
188
whileHover={{ scale: 1.05 }}
189
whileTap={{ scale: 0.95 }}
190
>
191
Interactive element
192
</motion.div>
193
);
194
}
195
```
196
197
### Hover Interactions
198
199
Hover-based animations and state management.
200
201
```typescript { .api }
202
interface HoverProps {
203
/** Animation while hovering */
204
whileHover?: Target | VariantLabels;
205
/** Hover event handlers */
206
onHoverStart?: (event: MouseEvent, info: HoverInfo) => void;
207
onHoverEnd?: (event: MouseEvent, info: HoverInfo) => void;
208
}
209
```
210
211
**Usage Examples:**
212
213
```typescript
214
import { motion } from "motion/react";
215
216
function HoverCard() {
217
return (
218
<motion.div
219
whileHover={{
220
scale: 1.05,
221
boxShadow: "0 10px 30px rgba(0,0,0,0.2)",
222
transition: { duration: 0.2 }
223
}}
224
onHoverStart={() => console.log("Hover started")}
225
onHoverEnd={() => console.log("Hover ended")}
226
>
227
Hover over me
228
</motion.div>
229
);
230
}
231
```
232
233
### Tap/Press Interactions
234
235
Tap and press gesture handling with feedback animations.
236
237
```typescript { .api }
238
interface TapProps {
239
/** Animation while tapping/pressing */
240
whileTap?: Target | VariantLabels;
241
/** Tap event handlers */
242
onTap?: (event: MouseEvent | TouchEvent | PointerEvent, info: TapInfo) => void;
243
onTapStart?: (event: MouseEvent | TouchEvent | PointerEvent, info: TapInfo) => void;
244
onTapCancel?: (event: MouseEvent | TouchEvent | PointerEvent, info: TapInfo) => void;
245
}
246
```
247
248
**Usage Examples:**
249
250
```typescript
251
import { motion } from "motion/react";
252
253
function TapButton() {
254
return (
255
<motion.button
256
whileTap={{
257
scale: 0.9,
258
backgroundColor: "#4f46e5"
259
}}
260
onTap={(event, info) => {
261
console.log("Button tapped at:", info.point);
262
}}
263
style={{
264
padding: "12px 24px",
265
background: "#6366f1",
266
color: "white",
267
border: "none",
268
borderRadius: "6px"
269
}}
270
>
271
Tap me
272
</motion.button>
273
);
274
}
275
```
276
277
### Focus Interactions
278
279
Focus-based animations for keyboard navigation and accessibility.
280
281
```typescript { .api }
282
interface FocusProps {
283
/** Animation while focused */
284
whileFocus?: Target | VariantLabels;
285
}
286
```
287
288
### InView Interactions
289
290
Viewport-based animations that trigger when elements enter or leave view.
291
292
```typescript { .api }
293
interface InViewProps {
294
/** Animation while in view */
295
whileInView?: Target | VariantLabels;
296
/** Viewport options */
297
viewport?: ViewportOptions;
298
}
299
300
interface ViewportOptions {
301
/** Root element for intersection */
302
root?: React.RefObject<Element>;
303
/** Root margin */
304
margin?: string;
305
/** Intersection amount */
306
amount?: "some" | "all" | number;
307
/** Run animation only once */
308
once?: boolean;
309
}
310
```
311
312
**Usage Examples:**
313
314
```typescript
315
import { motion } from "motion/react";
316
317
function ScrollReveal() {
318
return (
319
<motion.div
320
initial={{ opacity: 0, y: 50 }}
321
whileInView={{
322
opacity: 1,
323
y: 0,
324
transition: { duration: 0.6 }
325
}}
326
viewport={{
327
once: true,
328
amount: 0.3
329
}}
330
>
331
This animates when scrolled into view
332
</motion.div>
333
);
334
}
335
```
336
337
### Advanced Gesture Configuration
338
339
Advanced configuration options for fine-tuning gesture behavior.
340
341
```typescript { .api }
342
interface AdvancedGestureProps {
343
/** Drag direction lock */
344
dragDirectionLock?: boolean;
345
/** Direction lock threshold */
346
dragDirectionLockThreshold?: number;
347
/** Minimum distance to initiate pan */
348
dragStartDistance?: number;
349
/** Enable momentum scrolling */
350
dragMomentum?: boolean;
351
/** Momentum velocity multiplier */
352
dragMomentumVelocity?: number;
353
/** Transition for drag animations */
354
dragTransition?: Transition;
355
/** Enable drag propagation to parent */
356
dragPropagation?: boolean;
357
/** Elastic overshoot amount */
358
dragElastic?: boolean | number;
359
}
360
```
361
362
### Multi-Touch Gestures
363
364
Support for multi-touch gestures and pinch-to-zoom interactions.
365
366
```typescript { .api }
367
interface MultiTouchProps {
368
/** Enable pinch-to-zoom */
369
pinch?: boolean;
370
/** Enable rotation gestures */
371
rotate?: boolean;
372
/** Multi-touch event handlers */
373
onPinchStart?: (event: TouchEvent, info: PinchInfo) => void;
374
onPinch?: (event: TouchEvent, info: PinchInfo) => void;
375
onPinchEnd?: (event: TouchEvent, info: PinchInfo) => void;
376
}
377
378
interface PinchInfo {
379
/** Current scale */
380
scale: number;
381
/** Scale delta */
382
scaleOffset: number;
383
/** Center point of pinch */
384
point: Point;
385
}
386
```
387
388
**Usage Examples:**
389
390
```typescript
391
import { motion } from "motion/react";
392
393
function PinchZoomImage() {
394
return (
395
<motion.img
396
src="/image.jpg"
397
pinch
398
onPinch={(event, info) => {
399
console.log("Pinch scale:", info.scale);
400
}}
401
style={{
402
touchAction: "none" // Prevent browser zoom
403
}}
404
/>
405
);
406
}
407
```