Skip to content
This repository has been archived by the owner on May 7, 2023. It is now read-only.

Commit

Permalink
Resolve issue #437 - Fix animation bug in [SignIn] (#438)
Browse files Browse the repository at this point in the history
`transform` animation value is not preserved between render on mobile. This is the reason that `scale` is return to origin when writing a text on `textInput` which invokes `re-render`.  So I changed animation value from `scale` to `width` and `height`.

But there is a bug about `withSpring` function on `web`, then I splits an animation value according to platform. 
This bug seems to have related with `react-native-web`.  You can check relate issue with [here](software-mansion/react-native-reanimated#1804) or [here](necolas/react-native-web#1935).
  • Loading branch information
DevYuns authored Jul 28, 2021
1 parent 427d3b5 commit d0aae78
Showing 1 changed file with 42 additions and 20 deletions.
62 changes: 42 additions & 20 deletions client/src/components/pages/SignIn/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ import {useAuthContext} from '../../../providers/AuthProvider';
import {useMutation} from 'react-relay';
import {useNavigation} from '@react-navigation/core';

const AnimatedTouchableOpacity =
Animated.createAnimatedComponent(TouchableOpacity);
const AnimatedImage = Animated.createAnimatedComponent(Image);

const Container = styled.SafeAreaView`
flex: 1;
Expand Down Expand Up @@ -291,40 +290,64 @@ const SignIn: FC = () => {
// console.log('appOwnership', Constants.appOwnership);
}, []);

const LOGO_SIZE = 80;
const logoAnimValue = useSharedValue(0);
const {width: screenWidth, height: screenHeight} = Dimensions.get('window');
const LOGO_SIZE = 80;

const logoInitialPosition = {
x: (screenWidth - LOGO_SIZE) * 0.5,
y: screenHeight * 0.5 - LOGO_SIZE,
};
const logoAnimValue = useSharedValue(0);

useEffect(() => {
logoAnimValue.value = withSpring(1, {stiffness: 36, mass: 1.5});
let timer = setTimeout(
() => (logoAnimValue.value = withSpring(1, {stiffness: 36, mass: 1.5})),
100,
);

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

const logoAnimStyle = useAnimatedStyle(() => {
const left = interpolate(
logoAnimValue.value,
[0, 1],
[logoInitialPosition.x, 30],
[screenWidth * 0.7, 30],
);

const top = interpolate(
logoAnimValue.value,
[0, 1],
[logoInitialPosition.y, 80],
[screenHeight * 0.3, 80],
);

const scale = interpolate(logoAnimValue.value, [0, 1], [2, 1]);
const width =
Platform.OS !== 'web'
? withSpring(
interpolate(
logoAnimValue.value,
[0, 1],
[LOGO_SIZE * 2, LOGO_SIZE],
),
)
: interpolate(logoAnimValue.value, [0, 1], [LOGO_SIZE * 2, LOGO_SIZE]);

const height =
Platform.OS !== 'web'
? withSpring(
interpolate(
logoAnimValue.value,
[0, 1],
[LOGO_SIZE * 2, LOGO_SIZE],
),
)
: interpolate(logoAnimValue.value, [0, 1], [LOGO_SIZE * 2, LOGO_SIZE]);

return {
zIndex: 15,
position: 'absolute',
left,
zIndex: 15,
top,
transform: [{scale}],
left,
width,
height,
};
});

Expand All @@ -333,15 +356,14 @@ const SignIn: FC = () => {
<StatusBarBrightness />

<StyledScrollView>
<AnimatedTouchableOpacity
style={logoAnimStyle}
<TouchableOpacity
testID="theme-test"
onPress={(): void => changeThemeType()}>
<Image
style={{width: LOGO_SIZE, height: LOGO_SIZE, resizeMode: 'cover'}}
<AnimatedImage
style={[logoAnimStyle, {resizeMode: 'cover'}]}
source={themeType === 'dark' ? IC_LOGO_D : IC_LOGO_W}
/>
</AnimatedTouchableOpacity>
</TouchableOpacity>
<Wrapper>
<LogoWrapper>
<View style={{height: 12 + 60}} />
Expand Down

0 comments on commit d0aae78

Please sign in to comment.