or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdmotion.mdspring-system.mdstaggered-motion.mdtransition-motion.md

spring-system.mddocs/

0

# Spring System

1

2

React Motion's spring system provides physics-based animation configurations that feel more natural than traditional easing curves. Instead of specifying durations, you define spring characteristics like stiffness and damping to control animation behavior.

3

4

## Capabilities

5

6

### spring Function

7

8

Creates a spring configuration object that defines how a value should animate to its target.

9

10

```javascript { .api }

11

/**

12

* Creates spring configuration for animated values

13

* @param val - Target value for the animation

14

* @param config - Optional spring configuration parameters

15

* @returns OpaqueConfig object for internal use by Motion components

16

*/

17

function spring(val/*: number */, config/*?: SpringHelperConfig */)/*: OpaqueConfig */;

18

```

19

20

**Usage Examples:**

21

22

```javascript

23

import { spring } from 'react-motion';

24

25

// Basic spring with default settings

26

const basicSpring = spring(100);

27

28

// Custom spring configuration

29

const customSpring = spring(100, {

30

stiffness: 120,

31

damping: 17,

32

precision: 0.1

33

});

34

35

// Using in Motion component

36

<Motion

37

style={{

38

x: spring(targetX),

39

y: spring(targetY, {stiffness: 200, damping: 20}),

40

opacity: spring(1, {stiffness: 300, damping: 30})

41

}}

42

>

43

{({x, y, opacity}) => (

44

<div style={{

45

transform: `translate(${x}px, ${y}px)`,

46

opacity

47

}}>

48

Animated element

49

</div>

50

)}

51

</Motion>

52

```

53

54

### SpringHelperConfig Interface

55

56

Configuration object for customizing spring behavior.

57

58

```javascript { .api }

59

/**

60

* Configuration options for spring behavior

61

* All properties are optional and have sensible defaults

62

*/

63

/*::

64

type SpringHelperConfig = {

65

stiffness?: number, // Spring stiffness - higher values create snappier animations (default: 170)

66

damping?: number, // Spring damping - higher values reduce oscillation (default: 26)

67

precision?: number, // Animation precision threshold - smaller values run longer (default: 0.01)

68

};

69

*/

70

```

71

72

### OpaqueConfig Interface

73

74

Internal spring configuration object returned by the spring function. Not meant for direct manipulation.

75

76

```javascript { .api }

77

/**

78

* Internal spring configuration object

79

* Used internally by Motion components - do not modify directly

80

*/

81

/*::

82

type OpaqueConfig = {

83

val: number, // Target value for animation

84

stiffness: number, // Spring stiffness parameter

85

damping: number, // Spring damping parameter

86

precision: number, // Precision threshold for stopping animation

87

};

88

*/

89

```

90

91

### presets Object

92

93

Pre-defined spring configurations for common animation styles.

94

95

```javascript { .api }

96

/**

97

* Pre-defined spring configuration presets

98

* Use these for common animation styles

99

*/

100

const presets = {

101

/** Default balanced preset - smooth with minimal bounce */

102

noWobble: { stiffness: 170, damping: 26 },

103

/** Gentle, slower animation with soft easing */

104

gentle: { stiffness: 120, damping: 14 },

105

/** More oscillation and bounce */

106

wobbly: { stiffness: 180, damping: 12 },

107

/** Quick, snappy animation with minimal overshoot */

108

stiff: { stiffness: 210, damping: 20 }

109

};

110

```

111

112

**Usage Examples:**

113

114

```javascript

115

import { spring, presets } from 'react-motion';

116

117

// Using presets

118

const gentleSpring = spring(100, presets.gentle);

119

const wobblySpring = spring(50, presets.wobbly);

120

const stiffSpring = spring(200, presets.stiff);

121

122

// Comparing presets in action

123

function PresetDemo() {

124

const [active, setActive] = useState(null);

125

126

const presetConfigs = [

127

{ name: 'noWobble', config: presets.noWobble },

128

{ name: 'gentle', config: presets.gentle },

129

{ name: 'wobbly', config: presets.wobbly },

130

{ name: 'stiff', config: presets.stiff }

131

];

132

133

return (

134

<div>

135

{presetConfigs.map(({ name, config }) => (

136

<Motion

137

key={name}

138

style={{

139

x: spring(active === name ? 200 : 0, config)

140

}}

141

>

142

{({ x }) => (

143

<div

144

style={{

145

transform: `translateX(${x}px)`,

146

padding: '10px',

147

margin: '5px 0',

148

background: '#007bff',

149

color: 'white',

150

cursor: 'pointer',

151

width: '200px'

152

}}

153

onClick={() => setActive(active === name ? null : name)}

154

>

155

{name}: stiffness={config.stiffness}, damping={config.damping}

156

</div>

157

)}

158

</Motion>

159

))}

160

</div>

161

);

162

}

163

```

164

165

### stripStyle Function

166

167

Utility function that extracts plain numeric values from style objects containing spring configurations.

168

169

```javascript { .api }

170

/**

171

* Extracts plain numeric values from spring-configured style objects

172

* @param style - Style object that may contain spring configurations

173

* @returns PlainStyle object with numeric values only

174

*/

175

function stripStyle(style/*: Style */)/*: PlainStyle */;

176

```

177

178

**Usage Examples:**

179

180

