Search code examples
javascriptjquerysvgpanzoompanzoom

PanZoom catch Touch Up event


I am using Panzoom JS to zoom in on a map. It is working just the way I need it for zooming in and out on mobile and desktop. When you click on an item on the map, I grab the x/y coordinates relative to the top left of the container taking into account any scale applied, then look up that location/page in the database and open it. This all works great on desktop, but not on touch. I need to be able to catch the touch up location (just as if you'd clicked with a mouse) but only if there was no touch move, so I can distinguish between a pan/move, a pinch/zoom and a tap/touch-up (click). I can't find any documentation to work this out. Any help would be appreciated.

const elem = document.getElementById('map_inner_cont')
    
window.panzoom = panzoom(elem, {
        zoomDoubleClickSpeed: 1,
        autocenter  : true,
        bounds      : true,
        initialZoom : 0.2,
        animate     : true,
        maxZoom     : 2
})

Solution

  • Interesting, digging into panzoom a little, I can see you're managing three different sets of events:

    var events;
    if (typeof window.PointerEvent === 'function') {
        events = {
            down: 'pointerdown',
            move: 'pointermove',
            up: 'pointerup pointerleave pointercancel'
        };
    }
    else if (typeof window.TouchEvent === 'function') {
        events = {
            down: 'touchstart',
            move: 'touchmove',
            up: 'touchend touchcancel'
        };
    }
    else {
        events = {
            down: 'mousedown',
            move: 'mousemove',
            up: 'mouseup mouseleave'
        };
    }
    

    And my guess is that event.preventDefault() for pointerdown doesn't affect click, whereas touchstart on an older device would, and that's why we're seeing different behavior.

    My temptation is to use this same block used above to change what type of event we're listening for so the propagation is the same, but that seems a little fragile.

    I'd prefer that panzoom would optionally pass click-like events down as clicks to its children, perhaps? I could try creating a PR around that, if that makes sense.

    e.g. Panzoom({ propagateClicks: true })