0
# Animated Three.js Components
1
2
Animated versions of all Three.js objects and components for use with react-spring animations. The `animated` factory automatically creates animated versions of Three.js primitives that can accept spring values as props.
3
4
## Capabilities
5
6
### Animated Factory Function
7
8
Creates animated versions of any React Three Fiber component that can accept spring values as props.
9
10
```typescript { .api }
11
/**
12
* Creates an animated version of any component
13
* @param Component - React component to make animatable
14
* @returns Animated component that accepts spring values
15
*/
16
function animated<T extends ElementType>(Component: T): AnimatedComponent<T>;
17
18
// Short alias
19
const a = animated;
20
```
21
22
**Usage Examples:**
23
24
```typescript
25
import { animated, useSpring } from "@react-spring/three";
26
27
// Using built-in animated primitives
28
function AnimatedMesh() {
29
const springs = useSpring({
30
position: [0, 1, 0],
31
from: { position: [0, 0, 0] },
32
});
33
34
return (
35
<animated.mesh {...springs}>
36
<boxGeometry />
37
<meshStandardMaterial color="blue" />
38
</animated.mesh>
39
);
40
}
41
42
// Creating custom animated components
43
const AnimatedCustomComponent = animated(MyCustomThreeComponent);
44
```
45
46
### Built-in Animated Primitives
47
48
Pre-built animated versions of all Three.js components. These are automatically generated from Three.js class names by filtering all Three.js exported classes and converting their names to lowercase with the first letter lowercase.
49
50
```typescript { .api }
51
type Primitives = keyof JSX.IntrinsicElements;
52
53
type AnimatedPrimitives = {
54
[P in Primitives]: AnimatedComponent<FC<JSX.IntrinsicElements[P]>>;
55
};
56
57
/**
58
* All Three.js classes are automatically converted to animated primitives.
59
* The primitive names are generated by:
60
* 1. Taking all Three.js exports that start with uppercase letter
61
* 2. Converting first letter to lowercase
62
*
63
* Examples of available animated primitives include:
64
* - Geometries: boxGeometry, sphereGeometry, cylinderGeometry, planeGeometry, etc.
65
* - Meshes: mesh, instancedMesh, skinnedMesh, etc.
66
* - Materials: meshBasicMaterial, meshStandardMaterial, meshPhysicalMaterial, etc.
67
* - Lights: ambientLight, directionalLight, pointLight, spotLight, etc.
68
* - Cameras: perspectiveCamera, orthographicCamera, etc.
69
* - Controls: orbitControls, transformControls, etc.
70
* - Plus the special 'primitive' component for arbitrary Three.js objects
71
*/
72
const primitives: Primitives[] = ['primitive'].concat(
73
Object.keys(THREE)
74
.filter(key => /^[A-Z]/.test(key))
75
.map(key => key[0].toLowerCase() + key.slice(1))
76
);
77
```
78
79
**Usage Examples:**
80
81
```typescript
82
import { animated, useSpring, useTrail } from "@react-spring/three";
83
84
// Animating mesh properties
85
function AnimatedCube() {
86
const { rotation, scale } = useSpring({
87
rotation: [0, Math.PI * 2, 0],
88
scale: [1.2, 1.2, 1.2],
89
from: { rotation: [0, 0, 0], scale: [1, 1, 1] },
90
loop: true,
91
});
92
93
return (
94
<animated.mesh rotation={rotation} scale={scale}>
95
<animated.boxGeometry args={[1, 1, 1]} />
96
<animated.meshStandardMaterial color="orange" />
97
</animated.mesh>
98
);
99
}
100
101
// Animating material properties
102
function AnimatedMaterial() {
103
const { color, opacity } = useSpring({
104
color: "#ff6b6b",
105
opacity: 0.8,
106
from: { color: "#4ecdc4", opacity: 0.2 },
107
});
108
109
return (
110
<mesh>
111
<boxGeometry />
112
<animated.meshStandardMaterial color={color} transparent opacity={opacity} />
113
</mesh>
114
);
115
}
116
117
// Trail animation for multiple objects
118
function AnimatedTrail() {
119
const trail = useTrail(5, {
120
position: [[0, 0, 0], [1, 0, 0], [2, 0, 0], [3, 0, 0], [4, 0, 0]],
121
from: { position: [0, -5, 0] },
122
});
123
124
return (
125
<>
126
{trail.map((springs, index) => (
127
<animated.mesh key={index} {...springs}>
128
<sphereGeometry args={[0.2]} />
129
<meshStandardMaterial color="red" />
130
</animated.mesh>
131
))}
132
</>
133
);
134
}
135
```
136
137
### Generic Primitive Animation
138
139
Special animated primitive component for animating arbitrary Three.js objects.
140
141
```typescript { .api }
142
/**
143
* Animated primitive component for arbitrary Three.js objects
144
*/
145
interface PrimitiveProps {
146
object: any; // Three.js object instance
147
[key: string]: any; // Additional props to animate
148
}
149
```
150
151
**Usage Examples:**
152
153
```typescript
154
import * as THREE from "three";
155
import { animated, useSpring } from "@react-spring/three";
156
157
function AnimatedCustomObject() {
158
const customGeometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);
159
160
const springs = useSpring({
161
rotation: [0, Math.PI, 0],
162
from: { rotation: [0, 0, 0] },
163
});
164
165
return (
166
<animated.primitive object={customGeometry} {...springs}>
167
<meshStandardMaterial color="purple" />
168
</animated.primitive>
169
);
170
}
171
```
172
173
## Types
174
175
```typescript { .api }
176
import { CSSProperties, ForwardRefExoticComponent, FC, JSX, ElementType } from 'react';
177
import { AssignableKeys, ComponentPropsWithRef } from '@react-spring/types';
178
import { FluidValue } from '@react-spring/shared';
179
180
type AnimatedComponent<T extends ElementType> =
181
ForwardRefExoticComponent<AnimatedProps<ComponentPropsWithRef<T>>>;
182
183
type AnimatedProps<Props extends object> = {
184
[P in keyof Props]: P extends 'ref' | 'key'
185
? Props[P]
186
: AnimatedProp<Props[P]>;
187
};
188
189
// Complex type for animated prop values that handles style objects and arrays
190
type AnimatedProp<T> = [T, T] extends [infer T, infer DT]
191
? [DT] extends [never]
192
? never
193
: DT extends void
194
? undefined
195
: DT extends object
196
? [AssignableKeys<DT, CSSProperties>] extends [never]
197
? DT extends ReadonlyArray<any>
198
? AnimatedStyles<DT>
199
: DT
200
: AnimatedStyle<T>
201
: DT | AnimatedLeaf<T>
202
: never;
203
204
// Animated array of style objects
205
type AnimatedStyles<T extends ReadonlyArray<any>> = {
206
[P in keyof T]: [T[P]] extends [infer DT]
207
? DT extends object
208
? [AssignableKeys<DT, CSSProperties>] extends [never]
209
? DT extends ReadonlyArray<any>
210
? AnimatedStyles<DT>
211
: DT
212
: { [P in keyof DT]: AnimatedProp<DT[P]> }
213
: DT
214
: never;
215
};
216
217
// Animated object of style attributes
218
type AnimatedStyle<T> = [T, T] extends [infer T, infer DT]
219
? DT extends void
220
? undefined
221
: [DT] extends [never]
222
? never
223
: DT extends object
224
? { [P in keyof DT]: AnimatedStyle<DT[P]> }
225
: DT | AnimatedLeaf<T>
226
: never;
227
228
// Animated primitive (or an array of them)
229
type AnimatedLeaf<T> =
230
| Exclude<T, object | void>
231
| Extract<T, ReadonlyArray<number | string>> extends infer U
232
? [U] extends [never]
233
? never
234
: FluidValue<U | Exclude<T, object | void>>
235
: never;
236
237
// The type of the animated() function
238
type WithAnimated = {
239
<T extends ElementType>(wrappedComponent: T): AnimatedComponent<T>;
240
} & AnimatedPrimitives;
241
```