import { useEffect , useMemo , useState } from 'react' ; import { Spring , SpringSystem } from 'rebound' ; const useSpring = ( targetValue = 0 , tension = 50 , friction = 3 ) => { const [ spring , setSpring ] = useState < Spring | null > ( null ) ; const [ value , setValue ] = useState < number > ( targetValue ) ; const listener = useMemo ( ( ) => ( { onSpringUpdate : ( currentSpring ) => { const newValue = currentSpring . getCurrentValue ( ) ; setValue ( newValue ) ; } , } ) , [ ] ) ; useEffect ( ( ) => { if ( ! spring ) { const newSpring = new SpringSystem ( ) . createSpring ( tension , friction ) ; newSpring . setCurrentValue ( targetValue ) ; setSpring ( newSpring ) ; newSpring . addListener ( listener ) ; } return ( ) => { if ( spring ) { spring . removeListener ( listener ) ; setSpring ( null ) ; } } ; } , [ tension , friction , spring ] ) ; useEffect ( ( ) => { if ( spring ) { spring . setEndValue ( targetValue ) ; } } , [ targetValue ] ) ; return value ; } ; export default useSpring ;