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

How to add both left and right margin? #539

Open
ivankdev opened this issue Jan 26, 2024 · 9 comments
Open

How to add both left and right margin? #539

ivankdev opened this issue Jan 26, 2024 · 9 comments
Labels
question Further information is requested

Comments

@ivankdev
Copy link

This is my basic code example to reproduce situation

export const CarouselExample = () => {
 const PAGE_WIDTH = SCREEN_WIDTH * 0.8
 const PAGE_HEIGHT = SCREEN_WIDTH / 2

 return (
   <Carousel
     loop={false}
     pagingEnabled
     width={PAGE_WIDTH}
     height={PAGE_HEIGHT}
     style={{ width: '100%' }}
     data={['red', 'green', 'red', 'green', 'red']}
     renderItem={({ item }) => (
       <View
         style={{
           marginLeft: 16,
           width: PAGE_WIDTH,
           height: PAGE_HEIGHT,
           backgroundColor: item,
         }}
       ></View>
     )}
   />
 )
}

Which gives me only this result and only left aligment

first slide (marginLeft=16) -> any center slide -> last slide (marginRight=?)
Screenshot 2024-01-26 at 16 05 51 Screenshot 2024-01-26 at 16 05 56 Screenshot 2024-01-26 at 16 06 03

According to design I need carousel component which works this way:

first slide (marginLeft=16) -> any center slide -> last slide (marginRight=16)
Screenshot 2024-01-26 at 16 05 51 Screenshot 2024-01-26 at 16 05 56 Screenshot 2024-01-26 at 16 12 52

I need the last item has the same margin from right side like first item from left side. According to examples I can set up only either left or right alignment by marginLeft or marginRight on item component. Moreover your example made by transform: [{ "rotateY": "-180deg" }] which is quite unuseful, changes swipe direction and resets opposite alignment.

So how can I implement that behaviour? Would be happy to get any clue from you guys. Is that possible at all?

PS. for understanding what I'm saying for example on FlatList it could be done by contentInset props

Copy link

dosubot bot commented Jan 26, 2024

🤖

Hey @ivankdev! Great to cross paths with you again. Hope you're doing well!

Based on the information available in the repository, it seems that the react-native-reanimated-carousel component does not directly support custom alignment properties for individual slides. However, you can achieve the desired effect by modifying the renderItem function.

You can add a condition to check if the current item is the first or the last one, and apply different styles accordingly. Here's how you can do it:

export const CarouselExample = () => {
  const PAGE_WIDTH = SCREEN_WIDTH * 0.8
  const PAGE_HEIGHT = SCREEN_WIDTH / 2
  const data = ['red', 'green', 'red', 'green', 'red'];

  return (
    <Carousel
      loop={false}
      pagingEnabled
      width={PAGE_WIDTH}
      height={PAGE_HEIGHT}
      style={{ width: '100%' }}
      data={data}
      renderItem={({ item, index }) => (
        <View
          style={{
            marginLeft: index === 0 ? 16 : 0,
            marginRight: index === data.length - 1 ? 16 : 0,
            width: PAGE_WIDTH,
            height: PAGE_HEIGHT,
            backgroundColor: item,
          }}
        ></View>
      )}
    />
  )
}

In this code, we're checking if the current item (index) is the first one (index === 0) or the last one (index === data.length - 1). If it's the first one, we're applying a 16px left margin, and if it's the last one, we're applying a 16px right margin. For all other items, we're not applying any margin.

This approach should give you the desired effect of having the first slide with a left margin and the last slide with a right margin. However, please note that this is a workaround and might not work perfectly in all scenarios, especially if you have a large number of slides or if the slides have different widths.

I hope this helps! If you have any other questions or need further clarification, feel free to ask.

Sources


This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.

Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

If you want to continue the conversation, start your reply with @dosu-bot.

@dosubot dosubot bot added the question Further information is requested label Jan 26, 2024
@ivankdev
Copy link
Author

ivankdev commented Jan 26, 2024

The point is that marginRight

marginRight: index === data.length - 1 ? -16 : 0,

doesn't affect component anyhow. And if I set up marginLeft only for first element

marginLeft: index === 0 ? 16 : 0,

I lose common left margin for whole carousel.

So question isn't resolved

Simulator.Screen.Recording.-.iPhone.15.-.2024-01-26.at.17.16.29.mp4

@ivankdev
Copy link
Author

cc @dohooo maybe you have any clues, thank you!

@ahsan-ey-k
Copy link

same question.

@ahsan-ey-k
Copy link

I want it to snap from both sides and deactive cards should show from both of the sides.

@ivankdev
Copy link
Author

ivankdev commented Jan 30, 2024

I want it to snap from both sides and deactive cards should show from both of the sides.

I've partially solved it by prop overscrollEnabled={false}, but I needed to play around Carousel style prop

 container: {
   width: SCREEN_WIDTH - CAROUSEL_HORIZONTAL_PADDING - CAROUSEL_CONTENT_SPACING,
   alignSelf: 'flex-start',
   overflow: 'visible', 
 },

Why partially? Because manually by finger it works. But position of last item is still incorrect when autoPlay={true} and loop={false}, when animation happens underthehood

@ivankdev ivankdev changed the title How to add both left and right alignment? How to add both left and right margins? Jan 30, 2024
@ivankdev ivankdev changed the title How to add both left and right margins? How to add both left and right margin? Jan 30, 2024
@ahsan-ey-k
Copy link

It is not working.

const topPicksCardsCarousal = {
width: SCREEN_WIDTH - 50 - 50
alignSelf: 'flex-start',
overflow: 'visible',

}

<Carousel
overscrollEnabled={false}
style={styles.topPicksCardsCarousal}
width={Dimen.width * 0.8}
height={440}
pagingEnabled={true}
snapEnabled={true}
mode={"horizontal-stack"}
loop={true}
autoPlay={false}
autoPlayReverse={false}
data={homeTopPicks}
renderItem={renderCard}
modeConfig={{
snapDirection: 'left',
}}
customConfig={() => ({ type: "positive", viewCount: 10 })} />

@ivankdev
Copy link
Author

@ahsan-ey-k I mean try to play around with your width, and review your renderItem style of item

@manuwebs
Copy link

HI @ivankdev, @ahsan-ey-k not sure if you solved your issue. But from the first example and desired behavior I could replicate the following

Screen.Recording.2024-02-16.at.2.20.54.AM.mov

The only modification I made to the code was basically on PAGE_WIDTH don't know why is just 80% (width * 0.8) but here it should be the amount of space you want to leave on the sides (32 in your case). Then just keep the marginLeft for all items in order to have the same size and spacing.

No issues with autoplay.

Here's the code:

const CarouselExample = () => {
  const PAGE_WIDTH = width - 32;
  const PAGE_HEIGHT = width / 2;

  return (
    <Carousel
      loop={false}
      autoPlay
      pagingEnabled
      width={PAGE_WIDTH}
      height={PAGE_HEIGHT}
      style={{ width: '100%' }}
      data={['red', 'green', 'pink', 'green', 'red']}
      renderItem={({ item }) => (
        <View
          style={{
            marginLeft: 16,
            width: PAGE_WIDTH,
            height: PAGE_HEIGHT,
            backgroundColor: item,
          }}
        />
      )}
    />
  );
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants