App.js
import React from "react";
import { View, SafeAreaView, StyleSheet, Text } from "react-native";
import { ScaleAnimation } from './components/ScaleAnimation';
import { EntryAnimation } from './components/EntryAnimation';
function Button({backgroundColor = 'tomato', children}) {
return (
<View
style={[
styles.button,
{
height: 80,
width: 250,
backgroundColor,
},
]}>
<Text style={{fontSize: 30}}>{children}</Text>
</View>
);
}
function Spacer() {
return <View style={{height: 30, width: 50}} />;
}
function App() {
return (
<SafeAreaView style={styles.mainContainer}>
<Spacer />
<ScaleAnimation onPress={() => {}} disabled={false} scaleTo={0.97}>
<Button backgroundColor="red">YO</Button>
</ScaleAnimation>
<Spacer />
<EntryAnimation index={1}>
<ScaleAnimation onPress={() => {}} disabled={false} scaleTo={0.97}>
<Button backgroundColor="#7ab2c9">YO 1</Button>
</ScaleAnimation>
</EntryAnimation>
<Spacer />
<EntryAnimation index={2}>
<ScaleAnimation onPress={() => {}} disabled={false} scaleTo={0.97}>
<Button backgroundColor="#cb6442">YO 2</Button>
</ScaleAnimation>
</EntryAnimation>
<Spacer />
<EntryAnimation index={3}>
<ScaleAnimation onPress={() => {}} disabled={false} scaleTo={0.97}>
<Button backgroundColor="#e5cabb">YO 3</Button>
</ScaleAnimation>
</EntryAnimation>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
mainContainer: {
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
},
button: {
borderRadius: 25,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 7,
},
shadowOpacity: 0.43,
shadowRadius: 9.51,
elevation: 15,
},
});
export default App
ScaleAnimation.js
import React from 'react';
import {TouchableWithoutFeedback} from 'react-native';
import Animated, {
useAnimatedStyle,
useSharedValue,
useDerivedValue,
withTiming,
Easing,
interpolate,
Extrapolate,
} from 'react-native-reanimated';
const TimeConfigurations = {duration: 50, easing: Easing.linear};
export const ScaleAnimation = ({onPress, children, scaleTo, disabled}) => {
const pressed = useSharedValue(false);
const progress = useDerivedValue(() => {
return pressed.value
? withTiming(1, TimeConfigurations)
: withTiming(0, TimeConfigurations);
});
const animatedStyle = useAnimatedStyle(() => {
const scale = interpolate(
progress.value,
[0, 1],
[1, scaleTo],
Extrapolate.CLAMP,
);
return {
transform: [{scale}],
};
});
return (
<TouchableWithoutFeedback
onPressIn={() => {
pressed.value = true;
}}
onPressOut={() => {
pressed.value = false;
}}
onPress={onPress}
disabled={disabled}>
<Animated.View style={animatedStyle}>{children}</Animated.View>
</TouchableWithoutFeedback>
);
};
EntryAnimation.js
import React, {useEffect} from 'react';
import Animated, {
useAnimatedStyle,
useSharedValue,
useDerivedValue,
interpolate,
withDelay,
withTiming,
} from 'react-native-reanimated';
export const EntryAnimation = ({children, index}) => {
const play = useSharedValue(false);
const progress = useDerivedValue(() => {
return play.value
? withDelay(50 * (index ?? 0), withTiming(1, {duration: 350}))
: 0;
});
useEffect(() => {
play.value = true;
}, [ play.value ]);
const animatedStyle = useAnimatedStyle(() => {
const opacity = interpolate(progress.value, [0, 1], [0, 1]);
const translateY = interpolate(progress.value, [0, 1], [100, 0]);
return {
opacity,
transform: [{translateY}],
};
});
return <Animated.View style={animatedStyle}>{children}</Animated.View>;
};
No comments:
Post a Comment