Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix transform in exiting animation #5470

Merged
merged 2 commits into from
Dec 11, 2023
Merged

Conversation

m-bert
Copy link
Contributor

@m-bert m-bert commented Dec 7, 2023

Summary

Right now, if element has any transform (for example translateX), exiting won't work correctly. This happens because during animations we write transform directly into components' style to avoid problems with delay. On the other hand, exiting works with snapshots which already take care about components position, including transforms.

In order to fix that we can ignore creating animation with transform and reset dummy.style.transform.

Test plan

Test code
import React from 'react';
import { StyleSheet, View, Text, Pressable } from 'react-native';
import Animated, {
  FadeIn,
  FadeInDown,
  FadeOutDown,
} from 'react-native-reanimated';

export default function App() {
  const [showExiting, setShowExiting] = React.useState(false);

  return (
    <View style={styles.container}>
      {showExiting ? (
        <View style={[styles.box, styles.exitingBox]} key={'FadeOutDown'}>
          <Text style={styles.exitingText}>{'FadeOutDown'}</Text>
        </View>
      ) : (
        <Animated.View
          entering={FadeIn}
          exiting={FadeOutDown}
          key={'FadeIn'}
          style={[
            styles.box,
            styles.enteringBox,
            { transform: [{ translateX: 20 }] },
          ]}>
          <Text style={styles.enteringText}>{'FadeIn'}</Text>
        </Animated.View>
      )}

      <Pressable
        style={styles.button}
        onPress={() => setShowExiting(!showExiting)}>
        <Text style={{ color: 'white' }}> Click me! </Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  box: {
    height: 50,
    width: 250,
    margin: 4,
    alignItems: 'center',
    justifyContent: 'center',
  },
  enteringBox: {
    backgroundColor: '#b58df1',
  },
  enteringText: {
    fontSize: 16,
    color: 'white',
  },
  exitingBox: {
    borderColor: '#b58df1',
    borderStyle: 'dashed',
    borderWidth: 1,
  },
  exitingText: {
    fontSize: 16,
    color: '#b58df1',
  },
  button: {
    width: 100,
    height: 40,
    marginTop: 50,
    backgroundColor: '#b58df1',
    borderRadius: 5,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'space-around',
  },
});

@m-bert m-bert requested a review from piaskowyk December 7, 2023 10:53
@mrousavy
Copy link
Contributor

mrousavy commented Dec 7, 2023

Do the snapshots also take scale into account? Trying to debug #5475 rn...

@m-bert m-bert added this pull request to the merge queue Dec 11, 2023
Merged via the queue into main with commit ec9d645 Dec 11, 2023
7 checks passed
@m-bert m-bert deleted the @mbert/ignore-transform-in-exiting branch December 11, 2023 08:54
Latropos pushed a commit that referenced this pull request Dec 12, 2023
## Summary
 
Right now, if element has any `transform` (for example `translateX`),
exiting won't work correctly. This happens because during animations we
write transform directly into components' style to avoid [problems with
delay](#5298).
On the other hand, exiting works with `snapshots` which already take
care about components position, including transforms.

In order to fix that we can ignore creating animation with transform and
reset `dummy.style.transform`.

## Test plan

<details>
<summary> Test code </summary>

```jsx
import React from 'react';
import { StyleSheet, View, Text, Pressable } from 'react-native';
import Animated, {
  FadeIn,
  FadeInDown,
  FadeOutDown,
} from 'react-native-reanimated';

export default function App() {
  const [showExiting, setShowExiting] = React.useState(false);

  return (
    <View style={styles.container}>
      {showExiting ? (
        <View style={[styles.box, styles.exitingBox]} key={'FadeOutDown'}>
          <Text style={styles.exitingText}>{'FadeOutDown'}</Text>
        </View>
      ) : (
        <Animated.View
          entering={FadeIn}
          exiting={FadeOutDown}
          key={'FadeIn'}
          style={[
            styles.box,
            styles.enteringBox,
            { transform: [{ translateX: 20 }] },
          ]}>
          <Text style={styles.enteringText}>{'FadeIn'}</Text>
        </Animated.View>
      )}

      <Pressable
        style={styles.button}
        onPress={() => setShowExiting(!showExiting)}>
        <Text style={{ color: 'white' }}> Click me! </Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  box: {
    height: 50,
    width: 250,
    margin: 4,
    alignItems: 'center',
    justifyContent: 'center',
  },
  enteringBox: {
    backgroundColor: '#b58df1',
  },
  enteringText: {
    fontSize: 16,
    color: 'white',
  },
  exitingBox: {
    borderColor: '#b58df1',
    borderStyle: 'dashed',
    borderWidth: 1,
  },
  exitingText: {
    fontSize: 16,
    color: '#b58df1',
  },
  button: {
    width: 100,
    height: 40,
    marginTop: 50,
    backgroundColor: '#b58df1',
    borderRadius: 5,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'space-around',
  },
});

```

</details>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants