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

Problem with Stacks #566

Open
Code-Victor opened this issue Mar 12, 2024 · 1 comment
Open

Problem with Stacks #566

Code-Victor opened this issue Mar 12, 2024 · 1 comment
Assignees
Labels
bug Something isn't working

Comments

@Code-Victor
Copy link

Bug Description

Overview:
Encountering unexpected behaviors when using the react-native-reanimated-carousel library to build a flashcard list. The issues vary depending on the number of items in the data array.

Issues:

  1. Data Length > 2 (Expected Behavior):

    • The carousel functions correctly with a dataset larger than two items.
  2. Data Length = 2 (Erroneous Behavior):

    • Click actions on the first card inadvertently trigger actions on the second card as well, causing both cards to flip simultaneously.
  3. Data Length = 1 (Erroneous Behavior):

    • The single item in the carousel appears with an opacity of zero, rendering it invisible.

Screenshots:

  • Behavior with more than two items: many-items

  • Behavior with exactly two items:
    2-items

  • Behavior with a single item: Screenshot_1710259321

To Reproduce
Here's my code

function FlashcardCarousel({ data }: { data: FlashcardsData }) {
  const viewCount = 5;
  const { width } = useWindowDimensions();
  const renderItem = React.useCallback(
    ({ item, index }: { item: Option; index: number }) => {
      return (
        <FlipCard
          containerProps={{
            style: {
              flex: 1,
              marginHorizontal: 18,
              marginVertical: 12,
            },
            onPress: () => {
              console.log("pressed");
              console.log("pressed", item);
            },
          }}
          frontItem={<FrontItem question={item.front} />}
          backItem={<BackItem answer={item.back} />}
          key={`${item.front}-${index}`}
        />
      );
    },
    []
  );
  
  return (
    <View f={1} ai="center" jc="center" py="$4">
      <Carousel
        width={width}
        snapEnabled={true}
        mode={"horizontal-stack"}
        defaultIndex={0}
        loop={false}
        data={[data.options[0]]}
        modeConfig={{
          moveSize: width * 1.5,
          stackInterval: 22,
          scaleInterval: 0.08,
          rotateZDeg: 60,
          snapDirection: "left",
        }}
        customConfig={() => ({ type: "positive" })}
        renderItem={renderItem}
      />
    </View>
  );
}

Flipcard

import React from "react";
import { StyleSheet } from "react-native";
import Animated, {
  AnimatedProps,
  interpolate,
  useAnimatedStyle,
  useSharedValue,
  withTiming,
} from "react-native-reanimated";
import { View, ViewProps } from "tamagui";

const AnimatedView = Animated.createAnimatedComponent(View);

export const FlipCard = ({
  containerProps,
  backItem,
  frontItem,
}: {
  containerProps?: AnimatedProps<ViewProps>;
  frontItem?: React.ReactNode;
  backItem?: React.ReactNode;
}) => {
  const spin = useSharedValue<number>(0);

  const rStyle = useAnimatedStyle(() => {
    const spinVal = interpolate(spin.value, [0, 1], [0, 180]);
    return {
      transform: [
        {
          rotateY: withTiming(`${spinVal}deg`, { duration: 500 }),
        },
      ],
    };
  }, []);

  const bStyle = useAnimatedStyle(() => {
    const spinVal = interpolate(spin.value, [0, 1], [180, 360]);
    return {
      transform: [
        {
          rotateY: withTiming(`${spinVal}deg`, { duration: 500 }),
        },
      ],
    };
  }, []);

  return (
    <AnimatedView
      pos="relative"
      {...containerProps}
      onPress={() => {
        spin.value = spin.value ? 0 : 1;
        console.log("pressed");
      }}
    >
      <AnimatedView style={[Styles.front, rStyle]}>{frontItem}</AnimatedView>
      <AnimatedView style={[Styles.back, bStyle]}>{backItem}</AnimatedView>
    </AnimatedView>
  );
};

export default FlipCard;

const Styles = StyleSheet.create({
  front: {
    flex: 1,
    position: "absolute",
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
  },
  back: {
    flex: 1,
    backfaceVisibility: "hidden",
    zIndex: 10,
  },
});

Expected behavior
I hope I can get a consistent behavior like the first one(many items)

Versions (please complete the following information):

  • react: v18.2.0
  • react-native: v0.73.4
  • react-native-reanimated: v~3.6.2
  • react-native-reanimated-carousel: v^3.5.1
  • react-native-gesture-handler: v~2.14.0

Smartphone (please complete the following information):

  • Device: Pixel 7 Emmulator
  • OS: Android
@Code-Victor Code-Victor added the bug Something isn't working label Mar 12, 2024
@ckanissatran
Copy link

I think I'm running into something similar.

I have a carousel with two items. The carousel ref thinks there are 4 items in the carousel, but the data only has 2 items. Other carousels are fine as long as they have more than 2 items.

This is only an issue for carousels with 2 items? Anyone else running into something similar?

I'm on 4.0.0-alpha.10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants