Skip to content

Commit 2a59463

Browse files
committed
FadeInDown animation
1 parent 01d62ff commit 2a59463

File tree

2 files changed

+31
-17
lines changed

2 files changed

+31
-17
lines changed

hackathon/spacecraft/src/components/StarshipCard.tsx

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,48 @@ import { useNavigation } from "@react-navigation/native";
22
import * as React from "react";
33
import { Alert, StyleSheet } from "react-native";
44
import { Button, Card, Text } from "react-native-paper";
5-
import Animated, { FadeIn, FadeOut } from "react-native-reanimated";
5+
import Animated, {
6+
AnimateProps,
7+
FadeIn,
8+
FadeOut,
9+
FadeInDown,
10+
} from "react-native-reanimated";
611

712
import type { StarshipProps } from "../../api/types";
813
import { useImage } from "../hooks/useImage";
914
import { Routes } from "../navigation/Routes";
1015

1116
import { Image } from "~/components/Image";
1217

13-
export function createAnimatedComponentFrowardingRef<P, S>(
14-
Component: React.ComponentClass<P, S>
15-
) {
16-
return React.forwardRef<React.Component<P, S>, P>((props, ref) => {
17-
class Wrapper extends React.Component<P, S> {
18-
render() {
19-
return <Component {...this.props} ref={ref} />;
20-
}
18+
export function withAnimated<T extends object>(
19+
WrappedComponent: React.ComponentType<T>
20+
): React.ComponentClass<AnimateProps<T>, any> {
21+
const displayName =
22+
WrappedComponent.displayName || WrappedComponent.name || "Component";
23+
24+
class WithAnimated extends React.Component<T, any> {
25+
static displayName = `WithAnimated(${displayName})`;
26+
27+
render(): React.ReactNode {
28+
return <WrappedComponent {...this.props} />;
2129
}
22-
const AnimatedWrapper = Animated.createAnimatedComponent(Wrapper);
23-
return <AnimatedWrapper {...props} />;
24-
});
30+
}
31+
return Animated.createAnimatedComponent(WithAnimated);
2532
}
2633

27-
const AnimatedCard = createAnimatedComponentFrowardingRef(Card);
34+
const AnimatedCard = withAnimated(Card);
2835

2936
export interface StarshipCardProps {
3037
ship: StarshipProps;
38+
index: number;
3139
}
3240

3341
interface StarshipDetailsScreenParams {
3442
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3543
navigate: any;
3644
}
3745

38-
export const StarshipCard = ({ ship }: StarshipCardProps) => {
46+
export const StarshipCard = ({ ship, index }: StarshipCardProps) => {
3947
const title = ship.name;
4048
const price = ship.cost_in_credits;
4149
const { manufacturer } = ship;
@@ -51,14 +59,19 @@ export const StarshipCard = ({ ship }: StarshipCardProps) => {
5159
navigation.navigate(Routes.STARSHIP_DETAILS_SCREEN, ship);
5260
};
5361

62+
// visibleIndex -> prop
63+
// Range = if index belongs to this range [visibleIndex - 2, visibleIndex+ 2] -> animate
64+
// otherwise don't animate
5465
return (
5566
<AnimatedCard
5667
style={styles.containerCard}
5768
onPress={handleGoToDetails}
5869
// mounting
59-
entering={FadeIn.duration(500)}
70+
entering={FadeInDown.duration(index > 3 ? 0 : 250).delay(
71+
index > 3 ? 0 : 100 * index
72+
)}
6073
// unmounting
61-
existing={FadeOut.duration(500)}
74+
exiting={FadeOut.duration(250)}
6275
>
6376
<Image
6477
style={{ width: "100%", height: 200, borderRadius: 12 }}

hackathon/spacecraft/src/screens/StarshipFeedScreen.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ interface ShipProps {
1717

1818
interface RenderItemProps {
1919
item: ShipProps;
20+
index: number;
2021
}
2122

2223
// SOLUTION 2: with a FlatList - more performant
2324
const renderItem = (props: RenderItemProps) => {
2425
const ship = props.item;
2526

26-
return <StarshipCard ship={ship} />;
27+
return <StarshipCard ship={ship} index={props.index} />;
2728
};
2829

2930
export const StarshipFeedScreen = () => {

0 commit comments

Comments
 (0)