mediamonks / react-kit

A collection of React hooks, components and utilities we use at Media.Monks
https://mediamonks.github.io/react-kit/
MIT License
10 stars 2 forks source link

Create useLerp hook #241

Open VictorGa opened 1 year ago

VictorGa commented 1 year ago

Lerping hook for simple transitions. Properties would be initial number, final number, duration, ease method.

leroykorterink commented 1 year ago

@VictorGa can you provide an example of an implementation? A simple lerp can be implemented in a function, don't really see the benefit to have a hook for it.

I agree that having these functions ready to use is useful but wouldn't recommend implementing it via a react hook.

ReneDrie commented 1 year ago

The lerp as a function is already available (gsap.utils.interpolate). But I assume this does the animationFrame loop, and keeps updating the current value by interpolating to the target value.

I currently use something like this:

import { noop } from 'lodash-es';
import { useCallback, useRef } from 'react';
import { useRafLoop } from 'react-use';

export type LerpPoint = { x: number; y: number };
export type LerpValue = number | LerpPoint;

export function useLerp(
  value: LerpValue,
  target: LerpValue,
  interpolateValue = 0.1,
  callback: (value: LerpValue) => void = noop,
): (target: LerpValue) => void {
  const currentValue = useRef<LerpValue>(value);
  const targetValue = useRef<LerpValue>(target);
  const interpolate = useRef<number>(interpolateValue);

  useRafLoop(() => {
    if (typeof targetValue.current === 'number' || typeof currentValue.current === 'number') {
      currentValue.current = gsap.utils.interpolate(
        currentValue.current,
        targetValue.current,
        interpolate.current,
      );
    } else {
      currentValue.current.x = gsap.utils.interpolate(
        currentValue.current.x,
        targetValue.current.x,
        interpolate.current,
      );
      currentValue.current.y = gsap.utils.interpolate(
        currentValue.current.y,
        targetValue.current.y,
        interpolate.current,
      );
    }

    callback(currentValue.current);
  });

  return useCallback((updatedTarget: LerpValue) => {
    targetValue.current = updatedTarget;
  }, []);
}
VictorGa commented 1 year ago

Yes, exactly that. I didn't mean the formula in a hook. Mostly a way to interpolate the values in an easier way using a hook for it, regardless if we use interpolate from gsap or a formula, could be handy. We have an example from @evertmonk. I'll create a PR for it soon.