Created
June 24, 2019 03:19
-
-
Save SevenOutman/438aca96d4cc05f1a81ffe07a98ea99d to your computer and use it in GitHub Desktop.
React tween state hooks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Hook for use props as a tween state | |
// Usage. | |
// function Component({ propA, ...props }) { | |
// const tweenA = useAsTween(propA); | |
// // ... | |
// } | |
// | |
import { useEffect } from 'react'; | |
import useTweenState from './useTweenState'; | |
export default function useAsTween(state, ...args){ | |
const [tweenState, setTweenState] = useTweenState(state, ...args); | |
useEffect(() => { | |
setTweenState(state); | |
}, [state]); | |
return tweenState; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Hook for tween state | |
// Usage. | |
// const [tweenState, setTweenState] = useTweenState(0, 700); | |
// setTweenState(1000); // tweenState gradually changes to 1000 in 700ms | |
// | |
import { useCallback, useEffect, useRef, useState } from 'react'; | |
export default function useTweenState(initialValue, duration = 1200, easingFunction = easeInOutQuad) { | |
const [state, setState] = useState(initialValue); | |
const [runningTween, setRunningTween] = useState(false); | |
const now = Date.now(); | |
const startValue = useRef(state); | |
const targetValue = useRef(state); | |
const startTime = useRef(now); | |
const setTargetValue = useCallback((target) => { | |
if (target !== state) { | |
startValue.current = state; | |
targetValue.current = target; | |
startTime.current = now; | |
setRunningTween(true); | |
} else { | |
setRunningTween(false); | |
} | |
}, []); | |
useEffect(() => { | |
if (runningTween) { | |
const dt = now - startTime.current; | |
if (dt >= duration) { | |
setState(targetValue.current); | |
setRunningTween(false); | |
} else { | |
setState(easingFunction(dt / duration) * (targetValue.current - startValue.current) + startValue.current); | |
} | |
} | |
}, [runningTween, now]); | |
return [state, setTargetValue]; | |
} | |
// @see https://gist.github.com/gre/1650294 | |
export function linear(t) { | |
return t; | |
} | |
export function easeInQuad(t) { | |
return t * t; | |
} | |
export function easeOutQuad(t) { | |
return t * (2 - t); | |
} | |
export function easeInOutQuad(t) { | |
return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t; | |
} | |
export function easeInCubic(t) { | |
return t * t * t; | |
} | |
export function easeOutCubic(t) { | |
return (--t) * t * t + 1; | |
} | |
export function easeInOutCubic(t) { | |
return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1; | |
} | |
export function easeInQuart(t) { | |
return t * t * t * t; | |
} | |
export function easeOutQuart(t) { | |
return 1 - (--t) * t * t * t; | |
} | |
export function easeInOutQuart(t) { | |
return t < .5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t; | |
} | |
export function easeInQuint(t) { | |
return t * t * t * t * t; | |
} | |
export function easeOutQuint(t) { | |
return 1 + (--t) * t * t * t * t; | |
} | |
export function easeInOutQuint(t) { | |
return t < .5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment