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

usePinch receives duplicate events on Safari #681

Open
2 tasks done
andthom opened this issue Sep 7, 2024 · 1 comment
Open
2 tasks done

usePinch receives duplicate events on Safari #681

andthom opened this issue Sep 7, 2024 · 1 comment
Assignees

Comments

@andthom
Copy link

andthom commented Sep 7, 2024

Describe the bug

Every usePinch event seems to fire at least twice on Safari.

Example

  usePinch(
    (state) => {
      const { timeStamp } =
        state;
      console.log(timeStamp);
    },
    {
      target: yourTargetHere
    }
  );

...
return (
  <div
      ref={yourTargetHere}
      style={{ position: 'relative', touchAction: 'none' }}
    >
My component is in here.
  </div>
);

yields the following on Safari:

[Log] 4983.000000000001
[Log] 4983.000000000001
[Log] 4987
[Log] 4987
[Log] 4991.000000000001 
[Log] 4991.000000000001 
...

and the following on other browsers:

Firefox:
6836
6841
6844
6848

Chrome:
5586.60000000149
5594.89999999851
5607.39999999851
5611.5

Information:

  • Use Gesture version: @use-gesture/[email protected]
  • Device (OS): Macbook Pro 2016 (Monterey 12.7) and Macbook Pro 2023 (Sonoma 14.4)
  • Browser: Safari

Checklist:

  • I've read the documentation.
  • If this is an issue with drag, I've tried setting touch-action: none to the draggable element.
@andthom
Copy link
Author

andthom commented Sep 7, 2024

For posterity, here's how I've been coping. It's a bit janky. Admittedly, I could be foolish for not trusting it only ever to happen twice (returning timeStamp and comparing it to memo is the one-liner solution.)

Lmk if you have any ideas or, if it turns out this is by design, the proper way of dealing with it.

  const timestampSetRef = useRef<Set<number>>(new Set());

  const isRepeat = (n: number) => {
    const isRe = timestampSetRef.current.has(n);

    // Update the set manually
    timestampSetRef.current.add(n);

    // If the set exceeds 16 elements, remove the oldest one
    if (timestampSetRef.current.size > 16) {
      // Convert to an array, shift, and recreate the set
      timestampSetRef.current = new Set([...timestampSetRef.current].slice(1));
    }

    return isRe;
  };

Then in the handler:

  usePinch(
    (state) => {
      const { timeStamp } =
        state;

      if (isRepeat(timeStamp)) {
        return;
      }

      console.log(timeStamp + ' no more repeats.);
    },
    {
      target: yourTargetHere
    }
  );

Yields:

[Log] 890651.0000000001 no more repeats.
[Log] 890655 no more repeats.
[Log] 890663 no more repeats.
[Log] 890672 no more repeats.

@andthom andthom changed the title usePinch sends duplicate events on Safari usePinch receives duplicate events on Safari Sep 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants