dohooo / react-native-reanimated-carousel

🎠 React Native swiper/carousel component, fully implemented using reanimated v2, support to iOS/Android/Web. (Swiper/Carousel)
https://react-native-reanimated-carousel.vercel.app
MIT License
2.85k stars 329 forks source link

[Android][v4.0.0-canary.17] Carousel crashes the app #712

Open Bekaxp opened 2 weeks ago

Bekaxp commented 2 weeks ago

Describe the bug On Android when the user tries to scroll the carousel the app crashes and closes itself. Inspecting with Android Studio gives this error (top of the error stack):

java.lang.RuntimeException: Loss of precision during arithmetic conversion: (long) 388.7273063659668
at com.swmansion.reanimated.NativeProxy.performOperations(Native Method)

Maybe is even a bug with the react-native-reanimated, but I tried several versions and I always get the same results.

To Reproduce Steps to reproduce the behavior:

  1. Create a simple Carousel component:
    
    import Carousel from 'react-native-reanimated-carousel';
    import {View} from 'react-native';

export function CarouselView() { return ( <View style={{flex: 1}}> <Carousel ref={ref} width={width} height={height * 0.8} data={[1, 2, 3]} mode="parallax" modeConfig={{ parallaxScrollingScale: 0.9, parallaxScrollingOffset: 70, }} pagingEnabled={true} snapEnabled={true} vertical={false} renderItem={({item, index}) => {item}} /> ); };


2. Render it on an Android device/emulator
3. Try to scroll left/right
4. App crashes

**Expected behavior**
The Android app should not crash and the Carousel should scroll.

**Versions (please complete the following information):**
 - react: v18.3.1  
 - react-native: v0.76.1  
 - react-native-reanimated: v3.16.1    
 - react-native-reanimated-carousel: v4.0.0-canary.17  
 - react-native-gesture-handler: v2.20.2  

**Smartphone (please complete the following information):**
 - Device: Pixel 9 [emulator]

**Additional context**
- Using the Canary version of `react-native-reanimated-carousel`
dosubot[bot] commented 2 weeks ago

Hey @Bekaxp! I'm here to help you with any issues you're experiencing. I can assist you in solving bugs, answering questions, and becoming a contributor.

A similar issue regarding a "Loss of precision during arithmetic conversion" error has been reported and resolved. The suggested solution involves ensuring that arithmetic operations involving floating-point numbers are correctly handled before casting to a long. You can use Math.round in JavaScript to avoid precision loss. Here's an example:

const value = 388.7273063659668;
const longValue = Math.round(value); // Use Math.round to avoid precision loss

Additionally, ensure your babel.config.js includes the react-native-reanimated/plugin:

module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: ['react-native-reanimated/plugin'],
  };
};

Make sure your project is using compatible versions of the dependencies:

"dependencies": {
  "react": "18.3.1",
  "react-native": "0.76.1",
  "react-native-reanimated": "3.16.1",
  "react-native-reanimated-carousel": "4.0.0-canary.17",
  "react-native-gesture-handler": "2.20.2"
}

These steps should help resolve the issue and ensure compatibility [1].

To continue talking to Dosu, mention @dosu.

Bekaxp commented 2 weeks ago

Thank you

but as you can see in my simple example I am not doing any conversions of any sort. I guess this is done internally in the lib to calculate the positioning?

Cheers

Medkhat commented 2 weeks ago

Hi there! "react-native-reanimated-carousel": "^3.5.1" also has this issue

Yusang-park commented 1 week ago

I upgraded to 4.0.0~canary-17 and no issue was found. but I needed to modify the custom animation.

previous


const parallelX = (value: number) => {
  'worklet';

  const zIndex = interpolate(value, [-1, 0, 1], [10, 20, 30]);
  const scale = interpolate(value, [-2, -1, 0, 1, 2], [0.7, 0.8, 1, 0.8, 0.7]);
  const opacity = interpolate(value, [-0.75, 0, 1], [0, 1, 0]);
  const translateX = interpolate(value, [-1, 0, 1], [-PAGE_WIDTH * 0.5, 0, PAGE_WIDTH]);
  return {
    transform: [{ translateX }, { scale }],
    zIndex,
    opacity,
  };
};

new

const parallelX = (value: number) => {
  'worklet';

  const zIndex = Math.round(interpolate(value, [-1, 0, 1], [10, 20, 30]));
  const scale = interpolate(value, [-1, 0, 1], [0.8, 1, 0.8]);
  const opacity = interpolate(value, [-1, 0, 1], [0, 1, 0]);
  const translateX = Math.round(interpolate(value, [-1, 0, 1], [-PAGE_WIDTH * 0.3, 0, PAGE_WIDTH * 0.3]));

  return {
    transform: [{ translateX }, { scale }] as const,
    zIndex,
    opacity,
  };
};

Trying to add Math.***

Medkhat commented 1 week ago

@Yusang-park Did you test it on Android? I don't have any custom animation:

<Carousel
      autoPlay
      autoPlayInterval={4000}
      data={data as Banner[]}
      width={FULL_WIDTH_CONTENT}
      height={BANNER_HEIGHT}
      loop={true}
      pagingEnabled={true}
      snapEnabled={true}
      mode="parallax"
      modeConfig={{
        parallaxScrollingScale: 0.9,
        parallaxScrollingOffset: 50,
      }}
      // mode="horizontal-stack"
      // modeConfig={{
      //   showLength: 1,
      // }}
      renderItem={renderItem}
  />
Bekaxp commented 1 week ago

Have a look at the discussion in #715 . There is also a PR open to fix this. I tried with the patch from @thibaultcapelli and it worked. So I will happily wait for the PR to be merged and a new canary version to be released 👍 . Thanks.