BetterTyped/react-zoom-pan-pinch

How to disable the click event when drag & drop

EkaLinMan opened this issue · 5 comments

There is a demo that we can trigger the click event when we click the button, is there any way to prevent triggering the click event when drag & drop (Pan) on the button? Because my view is clickable everywhere, I hope to disable it when executing the drag & drop. Thanks!

https://bettertyped.github.io/react-zoom-pan-pinch/?path=/story/examples-controls--controls
image

Add delay to click

I have the same problem but I don't understand the solution "Add delay to click". Can you provide an example @acai69 ? Thanks!

I solved it for now by measuring the length between the mouseDown and mouseUp and preventing the click if this is longer than 250ms (kind of arbitrary). But ideally this click event is not triggered at all imho.

and preventing the click if this is longer than 250ms

That's it!

mind sharing your example? I have the exact same issue. I have a map with clickable sections, but on double click, the click is triggered. same when panning

just in case someone lands here, this is not for the panning situation above, but for a double click on a clickable item while zooming.

import { useEffect, useRef } from 'react'

/**
 * Custom React hook that handles canceling click events based on a specified time threshold.
 *
 * @param callback A function to be called when the click event is not canceled
 * @returns A function to handle click events and cancel them if they occur within a short time interval
 */
export const useCancelClick = (
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  callback: (event: React.MouseEvent<any>) => void
) => {
  const timeout = useRef<NodeJS.Timeout | null>(null)
  const timeStamp = useRef<null | number>(null)

  const cancelClick = () => {
    if (timeout.current) {
      clearTimeout(timeout.current)
    }
    timeStamp.current = null
  }

  const handleClick = (event: React.MouseEvent) => {
    const evt = event
    if (timeStamp.current) {
      console.log('difference', evt.timeStamp - timeStamp.current)
    }
    if (timeStamp.current && evt.timeStamp - timeStamp.current < 200) {
      cancelClick()
      return
    }
    timeStamp.current = evt.timeStamp
    timeout.current = setTimeout(() => {
      cancelClick()

      callback(evt)
    }, 200)
  }

  useEffect(() => {
    return () => {
      cancelClick()
    }
  }, [])

  return handleClick
}

thoughts?