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

Distinguish between horizontal and vertical swiping #739

Open
Vimiso opened this issue Dec 3, 2024 · 2 comments
Open

Distinguish between horizontal and vertical swiping #739

Vimiso opened this issue Dec 3, 2024 · 2 comments
Assignees
Labels
enhancement New feature or request

Comments

@Vimiso
Copy link

Vimiso commented Dec 3, 2024

Description:
Enable carousel components to exclusively respond to horizontal swipes while ignoring vertical swipes. This ensures that swiping up or down on a carousel allows the parent page to scroll as expected, providing a smoother user experience.

Use Case:
When a carousel occupies a significant portion of a page, users must awkwardly avoid it to scroll down the page. This is particularly noticeable on mobile devices, where vertical scrolling is the primary method of navigation. Allowing vertical swipes to pass through to the parent view while maintaining horizontal swipe functionality for the carousel would resolve this issue.

Proposed Solution:
Filter gestures based on the swipe's direction.
Horizontal swipes (gesture.dx > gesture.dy): Trigger the carousel.
Vertical swipes (gesture.dy > gesture.dx): Pass through to the parent view for page scrolling.

Example:

<Carousel
  ignoreVerticalGestures={ true } // Carousel only responds to horizontal swipes
  { ...props }
/>

Backwards Compatibility:
Default behavior should remain the same (both directions interact with the carousel) unless explicitly enabled via the new prop.

Impact:
Improving gesture handling would enhance user experience in common layouts with multiple carousels and vertical scrolling. This functionality would be especially impactful on mobile, where space and gestures are at a premium.

@Vimiso Vimiso added the enhancement New feature or request label Dec 3, 2024
@Vimiso
Copy link
Author

Vimiso commented Dec 14, 2024

UPDATE: assuming your app is wrapped in GestureHandlerRootView, looks like this can be achieved like so:

<Carousel
  ref={ ref }
  loop={ true }
  data={ data }
  onProgressChange={ progress }
  onConfigurePanGesture={ (panGesture) => {
    // Defines a dead zone for horizontal swipes. It ensures a swipe must exceed a
    // threshold in either direction to trigger a carousel scroll. It also allows
    // vertical scrolling, as minor horizontal movements within will be ignored.
    panGesture.activeOffsetX([-10, 10])
  } }
  width={ width }
  height={ height }
  style={{ width: '100%' }}
  renderItem={ renderItem }
/>

Not sure this is the correct approach, but seems to work pretty well. Tested on web, ios and android. Even inside a scroll view. All attempts to disable the carousel and implement custom gestures ended in headaches, like conflicts between vertical and horizontal scrolling or the carousel would skip multiple pagination slides at a time.

@nirajniroula
Copy link

Assuming that your carousel (horizontal scrolling) is wrapped inside a vertical parent scroll view, one way to make the carousel ignore the vertical gestures could be:

const ScreenA: React.FC<ScreenAProps> = () => {

  const scrollViewRef = useRef<ScrollView>(null);

  const disableParentScroll = () => {
    if (scrollViewRef.current) {
      scrollViewRef.current.setNativeProps({ scrollEnabled: false });
    }
  };

  const enableParentScroll = () => {
    if (scrollViewRef.current) {
      scrollViewRef.current.setNativeProps({ scrollEnabled: true });
    }
  };

  return (
    <ScrollView
      ref={scrollViewRef}
    >
      {/* Carousel */}
        <Carousel
          //Trigger disabling and enabling of the parent scroll during carousel interaction.
          onScrollBegin={() => disableParentScroll()}
          onScrollEnd={() => enableParentScroll()}
          ... other props
        />

      {/* Rest of the content */}
    </ScrollView>
  );
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants