sveltemulti-touch

Svelte component register each finger as a separate touch event


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.


Solution

  • 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