├── README.md ├── SUMMARY.md ├── animations.md ├── colors.md ├── coordinates.md ├── math.md ├── paths.md ├── physics.md ├── strings.md ├── transitions.md └── vectors.md /README.md: -------------------------------------------------------------------------------- 1 | # Redash 2 | 3 | The React Native Reanimated and Gesture Handler Toolbelt. As seen on the [“Can it be done in React Native?”](http://youtube.com/user/wcandill) YouTube series. 4 | 5 | ## Installation 6 | 7 | ```bash 8 | yarn add react-native-redash 9 | ``` 10 | 11 | ## ⚠️ v1 Users ⚠️ 12 | 13 | v1 documentation: [https://wcandillon.github.io/react-native-redash-v1-docs/](https://wcandillon.github.io/react-native-redash-v1-docs/) 14 | 15 | To access functions that work with Reanimated v1 nodes, use the following import: 16 | 17 | ```typescript 18 | import {usePanGestureHandler} from "react-native-redash/lib/module/v1"; 19 | ``` 20 | 21 | To add TypeScript support for the v1 functions, add the following type to your `tsconfig`: 22 | 23 | ```javascript 24 | "include": ["node_modules/react-native-redash/lib/typescript/v1/index.d.ts"] 25 | ``` 26 | 27 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [Redash](README.md) 4 | * [Animations](animations.md) 5 | * [Coordinates](coordinates.md) 6 | * [Math](math.md) 7 | * [Strings](strings.md) 8 | * [Transitions](transitions.md) 9 | * [Vectors](vectors.md) 10 | * [Paths](paths.md) 11 | * [Physics](physics.md) 12 | * [Colors](colors.md) 13 | 14 | -------------------------------------------------------------------------------- /animations.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Animations in Reanimated v2 have powerful composability built-in. The 4 | following are functions TypeScript types that will help you to build custom 5 | animations. 6 | --- 7 | 8 | # Animations 9 | 10 | ## Higher-order Animations 11 | 12 | Higher-order animations are a powerful concept in Reanimated v2. Here is an example. 13 | 14 | ### `defineAnimation()` 15 | 16 | This utility function enables you to declare custom animations that can be invoked on both the JS and UI thread. 17 | 18 | ```typescript 19 | const withCustomAnimation = () => { 20 | "worklet"; 21 | return defineAnimation(() => { 22 | "worklet"; 23 | // ...animation code 24 | return { 25 | animation, 26 | start 27 | } 28 | }); 29 | } 30 | ``` 31 | 32 | ### `animationParameter(animation)` 33 | 34 | Access animations passed as parameters safely on both the UI and JS thread with the proper static types. Animations can receive other animations as parameter. 35 | 36 | ```typescript 37 | export const withPause = ( 38 | animationParam: AnimationParameter, 39 | paused: Animated.SharedValue 40 | ) => { 41 | "worklet"; 42 | return defineAnimation(() => { 43 | "worklet"; 44 | // Access the animation passed as parameter safely at runtime 45 | // with the proper TypeScript types 46 | const nextAnimation = animationParameter(animationParam); 47 | // ...animation code 48 | ``` 49 | 50 | ### `withPause()` 51 | 52 | Make an animation pausable. The state of the animation \(paused or not\) is controlled by a boolean shared value. 53 | 54 | ```typescript 55 | const progress = useSharedValue(0); 56 | const paused = useSharedValue(false); 57 | useEffect(() => { 58 | progress.value = withPause(withLoop(withTiming(1)), paused); 59 | }, []); 60 | ``` 61 | 62 | ### `withBouncing()` 63 | 64 | Add a bouncing behavior to a physics-based animation. An animation is defined as being physics-based if it contains a velocity in its state. 65 | 66 | ```typescript 67 | // will bounce if the animations hits the position 0 or 100 68 | withBouncing(withDecay({ velocity }), 0, 100) 69 | ``` 70 | 71 | -------------------------------------------------------------------------------- /colors.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Color interpolations and more 3 | --- 4 | 5 | # Colors 6 | 7 | ## `mixColor()` 8 | 9 | Identical to `interpolateColor()` but with an animation value that goes from 0 to 1. 10 | 11 | ```typescript 12 | const backgroundColor = useDerivedValue(() => 13 | mixColor(progress.value, "#ff3884", "#38ffb3") 14 | ); 15 | ``` 16 | 17 | ## `colorForBackground()` 18 | 19 | Returns black or white depending on the value of the background color. 20 | -------------------------------------------------------------------------------- /coordinates.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | When doing animation you often need to use a polar or coordinate system. 4 | However, React Native uses a canvas coordinate system. These functions will 5 | help you to seamlessly go back and forth. 6 | --- 7 | 8 | # Coordinates 9 | 10 | ## `canvas2Cartesian()` 11 | 12 | ```typescript 13 | canvas2Cartesian: ({ x, y }: Vector, center: Vector) => Vector; 14 | ``` 15 | 16 | ## `cartesian2Canvas()` 17 | 18 | ```typescript 19 | export declare const cartesian2Canvas: ({ x, y }: Vector, center: Vector) => Vector; 20 | ``` 21 | 22 | ## `cartesian2Polar()` 23 | 24 | ```typescript 25 | export declare const cartesian2Polar: ({ x, y }: Vector, center: Vector) => { radius: number, theta: number }; 26 | ``` 27 | 28 | ## `polar2Cartesian()` 29 | 30 | ```typescript 31 | export declare const polar2Cartesian: ({ theta, radius }: PolarPoint) => Vector; 32 | ``` 33 | 34 | ## `polar2Canvas()` 35 | 36 | ```typescript 37 | export declare const polar2Canvas: ({ theta, radius }: PolarPoint, center: Vector) => Vector; 38 | ``` 39 | 40 | ## `canvas2Polar()` 41 | 42 | ```typescript 43 | export declare const canvas2Polar: ({ x, y }: Vector, center: Vector) => { 44 | theta: number; 45 | radius: number; 46 | }; 47 | ``` 48 | 49 | -------------------------------------------------------------------------------- /math.md: -------------------------------------------------------------------------------- 1 | # Math 2 | 3 | ## `mix()` 4 | 5 | ```typescript 6 | const mix = (value: number, x: number, y: number) => number 7 | ``` 8 | 9 | mix performs a linear interpolation between x and y using a to weight between them. The return value is computed as `x * (1 - value) + y * value`. 10 | 11 | ## `bin()` 12 | 13 | ```typescript 14 | const bin: (value: boolean) => 0 | 1 15 | ``` 16 | 17 | Convert a boolean value into a number. This can be useful in reanimated since 0 and 1 are used for conditional statements. 18 | 19 | ## `toRad()` 20 | 21 | ```typescript 22 | const toRad = (deg: number) => number; 23 | ``` 24 | 25 | Transforms an angle from degrees to radians. 26 | 27 | ## `toDeg()` 28 | 29 | ```typescript 30 | const toDeg = (rad: number) => number; 31 | ``` 32 | 33 | Transforms an angle from radians to degrees. 34 | 35 | ## `clamp()` 36 | 37 | ```typescript 38 | const clamp = (value: number, lowerBound: number, upperBound: number) => number; 39 | ``` 40 | 41 | Clamps a node with a lower and upper bound. 42 | 43 | ```typescript 44 | clamp(-1, 0, 100); // 0 45 | clamp(1, 0, 100); // 1 46 | clamp(101, 0, 100); // 100 47 | ``` 48 | 49 | ## `avg()` 50 | 51 | ```typescript 52 | const avg = (values: number[]) => number; 53 | ``` 54 | 55 | Returns the average value of an array 56 | 57 | ## `between()` 58 | 59 | ```typescript 60 | const between = (value: number, lowerBound: number, upperBound: number, inclusive?: boolean) => boolean; 61 | ``` 62 | 63 | Returns true if node is within lowerBound and upperBound. 64 | 65 | ## `round()` 66 | 67 | ```typescript 68 | const round = (value: Animated.Adaptable, precision: Animated.Adaptable = 0) => Animated.Node; 69 | ``` 70 | 71 | Computes animation node rounded to precision. 72 | 73 | ## `cubicBezier()` 74 | 75 | ```typescript 76 | const cubicBezier = (t: number, p0: number, p1: number, p2: number, p3: number) => number; 77 | ``` 78 | 79 | Returns the coordinate of a cubic bezier curve. t is the length of the curve from 0 to 1. `cubicBezier(0, p0, p1, p2, p3)` equals `p0` and `cubicBezier(1, p0, p1, p2, p3)` equals `p3`. `p0` and `p3` are respectively the starting and ending point of the curve. `p1` and `p2` are the control points. 80 | 81 | ## `cubicBezierYForX()` 82 | 83 | Given a cubic Bèzier curve, return the `y` value for `x`. 84 | 85 | ```typescript 86 | const x = 116; 87 | const from = vec.create(59, 218); 88 | const c1 = vec.create(131, 39); 89 | const c2 = vec.create(204, 223); 90 | const to = vec.create(227, 89); 91 | // y= 139 92 | const y = cubicBezierYForX(x, from, c1, c2, to))); 93 | ``` 94 | 95 | -------------------------------------------------------------------------------- /paths.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: 'Functions to build, interpolate, and SVG paths made of Bèzier curves' 3 | --- 4 | 5 | # Paths 6 | 7 | ## Examples 8 | 9 | ```typescript 10 | import {move, curve, serialize} from "react-native-redash"; 11 | 12 | const Example = () => { 13 | const path = createPath({ x: 0, y: 0}); 14 | addCurve(path, { 15 | c1: { 16 | x: 1, 17 | y: 0 18 | }, 19 | c2: { 20 | x: 1, 21 | y: 1 22 | }, 23 | to: { 24 | x: 1, 25 | y: 0.5 26 | } 27 | }); 28 | close(path); 29 | const d = serialize(path); 30 | return ( 31 | 32 | 33 | 34 | ); 35 | } 36 | ``` 37 | 38 | ## `createPath(path, {x, y})` 39 | 40 | Create a new path 41 | 42 | ## `addCurve(path, {c1: {x, y}, c2: {x, y}, to: {x, y}})` 43 | 44 | Add a Bèzier curve command to a path. 45 | 46 | ## `close(path)` 47 | 48 | Add a close command to a path. 49 | 50 | ## `parse(path)` 51 | 52 | **⚠️ this function cannot run on the UI thread. It must be executed on the JS thread** 53 | 54 | Parse an SVG path into a sequence of Bèzier curves. The SVG is normalized to have absolute values and to be approximated to a sequence of Bèzier curves. 55 | 56 | ## `serialize(path)` 57 | 58 | Serialize a path into an SVG path string. 59 | 60 | ## `interpolatePath()` 61 | 62 | Interpolate between paths. 63 | 64 | ```jsx 65 | const progress = useSharedValue(0); 66 | // ⚠️ parse() cannot be executed on the UI thread 67 | const p1 = 68 | parse("M150,0 C150,0 0,75 200,75 C75,200 200,225 200,225 C225,200 200,150 0,150 "); 69 | const p2 = parse( 70 | "M150,0 C150,0 0,75 200,75 C75,200 200,225 200,225 C225,200 200,150 0,150 "); 71 | const animatedProps = useAnimatedProps(() => { 72 | const d = interpolatePath(progress.value, [0, 1], [p1, p2]); 73 | return { 74 | d 75 | }; 76 | }); 77 | return ; 78 | ``` 79 | 80 | ## `mixPath()` 81 | 82 | Interpolate two paths with an animation value that goes from 0 to 1. 83 | 84 | ```jsx 85 | const progress = useSharedValue(0); 86 | // ⚠️ parse() cannot be executed on the UI thread 87 | const p1 = 88 | parse("M150,0 C150,0 0,75 200,75 C75,200 200,225 200,225 C225,200 200,150 0,150 "); 89 | const p2 = parse( 90 | "M150,0 C150,0 0,75 200,75 C75,200 200,225 200,225 C225,200 200,150 0,150 "); 91 | const animatedProps = useAnimatedProps(() => { 92 | const d = mixPath(progress.value, p1, p2); 93 | return { 94 | d 95 | }; 96 | }); 97 | return ; 98 | ``` 99 | 100 | ## `getYForX` 101 | 102 | Return the `y` value of a path given its `x` coordinate 103 | 104 | ```jsx 105 | const p1 = parse( 106 | "M150,0 C150,0 0,75 200,75 C75,200 200,225 200,225 C225,200 200,150 0,150" 107 | ); 108 | // 75 109 | getYForX(p1, 200)) 110 | // ~151 111 | getYForX(p1, 50) 112 | ``` 113 | 114 | -------------------------------------------------------------------------------- /physics.md: -------------------------------------------------------------------------------- 1 | # Physics 2 | 3 | ## `snapPoint()` 4 | 5 | ```typescript 6 | const snapPoint = (value: number, velocity: number, points: ReadonlyArray): number; 7 | ``` 8 | 9 | Select a point where the animation should snap to given the value of the gesture and it's velocity. 10 | 11 | ```typescript 12 | withSpring(snapPoint(translationX, velocityX, [0, width])) 13 | ``` 14 | 15 | -------------------------------------------------------------------------------- /strings.md: -------------------------------------------------------------------------------- 1 | # Strings 2 | 3 | ## `` 4 | 5 | This component is like `` but accepts a string animation node as property. Behind the scene, `` is using `` with some default styling. Therefore there might be some slight inconsistencies with ``. 6 | 7 | ```typescript 8 | () => { 9 | const price = useSharedValue(42); 10 | const formattedPrice = useDerivedValue(() => (`${price.value}`.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' }))); 11 | return ( 12 | 16 | ) 17 | } 18 | ``` 19 | 20 | -------------------------------------------------------------------------------- /transitions.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Transitions can attach an animation value to a change of React state. 3 | --- 4 | 5 | # Transitions 6 | 7 | | State \(JS Thread\) | Value \(UI Thread\) | | 8 | | :--- | :---: | ---: | 9 | | Timing | useTimingTransition\(\) | withTimingTransition\(\) | 10 | | Spring | useSpringTransition\(\) | withSpringTransition\(\) | 11 | 12 | ```typescript 13 | import { useTiming } from "react-native-redash"; 14 | 15 | const Toggle = () => { 16 | const [open, setOpen] = useState(false); 17 | const transition = useTiming(open, { duration: 400 }); 18 | } 19 | ``` 20 | 21 | ## `useTiming()` 22 | 23 | ```typescript 24 | const useTiming: (state: number | boolean, config?: Animated.WithTimingConfig) => number; 25 | ``` 26 | 27 | ## `useSpring()` 28 | 29 | ```typescript 30 | const useSpring: (state: number | boolean, config?: Animated.WithSpringConfig) => number; 31 | ``` 32 | 33 | -------------------------------------------------------------------------------- /vectors.md: -------------------------------------------------------------------------------- 1 | # Vectors 2 | 3 | ## `Vector` 4 | 5 | Type representing a vector. it is defined as 6 | 7 | ```typescript 8 | export interface Vector { 9 | x: T; 10 | y: T; 11 | } 12 | ``` 13 | 14 | ## `useVector()` 15 | 16 | Returns a vector of shared values. 17 | 18 | --------------------------------------------------------------------------------