React Native Redash

18.1.5 · active · verified Sun Apr 19

Redash is a utility library specifically designed to augment React Native Reanimated and React Native Gesture Handler, providing a collection of powerful helper functions and components for building complex, performant animations and interactions in React Native applications. It serves as a comprehensive toolbelt, simplifying common animation patterns that are frequently showcased in the popular 'Can it be done in React Native?' YouTube series. The current stable version is 18.1.5, with a consistent release cadence focusing on bug fixes and compatibility updates for new Reanimated versions. It maintains strong ties to the Reanimated ecosystem, abstracting away complex mathematical operations and animation logic into more accessible APIs, differentiating itself by its curated set of practical utilities for advanced animation scenarios.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates a draggable animated square using Redash's `mix` and `useVector` helpers in conjunction with React Native Reanimated and Gesture Handler for interactive scaling, rounding, and movement.

import React from 'react';
import { StyleSheet, View } from 'react-native';
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withSpring,
} from 'react-native-reanimated';
import { mix, useVector } from 'react-native-redash';
import { GestureHandlerRootView, Gesture } from 'react-native-gesture-handler';

export default function App() {
  const isPressed = useSharedValue(false);
  const offset = useVector(0, 0); // Redash helper for 2D vectors

  const animatedStyles = useAnimatedStyle(() => {
    const scale = mix(isPressed.value, 1, 1.2); // Redash mix helper
    const borderRadius = mix(isPressed.value, 0, 15);
    return {
      transform: [
        { translateX: offset.x.value },
        { translateY: offset.y.value },
        { scale },
      ],
      borderRadius,
      backgroundColor: isPressed.value ? 'dodgerblue' : 'hotpink',
    };
  });

  const panGesture = Gesture.Pan()
    .onBegin(() => {
      isPressed.value = true;
    })
    .onChange((event) => {
      offset.x.value = event.translationX;
      offset.y.value = event.translationY;
    })
    .onEnd(() => {
      isPressed.value = false;
      offset.x.value = withSpring(0); // Animate back to origin
      offset.y.value = withSpring(0); // Animate back to origin
    });

  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <View style={styles.container}>
        <GestureDetector gesture={panGesture}>
          <Animated.View style={[styles.box, animatedStyles]} />
        </GestureDetector>
      </View>
    </GestureHandlerRootView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  box: {
    width: 100,
    height: 100,
  },
});

view raw JSON →