hammerjs / hammer.js

A javascript library for multi-touch gestures :// You can touch this
http://hammerjs.github.io
MIT License
24.11k stars 2.63k forks source link

Pinch events *always* block scrolling, can we make it optional? #691

Open lostPixels opened 10 years ago

lostPixels commented 10 years ago

I've added the below code to my project, and it seems to automatically block scrolling over that element. This is not ideal, the element takes up a lot of real-estate and this breaks the UX.

myElement.get('pinch').set({ enable: true });

Ideally scrolling would only be blocked if the touches.length > 1.

ricogallo commented 10 years ago

Having the same issue here

danlbob commented 10 years ago

Same here. Would be nice to have scroll blocking only on touches.length > 1.

lostPixels commented 10 years ago

^ That was what I ultimately had to do. Basically, on touchstart, see if there were more than two fingers on the screen, then set that attribute to true. On touchend, I would then set it to false. This gave me the functionality I needed, but it seemed to be kind of hacky.

ricogallo commented 10 years ago

Also, I noticed that on iPad that code disables totally the selection, even if I apply

delete Hammer.defaults.cssProps.userSelect;

before instantiating my element.

danlbob commented 10 years ago

Thanks @lostPixels. Not a bad idea. Would you mind posting a code snippet?

lostPixels commented 10 years ago

Certainly. This is a quick copy/paste from my project, hopefully it gives you an idea of how I accomplished it. Note that I used the Hammer.js Jquery plugin, which of course adds another layer of complexity.

this.$hammer = $('img').hammer();
this.$hammer.on('touchstart', fingerDown)
    .on('touchend', fingerUp)
    .on('pinch', setScale);

function fingerDown(e) {

    var fingersDown = e.originalEvent.touches.length;

    if (this.activeFingers > 1) {
        // Lock Scrolling over the zoom element by allowing Hammer.js to fire pinch events.
        toggleHammerScrolling(true);
    }
}

function fingerUp(e) {
    toggleHammerScrolling(false);
}

function toggleHammerScrolling(shouldScroll){
   //This is where your implementation may change. Just do .get('pinch').set... on your own hammer object.
    this.$hammer.data('hammer').get('pinch').set({
        enable: shouldScroll
    });
}

function setScale(){
  console.log('do pinching stuff here');
}
danlbob commented 10 years ago

Thanks a bunch!

robtarr commented 9 years ago

@lostPixels Did your solution end up working? I tried it, and it's allowing scroll, but the pinch event never fires.

lostPixels commented 9 years ago

@robtarr This did work in my use case. I'd verify that you're successfully toggling the pinch enable, which should block scrolling.

julkue commented 8 years ago

@lostPixels For what is this fingersDown variable?

julkue commented 8 years ago

@lostPixels I found another answer from you on Stackoverflow. Here you are using the fingersdown variable. So in your above code this.activeFingers should be replaced with fingersDown. This worked for me.

However, with this fix I'm experiencing issues when allowing the scroll:

<meta name="viewport" content="width=device-width, initial-scale=1" />

I am not able to zoom in.

runspired commented 8 years ago

There's also a patch on master that unblocks where there's only one touch.

LabiKyo commented 8 years ago

+1, unblocks where there's only one touch make sense, when will the patch release?

runspired commented 8 years ago

@LabiKyo patch is in 2.0.6 which released a while ago

fedyd commented 7 years ago

Hi, I am using 2.08 only for the pinch event, but if I enable pinch recognizer, default scroll is locked (tried with Firefox on Android 4 and Safari on Ipad2). Is this normal? Have I also to add hammer.js pan recognizer and use it in order to scroll? Thank you, Federico

exedriver commented 7 years ago

I have the same problem as @fedyd , any solutions?

In my application, I have some responsive cards with an background image, which can be viewed in fullscreen if pinchout over it. But if I activate pinch on that element, I am not able to scroll the page when I start scrolling on the pinchable item itself. The cards fill a lot of space of the screen, so with this bug my application is totally broken and not usable. Hope anyone has an idea - thanks a lot!

skyqrose commented 6 years ago

I'm using 2.0.8 and having pinch enabled still blocks scrolling. I'm not sure why, given the patch that was mentioned upthread.

I also couldn't get hammer's touchstart and touchend handlers working, (were they removed?) so I adapted the above solution to use addEventListener instead.

  const mainElem = document.querySelector("main");
  var hammer = new Hammer(mainElem);
  mainElem.addEventListener("touchstart", function(event) {
    if (event.touches.length >= 2) {
      hammer.get("pinch").set({ enable: true });
    }
  });
  mainElem.addEventListener("touchend", function(event) {
    if (event.touches.length < 2) {
      hammer.get("pinch").set({ enable: false });
    }
  });
  hammer.on("pinch", function(event) {
    console.log("pinch");
    console.log(event);
  });

Hope this helps future viewers of this thread. :)

sgbj commented 5 years ago

I'm also using 2.0.8 and ran into this issue, but I resolved it by using the touchAction property.

var hammer = new Hammer(element, { touchAction: 'pan-x pan-y' });

hammer.get('pinch').set({ enable: true });

hammer.on('pinch', function(event) {
  console.log(event);
});