Skip to content

Instantly share code, notes, and snippets.

@mattThousand
Created January 11, 2021 03:32
Show Gist options
  • Save mattThousand/d60a0463513e1cbed15bfcf83e873c4c to your computer and use it in GitHub Desktop.
Save mattThousand/d60a0463513e1cbed15bfcf83e873c4c to your computer and use it in GitHub Desktop.
import { BlurView } from 'expo-blur';
import React, { FunctionComponent, useEffect } from 'react';
import { View, StyleSheet, Dimensions, Animated, Pressable, Easing, Text } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
const { width, height } = Dimensions.get('screen');
const BreathAnimation: FunctionComponent = () => {
const animatedScale = React.useRef(new Animated.Value(1)).current;
const animatedTextScale = React.useRef(new Animated.Value(1)).current;
const timerAnimation = React.useRef(new Animated.Value(0)).current;
const [visibleText, setVisibleText] = React.useState<string>('10');
const handlePress = () => {
timerAnimation.setValue(10);
Animated.parallel([
Animated.sequence([
Animated.timing(animatedScale, {
toValue: 1.4,
duration: 4000,
useNativeDriver: true,
}),
Animated.delay(2000),
Animated.timing(animatedScale, {
toValue: 1,
duration: 4000,
useNativeDriver: true,
}),
]),
Animated.timing(timerAnimation, {
toValue: 0,
duration: 10000,
easing: Easing.linear,
useNativeDriver: true,
}),
]).start();
};
useEffect(() => {
timerAnimation.addListener((value) => {
const displayValue = Math.ceil(value.value);
setVisibleText(displayValue.toString());
if (value.value % 1 < 0.05) {
animatedTextScale.setValue(0.8);
Animated.spring(animatedTextScale, {
toValue: 1,
useNativeDriver: true,
}).start();
}
});
return () => {
timerAnimation.removeAllListeners();
};
}, []);
return (
<View style={style.container}>
<Animated.View style={[style.circle, { transform: [{ scale: animatedScale }] }]}>
<LinearGradient colors={['yellow', 'red', 'purple']} style={style.gradient} />
</Animated.View>
<BlurView tint={'dark'} intensity={80} style={style.blurview} />
<Animated.Text style={[style.text, { transform: [{ scale: animatedTextScale }] }]}>{visibleText}</Animated.Text>
<Pressable onPress={handlePress} style={[style.circle, style.pressable]} />
</View>
);
};
const style = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
blurview: {
width,
height: height / 2,
position: 'absolute',
bottom: 0,
},
circle: {
width: 250,
height: 250,
borderRadius: 150,
overflow: 'hidden',
},
gradient: {
width: 250,
height: 250,
},
pressable: {
position: 'absolute',
},
text: {
position: 'absolute',
bottom: 50,
left: 50,
color: '#fff',
fontSize: 70,
},
});
export default BreathAnimation;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment