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

Flip card animation example is broken in iOS with Expo 52 #6722

Open
david-bermejo opened this issue Nov 18, 2024 · 6 comments
Open

Flip card animation example is broken in iOS with Expo 52 #6722

david-bermejo opened this issue Nov 18, 2024 · 6 comments
Assignees
Labels
Platform: iOS This issue is specific to iOS Repro provided A reproduction with a snippet of code, snack or repo is provided

Comments

@david-bermejo
Copy link

david-bermejo commented Nov 18, 2024

Description

As the title says, flip card animation example present in your page is broken in iOS with Expo 52. I am using it in one of my projects and the same happens.

The provided Snack project is the one present in your page as an example. When flipped, the back card face is visible on top during the animation, and that should not happen. This bug was not present in Expo 51 or previous versions. Other platforms are not affected.

Steps to reproduce

  1. Open snack project
  2. Make sure platform option is iOS and Expo version is 52.0.0
  3. Click on Launch Snack

Snack or a link to a repository

https://snack.expo.dev/@bermejus/flip-card-%7C-react-native-reanimated?platform=ios

Reanimated version

3.16.1

React Native version

0.76.2

Platforms

iOS

JavaScript runtime

Hermes

Workflow

Expo Go

Architecture

Fabric (New Architecture)

Build type

None

Device

iOS simulator

Device model

No response

Acknowledgements

Yes

@github-actions github-actions bot added Missing repro This issue need minimum repro scenario Platform: iOS This issue is specific to iOS Repro provided A reproduction with a snippet of code, snack or repo is provided and removed Missing repro This issue need minimum repro scenario labels Nov 18, 2024
@patrycjakalinska patrycjakalinska self-assigned this Nov 20, 2024
@kristof-kovacs
Copy link

I am also experiencing this after Expo SDK 52 upgrade

@patrycjakalinska
Copy link
Contributor

patrycjakalinska commented Nov 21, 2024

Hi @david-bermejo ! It looks like on newer releases backfaceVisibility works slightly different. Setting backfaceVisibility: 'hidden' on both cards should fix this issue:

      // ...
      
      <FlipCard
        isFlipped={isFlipped}
        cardStyle={styles.flipCard}
        FlippedContent={<FlippedContent />}
        RegularContent={<RegularContent />}
      />
      
      // ...
      
      const styles = StyleSheet.create({
         flipCard: {
          width: 170,
          height: 200,
          backfaceVisibility: 'hidden'
  },
});

@kristof-kovacs
Copy link

Hi @patrycjakalinska I tried that on both the cards and that has not fixed it. However in my implementation the cards are two separate modals with equal dimensions that I am flipping between. Their animated styles are below, as you can see the backfaceVisibility has always been 'hidden', and that used to work but no longer does

     const frontAnimatedStyle = useAnimatedStyle(() => {
        const rotateValue = interpolate(rotate.value, [0, 1], [0, 180]);
        return {
            transform: [
                { rotateY: `${rotateValue}deg` },
                { perspective: 1000 },
            ],
            backfaceVisibility: 'hidden',
            pointerEvents: rotate.value < 0.5 ? 'auto' : 'none',
        };
    }, [rotate]);

    const backAnimatedStyle = useAnimatedStyle(() => {
        const rotateValue = interpolate(rotate.value, [0, 1], [-180, 0]);
        return {
            transform: [
                { rotateY: `${rotateValue}deg` },
                { perspective: 1000 },
            ],
            backfaceVisibility: 'hidden',
            pointerEvents: rotate.value >= 0.5 ? 'auto' : 'none',
        };
    }, [rotate]);

@patrycjakalinska
Copy link
Contributor

Hi @kristof-kovacs, could you provide a full snack or some code source, so I can look into that?

@kristof-kovacs
Copy link

Really appreciate you taking the time to look into it @patrycjakalinska. The most productive thing for me to show you here is the rendering logic of the modals. Both modals that make up the card, as well as the screen in which they are rendered are massive files so not too comfortable sharing them in full here.

Here is the style, as well as the function that flips the card:

const frontAnimatedStyle = useAnimatedStyle(() => {
        const rotateValue = interpolate(rotate.value, [0, 1], [0, 180]);
        return {
            transform: [
                { rotateY: `${rotateValue}deg` },
                { perspective: 1000 },
            ],
            backfaceVisibility: 'hidden',
            pointerEvents: rotate.value < 0.5 ? 'auto' : 'none',
        };
    }, [rotate]);

    const backAnimatedStyle = useAnimatedStyle(() => {
        const rotateValue = interpolate(rotate.value, [0, 1], [-180, 0]);
        return {
            transform: [
                { rotateY: `${rotateValue}deg` },
                { perspective: 1000 },
            ],
            backfaceVisibility: 'hidden',
            pointerEvents: rotate.value >= 0.5 ? 'auto' : 'none',
        };
    }, [rotate]);

    const triggerFlip = () => {
        rotate.value = withTiming(rotate.value === 0 ? 1 : 0, { duration: 500 });
    };

and here is the rendering of the two different card views with the frontFlipCard and backFlipCard

<Modal
                animationType="slide"
                transparent={true}
                visible={isModalVisible}
                onRequestClose={() => {
                    setIsModalVisible(!isModalVisible);
                }}
            >
                <BlurView style={styles.fullScreen} intensity={50} tint="dark">
                    <View style={styles.animationContainer}>
                        <Animated.View style={[styles.frontFlipCard, frontAnimatedStyle]}>
                            <FinishedBooksFrontModal
                                book={book}
                                userDetails={currentUser.userDetails}
                                setIsModalVisible={setIsModalVisible}
                                triggerFlip={triggerFlip}
                                startDate={startDate}
                                setStartDate={setStartDate}
                                endDate={endDate}
                                setEndDate={setEndDate}
                                reviewText={reviewText}
                                setReviewText={setReviewText}
                                isSilent={isSilent}
                                setIsSilent={setIsSilent}
                                isAudio={isAudio}
                                setIsAudio={setIsAudio}
                                isAudioDisabled={isAudioDisabled}
                                isSpoiler={isSpoiler}
                                setIsSpoiler={setIsSpoiler}
                            />
                        </Animated.View>
                        <Animated.View style={[styles.backFlipCard, backAnimatedStyle]}>
                            <FinishedBooksBackModal
                                book={book}
                                triggerFlip={triggerFlip}
                                reviewText={reviewText}
                                setReviewText={setReviewText}
                                isSpoiler={isSpoiler}
                                setIsSpoiler={setIsSpoiler}
                            />
                        </Animated.View>
                    </View>
                </BlurView>
            </Modal>

and finally, the relevant styles

animationContainer: {
        position: 'relative',
        width: '80%',
        height: '80%',
    },
    frontFlipCard: {
        width: '100%',
        height: '100%',
        justifyContent: 'center',
        alignItems: 'center',
        position: 'absolute',
        backfaceVisibility: 'hidden'
    },
    backFlipCard: {
        width: '100%',
        height: '100%',
        justifyContent: 'center',
        alignItems: 'center',
        backfaceVisibility: 'hidden',
        position: 'absolute',
        backfaceVisibility: 'hidden'
    },

@david-bermejo
Copy link
Author

Hi @david-bermejo ! It looks like on newer releases backfaceVisibility works slightly different. Setting backfaceVisibility: 'hidden' on both cards should fix this issue:


      // ...

      

      <FlipCard

        isFlipped={isFlipped}

        cardStyle={styles.flipCard}

        FlippedContent={<FlippedContent />}

        RegularContent={<RegularContent />}

      />

      

      // ...

      

      const styles = StyleSheet.create({

         flipCard: {

          width: 170,

          height: 200,

          backfaceVisibility: 'hidden'

  },

});

Wow it really solved my problem, thank you for your time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Platform: iOS This issue is specific to iOS Repro provided A reproduction with a snippet of code, snack or repo is provided
Projects
None yet
Development

No branches or pull requests

3 participants