import { useChain, animated } from 'react-spring'
// Build a spring and catch its ref
const springRef = useSpringRef()
const props = useSpring({ ...values, ref: springRef })
// Build a transition and catch its ref
const transitionRef = useSpringRef()
const transitions = useTransition({ ...values, ref: transitionRef })
// First run the spring, when it concludes run the transition
useChain([springRef, transitionRef])
// Use the animated props like always
return (
<animated.div style={props}>
{transitions(styles => (
<animated.div style={styles} />
))}
</animated.div>
)
위와 같이 각 스프링에 ref를 걸어두고 Chain으로 엮으면 두 스프링이 동시에 실행된다. 만약 실행 시간에 텀을 주고 싶으면 다음과 같이 설정해줄 수 있다.
// The spring will start right away: 0.0 * 1000ms = 0ms
// The transition will start after: 0.5 * 1000ms (the timeFrame default) = 500ms
useChain([springRef, transitionRef], [0, 0.5] /*1000*/)
이렇게 설정하면 01000초 후에 첫번째 스프링이, 0.51000초 후에 두번째 스프링이 실행된다.
곱하는 값을 바꾸고 싶다면 뒤에 세번째 인자로 아래와 같이 넘겨주면 2000ms 단위로 설정이 된다.
useChain([springRef, transitionRef], [0, 0.5], 2000)
예제
//App.tsx
import React, { useState } from 'react'
import {
useTransition,
useSpring,
useChain,
config,
animated,
useSpringRef,
} from '@react-spring/web'
import data from './data'
import styles from './styles.module.css'
export default function App() {
const [open, set] = useState(false)
const springApi = useSpringRef()
const { size, ...rest } = useSpring({
ref: springApi,
config: config.stiff,
from: { size: '20%', background: 'hotpink' },
to: {
size: open ? '100%' : '20%',
background: open ? 'white' : 'hotpink',
},
})
const transApi = useSpringRef()
const transition = useTransition(open ? data : [], {
ref: transApi,
trail: 400 / data.length,
from: { opacity: 0, scale: 0 },
enter: { opacity: 1, scale: 1 },
leave: { opacity: 0, scale: 0 },
})
// This will orchestrate the two animations above, comment the last arg and it creates a sequence
useChain(open ? [springApi, transApi] : [transApi, springApi], [
0,
open ? 0.1 : 0.6,
])
return (
<div className={styles.wrapper}>
<animated.div
style={{ ...rest, width: size, height: size }}
className={styles.container}
onClick={() => set(open => !open)}>
{transition((style, item) => (
<animated.div
className={styles.item}
style={{ ...style, background: item.css }}
/>
))}
</animated.div>
</div>
)
}
chain... Blockchain..