Svelte component register each finger as a separate touch event

Viewed 39

I have instances of a Svelte component inside a loop and I want to be able to slide the .box element of each Slider component independently with more than one fingers at the same time.

Here's a reduced version of the code (couldn't include it in a REPL): https://github.com/dtsmarin/svelteSOexample

EDIT: I think my use of svelte-motion here causes more problems than it solves. I'm in the process of replacing it with something simpler like Hammer.js. In any case If someone has got a solution I'm still interested.

1 Answers

The approach here should be to use pointer events which provide a pointerId that can be used to identify the finger. You can use capture functions to prevent interference between fingers and to keep sliding a slider until the finger is released, even if the finger accidentally left the slider's area during the interaction.

Example:

<script>
  let element;
  
  let capturedPointerId = null;
  let x = 0;
  let y = 0;

  function onPointerDown(e) {
    element.setPointerCapture(e.pointerId);
    capturedPointerId = e.pointerId;
  }
  function onPointerUp(e) {
    capturedPointerId = null;
    element.releasePointerCapture(e.pointerId);
  }
  function onPointerMove(e) {
    if (capturedPointerId != e.pointerId)
      return;

    e.preventDefault();
    e.stopPropagation();

    x += e.movementX;
    y += e.movementY;
  }
</script>

<div bind:this={element}
     on:pointerdown={onPointerDown}
     on:pointerup={onPointerUp}
     on:pointermove={onPointerMove}
     style:transform="translate({x}px, {y}px)">
  {capturedPointerId}
</div>

<style>
  div {
    /* This is important to prevent panning/zooming/reload gestures. */
    touch-action: none;
  }
</style>

REPL

Related