```javascript

181

import { stripStyle, spring } from 'react-motion';

182

183

// Style with springs

184

const styleWithSprings = {

185

x: spring(100, { stiffness: 120 }),

186

y: spring(200),

187

opacity: 1, // plain number

188

scale: spring(1.5, { damping: 20 })

189

};

190

191

// Extract plain values

192

const plainStyle = stripStyle(styleWithSprings);

193

// Result: { x: 100, y: 200, opacity: 1, scale: 1.5 }

194

195

// Useful for getting initial values

196

function MyComponent() {

197

const targetStyle = {

198

width: spring(expanded ? 300 : 100),

199

height: spring(expanded ? 200 : 50)

200

};

201

202

return (

203

<Motion

204

defaultStyle={stripStyle(targetStyle)} // Initial values without animation

205

style={targetStyle}

206

>

207

{interpolatedStyle => (

208

<div style={interpolatedStyle}>

209

Content

210

</div>

211

)}

212

</Motion>

213

);

214

}

215

```

216

217

## Spring Physics Explained

218

219

### Stiffness Parameter

220

221

Controls how quickly the spring tries to reach its target:

222

- **Low (60-120)**: Slower, more gentle animations

223

- **Medium (120-200)**: Balanced, natural feeling

224

- **High (200-300)**: Quick, snappy animations

225

226

```javascript

227

// Slow, gentle movement

228

spring(100, { stiffness: 80 })

229

230

// Quick, responsive movement

231

spring(100, { stiffness: 250 })

232

```

233

234

### Damping Parameter

235

236

Controls how much the spring oscillates around its target:

237

- **Low (8-15)**: More bounce and oscillation

238

- **Medium (15-30)**: Balanced with slight overshoot

239

- **High (30-50)**: Heavily damped, minimal overshoot

240

241

```javascript

242

// Bouncy animation

243

spring(100, { damping: 10 })

244

245

// Smooth with no overshoot

246

spring(100, { damping: 40 })

247

```

248

249

### Precision Parameter

250

251

Controls when the animation stops:

252

- **Smaller values (0.001-0.01)**: Animation runs longer, smoother ending

253

- **Larger values (0.1-1.0)**: Animation stops sooner, may feel abrupt

254

255

```javascript

256

// Very precise, runs until nearly perfect

257

spring(100, { precision: 0.001 })

258

259

// Less precise, stops when "close enough"

260

spring(100, { precision: 0.1 })

261

```

262

263

## Choosing Spring Parameters

264

265

### Common Combinations

266

267

```javascript

268

// UI Elements (buttons, menus)

269

spring(value, { stiffness: 300, damping: 30 })

270

271

// Layout changes (expanding panels)

272

spring(value, { stiffness: 120, damping: 17 })

273

274

// Playful interactions (hover effects)

275

spring(value, { stiffness: 180, damping: 12 })

276

277

// Smooth, professional (form transitions)

278

spring(value, { stiffness: 170, damping: 26 })

279

280

// Snappy mobile interactions

281

spring(value, { stiffness: 400, damping: 28 })

282

```

283

284

### Guidelines by Use Case

285

286

**Modal/Dialog Animations:**

287

```javascript

288

// Entry

289

{ stiffness: 300, damping: 30 }

290

// Exit

291

{ stiffness: 400, damping: 40 }

292

```

293

294

**List Item Transitions:**

295

```javascript

296

{ stiffness: 200, damping: 22 }

297

```

298

299

**Drag and Drop:**

300

```javascript

301

// While dragging

302

{ stiffness: 400, damping: 40 }

303

// Snap back

304

{ stiffness: 300, damping: 30 }

305

```

306

307

**Loading Animations:**

308

```javascript

309

{ stiffness: 150, damping: 15 } // Bouncy for attention

310

```

311

312

## Advanced Usage

313

314

### Conditional Spring Configs

315

316

```javascript

317

function AdaptiveSpring({ urgent, value }) {

318

const config = urgent

319

? { stiffness: 400, damping: 28 } // Fast for urgent changes

320

: { stiffness: 120, damping: 20 }; // Gentle for normal changes

321

322

return (

323

<Motion style={{ x: spring(value, config) }}>

324

{({ x }) => <div style={{ transform: `translateX(${x}px)` }} />}

325

</Motion>

326

);

327

}

328

```

329

330

### Dynamic Spring Parameters

331

332

```javascript

333

function DynamicSpring() {

334

const [distance, setDistance] = useState(0);

335

336

// Adjust stiffness based on distance

337

const stiffness = Math.max(120, Math.min(300, distance * 2));

338

339

return (

340

<Motion

341

style={{

342

x: spring(distance, { stiffness, damping: 20 })

343

}}

344

>

345

{({ x }) => (

346

<div

347

style={{ transform: `translateX(${x}px)` }}

348

onClick={(e) => setDistance(e.clientX)}

349

>

350

Click to move (stiffness: {stiffness})

351

</div>

352

)}

353

</Motion>

354

);

355

}

356

```

357

358

### Mixed Style Objects

359

360

```javascript

361

// Combining springs and static values

362

const mixedStyle = {

363

// Animated properties

364

x: spring(targetX, presets.stiff),

365

y: spring(targetY, presets.gentle),

366

scale: spring(targetScale),

367

368

// Static properties (no animation)

369

color: 'blue',

370

fontSize: 16,

371

fontWeight: 'bold'

372

};

373

```

374

375

## Performance Considerations

376

377

### Spring Calculation Cost

378

379

- More complex springs (lower precision) require more calculations

380

- High stiffness values may cause more frequent updates

381

- Consider using presets for optimal performance

382

383

### Animation Duration

384

385

Unlike CSS transitions, spring animations don't have fixed durations:

386

- Stiff springs with high damping finish quickly

387

- Soft springs with low damping take longer

388

- Very low precision values can cause unnecessarily long animations

389

390

### Memory Usage

391

392

- Each spring maintains internal state (position, velocity)

393

- Multiple springs on the same element share animation frames

394

- Springs automatically clean up when components unmount