Skip to content

Commit 869bcc8

Browse files
authored
AnimatedImage - move from LayoutAnimation to AnimationStyle (#2223)
* AnimatedImage - move from LayoutAnimation to AnimationStyle This is done so we can stop the animation when we choose to (i.e. remove the loader). * Fix snapshots
1 parent cb81130 commit 869bcc8

File tree

2 files changed

+47
-28
lines changed

2 files changed

+47
-28
lines changed

demo/src/screens/__tests__/__snapshots__/AvatarScreen.spec.js.snap

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,9 +1254,9 @@ exports[`AvatarScreen renders screen 1`] = `
12541254
undefined,
12551255
undefined,
12561256
undefined,
1257-
Object {},
1258-
Object {},
1259-
Object {},
1257+
undefined,
1258+
undefined,
1259+
undefined,
12601260
Object {
12611261
"alignItems": "center",
12621262
"borderRadius": 999,
@@ -1288,21 +1288,26 @@ exports[`AvatarScreen renders screen 1`] = `
12881288
undefined,
12891289
false,
12901290
Array [
1291+
Array [
1292+
Object {
1293+
"alignItems": "center",
1294+
"borderRadius": 999,
1295+
"height": 60,
1296+
"justifyContent": "center",
1297+
"width": 60,
1298+
},
1299+
Object {
1300+
"bottom": 0,
1301+
"left": 0,
1302+
"position": "absolute",
1303+
"right": 0,
1304+
"top": 0,
1305+
},
1306+
undefined,
1307+
],
12911308
Object {
1292-
"alignItems": "center",
1293-
"borderRadius": 999,
1294-
"height": 60,
1295-
"justifyContent": "center",
1296-
"width": 60,
1309+
"opacity": 0,
12971310
},
1298-
Object {
1299-
"bottom": 0,
1300-
"left": 0,
1301-
"position": "absolute",
1302-
"right": 0,
1303-
"top": 0,
1304-
},
1305-
undefined,
13061311
],
13071312
false,
13081313
]

src/components/animatedImage/index.tsx

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
// TODO: consider unify this component functionality with our Image component
2-
import React, {useState, useCallback} from 'react';
2+
import React, {useState, useCallback, useMemo} from 'react';
33
import {StyleSheet, StyleProp, ViewStyle, NativeSyntheticEvent, ImageLoadEventData} from 'react-native';
4-
import Animated, {FadeIn} from 'react-native-reanimated';
4+
import Animated, {useSharedValue, useAnimatedStyle, withTiming} from 'react-native-reanimated';
55
import View from '../../components/view';
66
import Image, {ImageProps} from '../../components/image';
7+
import {useDidUpdate} from '../../hooks';
78

89
const UIAnimatedImage = Animated.createAnimatedComponent<ImageProps>(Image);
910

@@ -39,24 +40,37 @@ const AnimatedImage = (props: AnimatedImageProps) => {
3940
testID,
4041
...others
4142
} = props;
43+
4244
const [isLoading, setIsLoading] = useState(true);
45+
const opacity = useSharedValue(0);
46+
47+
useDidUpdate(() => {
48+
if (!loader) {
49+
opacity.value = 1;
50+
}
51+
}, [loader]);
4352

4453
const onLoad = useCallback((event: NativeSyntheticEvent<ImageLoadEventData>) => {
4554
setIsLoading(false);
4655
propsOnLoad?.(event);
56+
// did not start the animation already
57+
if (opacity.value === 0) {
58+
opacity.value = withTiming(1, {duration: animationDuration});
59+
}
4760
},
48-
[setIsLoading, propsOnLoad]);
61+
// eslint-disable-next-line react-hooks/exhaustive-deps
62+
[setIsLoading, propsOnLoad, animationDuration]);
63+
64+
const fadeInStyle = useAnimatedStyle(() => {
65+
return {opacity: opacity.value};
66+
});
67+
68+
// eslint-disable-next-line react-hooks/exhaustive-deps
69+
const _style = useMemo(() => [style, fadeInStyle], [style]);
4970

5071
return (
51-
<View reanimated style={containerStyle}>
52-
<UIAnimatedImage
53-
entering={FadeIn.duration(animationDuration)}
54-
{...others}
55-
style={style}
56-
source={source}
57-
onLoad={onLoad}
58-
testID={testID}
59-
/>
72+
<View style={containerStyle}>
73+
<UIAnimatedImage {...others} style={_style} source={source} onLoad={onLoad} testID={testID}/>
6074
{isLoading && loader && <View style={styles.loader}>{loader}</View>}
6175
</View>
6276
);

0 commit comments

Comments
 (0)