Skip to content

Commit

Permalink
Merge pull request #2 from Endurance-Soft/feateru/waterfall-animation…
Browse files Browse the repository at this point in the history
…s-addition

feat(ui): Add waterfall animation to Home and Search screens
  • Loading branch information
WilliamCallao authored Mar 8, 2024
2 parents 6d76382 + 72dd174 commit 313c57a
Show file tree
Hide file tree
Showing 11 changed files with 315 additions and 112 deletions.
14 changes: 13 additions & 1 deletion AppNavigator.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { NavigationContainer } from '@react-navigation/native';
import NewScreen from './src/screens/HomeScreen';
import ClientSearchScreen from './src/screens/ClientSearchScreen';
import CascadingEffectScreen from './src/screens/CascadingEffectScreen';

const Stack = createNativeStackNavigator();

function AppNavigator() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="NewScreen" >
<Stack.Navigator initialRouteName="NewScreen"
screenOptions={{
animationEnabled: false, // Desactivar animaciones de transición
}}
>
<Stack.Screen
name="NewScreen"
component={NewScreen}
Expand All @@ -24,6 +29,13 @@ function AppNavigator() {
headerShown: false,
}}
/>
<Stack.Screen
name='CascadingEffectScreen'
component={CascadingEffectScreen}
options={{
headerShown: false,
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
Expand Down
48 changes: 48 additions & 0 deletions src/animation/AnimatedComponent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { useEffect, useRef } from 'react';
import { Animated, StyleSheet } from 'react-native';

const AnimatedComponent = ({ delay, children, style }) => {
const fadeAnim = useRef(new Animated.Value(0)).current;
const yPosition = useRef(new Animated.Value(20)).current;

useEffect(() => {
const timer = setTimeout(() => {
Animated.parallel([
Animated.timing(fadeAnim, {
toValue: 1,
duration: 300,
useNativeDriver: true,
}),
Animated.timing(yPosition, {
toValue: 0,
duration: 300,
useNativeDriver: true,
}),
]).start();
}, delay);

return () => clearTimeout(timer);
}, [delay]);

return (
<Animated.View
style={[
{
opacity: fadeAnim,
transform: [{ translateY: yPosition }],
},
style,
]}
>
{children}
</Animated.View>
);
};

export default AnimatedComponent;

// import AnimatedComponent from './AnimatedComponent';
// <AnimatedComponent delay={0}></AnimatedComponent>
// la animacion del componente que lo utiliza dura 300ml,
// lo ideal es que el timepo de los componentes que continuan
// la cascada tengan una diferencia de 200ml segun el orden vertical que tienen
62 changes: 62 additions & 0 deletions src/animation/CascadingFadeInView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React, { useEffect, useRef } from 'react';
import { Animated, Text, StyleSheet } from 'react-native';

const CascadingFadeInView = ({ children, delay = 0, style, animationKey }) => {
const fadeAnim = useRef(new Animated.Value(0)).current;
const yPosition = useRef(new Animated.Value(20)).current;

useEffect(() => {
fadeAnim.setValue(0);
yPosition.setValue(20);

const timer = setTimeout(() => {
Animated.parallel([
Animated.timing(fadeAnim, {
toValue: 1,
duration: 300,
useNativeDriver: true,
}),
Animated.timing(yPosition, {
toValue: 0,
duration: 200,
useNativeDriver: true,
}),
]).start();
}, delay);

return () => clearTimeout(timer);
}, [animationKey]);

return (
<Animated.View
style={[
style,
{
opacity: fadeAnim,
transform: [{ translateY: yPosition }],
},
]}
>
{children}
</Animated.View>
);
};

const styles = StyleSheet.create({
});

export default CascadingFadeInView;

// import Cascading from '../animation/CascadingFadeInView';
// import { useFocusEffect } from '@react-navigation/native';


// const [animationKey, setAnimationKey] = useState(Date.now());
// useFocusEffect(
// useCallback(() => {
// setAnimationKey(Date.now());
// }, [])
// );

{/* <Cascading delay={100} animationKey={animationKey}>
</Cascading> */}
4 changes: 2 additions & 2 deletions src/components/DropdownSelector.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// DropdownSelector.js
import React, { useState } from "react";
import React, { useState, useCallback } from "react";
import { View, Text } from "react-native";
import { FontAwesome5 } from "@expo/vector-icons";
import { Menu, MenuOptions, MenuOption, MenuTrigger } from "react-native-popup-menu";
Expand All @@ -11,7 +11,7 @@ const DropdownSelector = ({ selectedOption, onOptionChange }) => {
const toggleMenu = () => {
setMenuVisible(prevState => !prevState);
};

return (
<View style={styles.container}>
<View style={styles.label}>
Expand Down
19 changes: 16 additions & 3 deletions src/components/ProfileHeader.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
// ProfileHeader.js
import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import React, { useState, useCallback } from 'react';
import { View, Text, TouchableOpacity} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import { useNavigation } from '@react-navigation/native';
import {styles} from './styles/ProfileHeaderStyles';
import Cascading from '../animation/CascadingFadeInView';
import { useFocusEffect } from '@react-navigation/native';

const ProfileHeader = ({ userName }) => {
const [animationKey, setAnimationKey] = useState(Date.now());
useFocusEffect(
useCallback(() => {
setAnimationKey(Date.now());
}, [])
);

const navigation = useNavigation();
return (
<View style={styles.maxContainer}>
<Cascading delay={100} animationKey={animationKey}>
<View style={styles.acountContainer}>
<View style={styles.letter}>
<Text style={styles.initialLetter}>J</Text>
Expand All @@ -18,6 +28,8 @@ const ProfileHeader = ({ userName }) => {
<Text style={styles.userName}>{userName}</Text>
</View>
</View>
</Cascading>
<Cascading delay={200} animationKey={animationKey}>
<View style={styles.buttonContainer}>
<TouchableOpacity style={styles.button} onPress={() => navigation.navigate('ClientSearchScreen')}>
<Icon name="money" size={40} color="black" />
Expand All @@ -30,8 +42,9 @@ const ProfileHeader = ({ userName }) => {
<TouchableOpacity style={styles.button}>
<Icon name="line-chart" size={40} color="black" />
<Text style={styles.buttonText}>Ventas</Text>
</TouchableOpacity>
</TouchableOpacity>
</View>
</Cascading>
</View>
);
};
Expand Down
3 changes: 0 additions & 3 deletions src/components/styles/DropdownSelectorStyles.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,10 @@ export const styles = StyleSheet.create({
flexDirection: "row",
alignItems: 'center',
justifyContent: 'space-between',
elevation: 5,
paddingVertical: 12,
paddingHorizontal: 25,
backgroundColor: theme.colors.tertiary,
borderRadius: 22,
elevation: 5,
width: 200,
},
menuTriggerInter: {
Expand All @@ -58,7 +56,6 @@ export const styles = StyleSheet.create({
borderRadius: 20,
width: 200,
backgroundColor: theme.colors.tertiary,
elevation: 5,
},
optionsWrapper: {
marginLeft: 20,
Expand Down
2 changes: 1 addition & 1 deletion src/components/styles/ProfileHeaderStyles.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export const styles = StyleSheet.create({
justifyContent: 'flex-end',
paddingVertical: 10,
paddingLeft: 13,
elevation:5,
// elevation:5,
},
buttonText: {
marginTop: 3,
Expand Down
3 changes: 0 additions & 3 deletions src/components/styles/SearchBarStyles.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export const searchBarStyles = StyleSheet.create({
borderRadius: 22,
alignItems: "center",
marginHorizontal: windowWidth * 0.05,
elevation: 5,
},
searchTextInput: {
flex: 1,
Expand All @@ -24,7 +23,6 @@ export const searchBarStyles = StyleSheet.create({
color: theme.colors.primaryText,
},
trigger: {
elevation: 5,
paddingVertical: 12,
paddingHorizontal: 25,
backgroundColor: theme.colors.tertiary,
Expand All @@ -43,7 +41,6 @@ export const searchBarStyles = StyleSheet.create({
borderRadius: 20,
width: 142,
backgroundColor: theme.colors.tertiary,
elevation: 5,
},
optionsWrapper: {
marginLeft: 20,
Expand Down
32 changes: 32 additions & 0 deletions src/screens/CascadingEffectScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import AnimatedComponent from '../animation/AnimatedComponent';

const CascadingEffectScreen = () => {
return (
<View style={styles.container}>
<AnimatedComponent delay={0}>
<Text>Texto que aparece inmediatamente</Text>
</AnimatedComponent>
<AnimatedComponent delay={200} style={styles.delayedText}>
<Text>Texto que aparece después de 2 segundos</Text>
</AnimatedComponent>
<AnimatedComponent delay={400} style={styles.delayedText}>
<Text>Texto que aparece después de 2 segundos</Text>
</AnimatedComponent>
</View>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
delayedText: {
marginTop: 20, // Espacio entre los textos animados
},
});

export default CascadingEffectScreen;
Loading

0 comments on commit 313c57a

Please sign in to comment.