0

I've created a carousel using the drag gesture in Framer, each slide contains a video component and some text. Is there a way to have a drag gesture on the entire carousel track but excluding the video components in each slide even though it's a child element.

When a user tries to drag the container over the video, it still does the drag gesture but also plays the video at the same time as it picks up the pointer down event as a onDragStart and onClick event. How could I separate the two, so that the video isn't draggable but only clickable?

I've tried having a isDragging state which updates onDragStart, then disabling the onClick when it updates to true, which works sometimes but not others.

1 Answers1

0

I found a work around here. A resolution is to remove the default drag listener and manually start or stop the animation based on event target. Honestly thought Framer would have a built in dragControls.cancel function but unfortunately not.

I still have it starting on a pointerDown event on the whole container but if at any stage the target clicked is the video player inside then it cancels the event. Just added a className of "no-drag" to any child element I don't want draggable.

  const dragControls = useDragControls();

  const onDragStart = (event, info) => {
    if (!event.target.classList.contains("no-drag")) {
      dragControls.start(event);
    } else {
      dragControls.componentControls.forEach((entry) => {
        entry.stop(event, info);
      });
    }
  };
  
  <Wrapper>
      <StyledTrack
        ref={trackRef}
        animate={controls}
        drag="x"
        dragConstraints={{
          left: windowWidth - trackDimensions.innerWidth,
          right: 0,
        }}
        dragControls={dragControls}
        onPointerDown={onDragStart}
        onDragEnd={onDragEnd}
        dragListener={false}
        style={{ x }}
      >
        {children}
      </StyledTrack>
  </Wrapper>