4

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
})
Chris
  • 833
  • 2
  • 17
  • 37
  • 1
    You may want to tag JavaScript to get the right eyes on this post. You could capture the touch start, touch move, and touch end events. If the total movement across those events is relatively small, you could treat it as a tap/click. – John Glenn Feb 01 '22 at 05:30
  • Hi John - thanks for the heads up. I updated the tags. How would that touch start, touch move, and touch end events look like? – Chris Feb 01 '22 at 17:06
  • 1
    In their demo, they uses HammerJS: https://github.com/bumbu/svg-pan-zoom/blob/master/demo/mobile.html – Clément Baconnier Feb 01 '22 at 17:08

1 Answers1

1

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 })

Umesh Thapa
  • 195
  • 1
  • 7
  • Hi Umesh! Thank you for looking at this. I ended up contacting the developer and he actually updated the script as seen here https://github.com/anvaka/panzoom/blob/master/demo/click-tap.html adding onClick(e). But your answer helped me in another issue I was having – Chris Feb 11 '22 at 18:45