Skip to content

Commit eb69b7e

Browse files
committed
feat: added inertia example
1 parent 45edcef commit eb69b7e

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

components/examples-hooks.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ return <animated.div style={{ transform }} children="Slide">`,
7474
link: 'https://codesandbox.io/embed/r5qmj8m6lq',
7575
tags: ['useSprings'],
7676
},
77+
{
78+
name: 'hooks/inertia',
79+
title: 'Inertia',
80+
tags: ['useSprings'],
81+
},
7782
{
7883
name: 'hooks/clamp-bounce',
7984
title: 'Clamp bounce',

demos/hooks/inertia/index.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React from 'react'
2+
import { useSpring, animated } from 'react-spring'
3+
import { useDrag } from 'react-use-gesture'
4+
import './styles.css'
5+
6+
const [min, max] = [-250, 250]
7+
8+
export default function Inertia() {
9+
const [{ y }, set] = useSpring(() => ({ y: 0 }))
10+
11+
const bind = useDrag(
12+
({ down, movement: [, dy], vxvy: [, vy], memo = y.getValue() }) => {
13+
if (down) set({ y: dy + memo, onFrame: () => {}, immediate: true })
14+
else inertia(dy + memo + 1, vy)
15+
return memo
16+
}
17+
)
18+
19+
const springBounce = React.useCallback(
20+
velocity => {
21+
set({
22+
y: velocity > 0 ? max : min,
23+
onFrame: () => {}, // <-- this is annoying :)
24+
config: { velocity: velocity * 3 },
25+
})
26+
},
27+
[set]
28+
)
29+
30+
const inertia = React.useCallback(
31+
(position, velocity) => {
32+
set({
33+
to: async (next, stop) => {
34+
await next({
35+
y: position,
36+
onFrame: async v => {
37+
const vel = y.lastVelocity
38+
39+
if ((v.y > max && vel > 0) || (v.y < min && vel < 0)) {
40+
stop()
41+
springBounce(vel)
42+
}
43+
},
44+
config: { decay: true, velocity },
45+
})
46+
},
47+
})
48+
},
49+
[y, set, springBounce]
50+
)
51+
// Now we're just mapping the animated values to our view, that's it. Btw, this component only renders once. :-)
52+
return (
53+
<div className="inertia">
54+
<animated.div {...bind()} style={{ y }} />
55+
</div>
56+
)
57+
}

demos/hooks/inertia/styles.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.inertia {
2+
display: flex;
3+
align-items: center;
4+
justify-content: center;
5+
background: #ecede7;
6+
height: 100%;
7+
}
8+
9+
.inertia > div {
10+
width: 80px;
11+
height: 80px;
12+
background: hotpink;
13+
border-radius: 16px;
14+
}

0 commit comments

Comments
 (0)