Skip to content

Instantly share code, notes, and snippets.

@SevenOutman
Created June 24, 2019 03:19
Show Gist options
  • Save SevenOutman/438aca96d4cc05f1a81ffe07a98ea99d to your computer and use it in GitHub Desktop.
Save SevenOutman/438aca96d4cc05f1a81ffe07a98ea99d to your computer and use it in GitHub Desktop.
React tween state hooks
// 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;
}
// 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