wcandillon / react-native-redash

The React Native Reanimated and Gesture Handler Toolbelt
https://wcandillon.gitbook.io/redash/
MIT License
1.99k stars 117 forks source link

Add interpolate with Easing support #47

Open wcandillon opened 5 years ago

wcandillon commented 5 years ago

interpolate in Reanimated doesn't have support for the easing property: https://github.com/kmagiera/react-native-reanimated/blob/master/react-native-reanimated.d.ts#L41. We might be able to add that here. This property exists in the RN Animated API: https://github.com/facebook/react-native/blob/e2ce98b7c6f4f2fc7011c214f9edc1301ff30572/Libraries/Animated/src/Interpolation.js#L27

hssrrw commented 4 years ago

I use following code to achieve this:

interface InterpolationConfig {
  inputRange: ReadonlyArray<Animated.Adaptable<number>>
  outputRange: ReadonlyArray<Animated.Adaptable<number>>
  extrapolate?: Animated.Extrapolate
  extrapolateLeft?: Animated.Extrapolate
  extrapolateRight?: Animated.Extrapolate
  easing?: Animated.EasingFunction
}

const interpolateWithEasing = (
  value: Animated.Adaptable<number>,
  config: InterpolationConfig,
) => {
  const { easing, inputRange } = config
  if (easing) {
    const minValue = min(...inputRange)
    const maxValue = max(...inputRange)
    const length = sub(maxValue, minValue)
    const progress = divide(sub(value, minValue), length) // normalized to [0, 1] for easing functions
    const eased = add(multiply(easing(progress), length), minValue)

    return interpolate(eased, {
      ...config,
      extrapolate: Extrapolate.CLAMP,
    })
  } else {
    return interpolate(value, config)
  }
}