Created
March 5, 2024 06:35
-
-
Save pSapien/6b58503e0d3caa822a17ef65175b0a10 to your computer and use it in GitHub Desktop.
Bezier Curve Animation in react native
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { useRef } from 'react'; | |
import { Animated, Button, StyleSheet, View, useWindowDimensions } from 'react-native'; | |
const half = (v: number) => Math.floor(v / 2); | |
export function ChatContainer() { | |
const { height, width } = useWindowDimensions(); | |
const animRef = useRef(new Animated.Value(0)); | |
const ballRef = useRef<View>(null); | |
const START = { | |
x: half(width), | |
y: 0, | |
}; | |
const ANCHOR = { | |
x: half(width), | |
y: -half(height), | |
}; | |
const END = { | |
x: 0, | |
y: -half(height), | |
}; | |
function resetAnimation() { | |
Animated.timing(animRef.current, { | |
toValue: 0, | |
duration: 3000, | |
useNativeDriver: false, | |
}).start(); | |
} | |
function startAnimation() { | |
Animated.timing(animRef.current, { | |
toValue: 1, | |
duration: 1000, | |
useNativeDriver: false, | |
}).start(); | |
} | |
return ( | |
<> | |
<View | |
style={{ | |
...StyleSheet.absoluteFillObject, | |
height, | |
width, | |
}} | |
> | |
<Animated.View | |
ref={ballRef} | |
style={{ | |
backgroundColor: 'red', | |
height: 30, | |
width: 30, | |
borderRadius: 15, | |
transform: [ | |
{ | |
translateX: animRef.current.interpolate({ | |
inputRange: [0, 1], | |
outputRange: [0, 1], | |
easing: v => calcBezier(v, START.x, ANCHOR.x, END.x), | |
}), | |
}, | |
{ | |
translateY: animRef.current.interpolate({ | |
inputRange: [0, 1], | |
outputRange: [0, 1], | |
easing: v => calcBezier(v, START.y, ANCHOR.y, END.y), | |
}), | |
}, | |
], | |
position: 'absolute', | |
bottom: 0, | |
left: 0, | |
}} | |
/> | |
</View> | |
<Button title="Animate" onPress={startAnimation} /> | |
<Button title="Reset" onPress={resetAnimation} /> | |
</> | |
); | |
} | |
function calcBezier(interploatedValue: number, start: number, anchor: number, end: number) { | |
return Math.round( | |
Math.pow(1 - interploatedValue, 2) * start + | |
2 * (1 - interploatedValue) * interploatedValue * anchor + | |
Math.pow(interploatedValue, 2) * end, | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment