or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

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

motion.mddocs/

0

# Motion Component

1

2

The Motion component provides single element animations using spring physics. It's the simplest and most commonly used component in React Motion, ideal for basic state transitions, hover effects, and straightforward UI animations.

3

4

## Capabilities

5

6

### Motion Component

7

8

Creates a single animated element that transitions between style states using spring physics.

9

10

```javascript { .api }

11

/**

12

* Single element animation component using spring physics

13

* Animates from defaultStyle (or current style) to target style

14

*/

15

class Motion extends React.Component {

16

static propTypes = {

17

/** Initial style values (optional, defaults to target style values) */

18

defaultStyle: PropTypes.objectOf(PropTypes.number),

19

/** Target style with spring configurations (required) */

20

style: PropTypes.objectOf(PropTypes.oneOfType([

21

PropTypes.number,

22

PropTypes.object,

23

])).isRequired,

24

/** Render function receiving interpolated style values (required) */

25

children: PropTypes.func.isRequired,

26

/** Callback fired when animation completes (optional) */

27

onRest: PropTypes.func,

28

};

29

}

30

```

31

32

**Usage Examples:**

33

34

```javascript

35

import React, { useState } from 'react';

36

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

37

38

// Basic animation

39

function BasicMotion() {

40

const [open, setOpen] = useState(false);

41

42

return (

43

<Motion

44

defaultStyle={{width: 0, opacity: 0}}

45

style={{

46

width: spring(open ? 200 : 0),

47

opacity: spring(open ? 1 : 0)

48

}}

49

>

50

{({width, opacity}) => (

51

<div

52

style={{

53

width: `${width}px`,

54

opacity,

55

background: 'blue',

56

overflow: 'hidden'

57

}}

58

>

59

<button onClick={() => setOpen(!open)}>

60

Toggle

61

</button>

62

</div>

63

)}

64

</Motion>

65

);

66

}

67

68

// With custom spring config

69

function CustomSpringMotion() {

70

const [x, setX] = useState(0);

71

72

return (

73

<Motion

74

style={{

75

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

76

}}

77

>

78

{({x}) => (

79

<div

80

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

81

onClick={() => setX(x === 0 ? 100 : 0)}

82

>

83

Click to move

84

</div>

85

)}

86

</Motion>

87

);

88

}

89

90

// With onRest callback

91

function MotionWithCallback() {

92

const [scale, setScale] = useState(1);

93

const [animating, setAnimating] = useState(false);

94

95

return (

96

<Motion

97

style={{scale: spring(scale)}}

98

onRest={() => {

99

setAnimating(false);

100

console.log('Animation completed!');

101

}}

102

>

103

{({scale}) => (

104

<div

105

style={{

106

transform: `scale(${scale})`,

107

transition: animating ? 'none' : undefined

108

}}

109

onClick={() => {

110

setAnimating(true);

111

setScale(scale === 1 ? 1.5 : 1);

112

}}

113

>

114

{animating ? 'Animating...' : 'Click to scale'}

115

</div>

116

)}

117

</Motion>

118

);

119

}

120

```

121

122

### defaultStyle Property

123

124

Optional initial style values. If not provided, the component will extract initial values from the target style.

125

126

```javascript { .api }

127

/**

128

* Initial style values for the animation

129

* If omitted, values are extracted from target style

130

*/

131

defaultStyle?: PlainStyle;

132

```

133

134

### style Property

135

136

Target style object containing numeric values or spring configurations. This is where you define what the animation should transition to.

137

138

```javascript { .api }

139

/**

140

* Target style with spring configurations

141

* Can mix plain numbers with spring() calls

142

*/

143

style: Style;

144

```

145

146

### children Property

147

148

Render function that receives the current interpolated style values and returns a React element.

149

150

```javascript { .api }

151

/**

152

* Render function receiving interpolated style values

153

* Called on every animation frame with current values

154

*/

155

children: (interpolatedStyle: PlainStyle) => ReactElement;

156

```

157

158

### onRest Property

159

160

Optional callback function fired when the animation reaches its target and stops moving.

161

162

```javascript { .api }

163

/**

164

* Callback fired when animation completes

165

* Useful for chaining animations or triggering side effects

166

*/

167

onRest?: () => void;

168

```

169

170

## Animation Behavior

171

172

### Spring Physics

173

174

The Motion component uses a spring-damper physics system:

175

- **No duration**: Animations run until they naturally settle

176

- **Interruption-safe**: Can be redirected mid-animation without jarring transitions

177

- **Natural feel**: Springs feel more organic than easing curves

178

179

### Performance

180

181

- Uses `requestAnimationFrame` for smooth 60fps animations

182

- Automatically stops when values reach target within precision threshold

183

- Handles browser tab switching gracefully by restarting timing

184

- Batches style updates through React's reconciliation

185

186

### State Management

187

188

Internally tracks:

189

- `currentStyle`: Current interpolated values

190

- `currentVelocity`: Current velocity for each animated property

191

- `lastIdealStyle`: Target values from previous frame

192

- `lastIdealVelocity`: Target velocity from previous frame

193

194

This state enables smooth interruptions when style prop changes during animation.

195

196

## Common Patterns

197

198

### Conditional Animations

199

200

```javascript

201

<Motion

202

style={{

203

x: spring(condition ? 100 : 0),

204

opacity: spring(visible ? 1 : 0)

205

}}

206

>

207

{({x, opacity}) => (

208

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

209

Content

210

</div>

211

)}

212

</Motion>

213

```

214

215

### Multiple Properties

216

217

```javascript

218

<Motion

219

style={{

220

width: spring(expanded ? 200 : 50),

221

height: spring(expanded ? 200 : 50),

222

rotate: spring(expanded ? 45 : 0),

223

borderRadius: spring(expanded ? 20 : 5)

224

}}

225

>

226

{({width, height, rotate, borderRadius}) => (

227

<div

228

style={{

229

width: `${width}px`,

230

height: `${height}px`,

231

transform: `rotate(${rotate}deg)`,

232

borderRadius: `${borderRadius}px`

233

}}

234

>

235

Morphing box

236

</div>

237

)}

238

</Motion>

239

```

240

241

### Chained Animations

242

243

```javascript

244

function ChainedAnimation() {

245

const [stage, setStage] = useState(0);

246

247

return (

248

<Motion

249

style={{

250

x: spring(stage === 0 ? 0 : stage === 1 ? 100 : 200),

251

y: spring(stage < 2 ? 0 : 100)

252

}}

253

onRest={() => {

254

if (stage < 2) {

255

setStage(stage + 1);

256

}

257

}}

258

>

259

{({x, y}) => (

260

<div style={{transform: `translate(${x}px, ${y}px)`}}>

261

Stage {stage}

262

</div>

263

)}

264

</Motion>

265

);

266

}

267

```