Leaflet: Dragging issue with ionic2

Created on 20 May 2016  路  18Comments  路  Source: Leaflet/Leaflet

Hey guys,

I just set up a clean ionic2 beta7 TypeScript project and added leaflet (latest master + rc1) but got some really strange issues while dragging.

I captured my screen: https://paste.xinu.at/KISMRj/

(old: https://paste.xinu.at/YRO9/ )

And here's the code: https://paste.xinu.at/MQm2gI/js

I'm not sure if its a leaflet or ionic2 issue =/

Most helpful comment

Thanks @jordane51. With your example I was able to figure out what is happening.

The map's move animation (in L.PosAnimation) uses the browser's window.requestAnimationFrame function. When the animation is finished, it calls window.cancelAnimationFrame. I noticed that even after calling cancelAnimationFrame, the map's animation never stops playing. Leaflet has a protection so that the animation always stops at the desired endpoint. So what's happening is, as you drag, the prior animation is still ongoing, and it keeps resetting you back to where that animation was supposed to end.

Reason:
Angular uses a library called zone.js that overrides the browser's requestAnimationFrame and cancelAnimationFrame functions. The problem is, their implementation of cancelAnimationFrame is broken! This is a known bug with Angular/zone.js: https://github.com/angular/zone.js/issues/326

Your options:

  1. Disable animation for now using the animate option.
  2. Fix zone.js yourself. See my proposed change on their issue. I'm surprised this very serious bug has not been addressed yet. You can try to get this escalated with them.

All 18 comments

Hi,

Unfortunately this is not enough for a proper bug report - "really strange issue" doesn't describe the problem, I don't see anything weird in your screencap, and unless we can reproduce the bug _outside an ionic project_, we won't be able to diagnose and fix it.

Hello Ivan,

for example seconds 16 to seconds 20. You can see that the screen is being repositioned to where the drag started. I didnt release the mouse.

/Edit/

I updated the screencast to a more focusing one: https://paste.xinu.at/KISMRj/

What's a _reproducible_ _exact sequence of actions_ that triggers such a behaviour? Are you moving the pointer outside of the map area? Are all mouse events being correctly propagated through ionic into leaflet?

The flickering is caused while moving and holding the pointer (_dragging_). The repositioning is caused right after I release the pointer (_dragend_).

This does not happen at the first drag. It can be reproduced at 2nd (sometimes 3rd) drag.

The issue has nothing to do with the border of the map area. I can reproduce it staying inside of the map area.

A more or less exact sequence would be:

  1. Drag (start, drag, release) the map for the first time.
  2. Start dragging the map from left to right without releasing
  3. Move the pointer just a little bit after reaching your destination. You will see flickering now.
  4. Release the pointer. You will be repositioned to your origin.
  5. Restart at 2 if flickering/repositioning does not happen.

How can I check your last point?

I'm having the same problem, the only thing i can add is that the issue doesn't happen using leaflet 0.7.7.

To narrow this down, you need to illustrate that this is reproducible in a browser just using Leaflet.

If it's not reproducible, the problem is with Ionic, or whatever you need to integrate Leaflet into Ionic, which is outside the scope of the Leaflet project. If it _is_ reproducible in a browser with just Leaflet, it's a bug we can work with.

From Ionic's doc on their custom tap system:

"In some cases, third-party libraries may also be working with touch events which can interfere with the tap system. For example, mapping libraries like Google or Leaflet Maps often implement a touch detection system which conflicts with Ionic鈥檚 tap system."
http://ionicframework.com/docs/api/page/tap/

Wait, is this the old "disable the L.Map.Tap handler when using a touch UI library" bug all over again?

I see you added the data-tap-disabled="true" attribute, but even with this setting, other developers have still encountered Ionic-related event problems (here and here for example). These issues deal with tapping rather than clicking, so your issue may be only tangentially related.

Try 0.7.7 as @jordane51 mentioned and let us know. Try disabling Leaflet's own tap hack as @IvanSanchez mentioned.

If you can get your page onto the Web I can take a look, and maybe there is something that can be improved on the Leaflet side to prevent this class of compatibility issues. But as others have stated you will probably find more success asking Ionic people at https://forum.ionicframework.com/.

Setting tap: false in the MapOptions didn't do the trick. data-tap-disabled="true"has no effect either.

@jwoyame I will put my application tomorrow on my server so you can take a look :)

@all: Maybe this is the fix: https://github.com/driftyco/ionic/commit/88b377724a8f5dd46c367d40b77b03fcc5abac71

@jwoyame @kaynz I've uploaded an example here. What's weird is that if i scroll slowly it works fine. Setting tap: false didn't work for me either.

Thanks @jordane51. With your example I was able to figure out what is happening.

The map's move animation (in L.PosAnimation) uses the browser's window.requestAnimationFrame function. When the animation is finished, it calls window.cancelAnimationFrame. I noticed that even after calling cancelAnimationFrame, the map's animation never stops playing. Leaflet has a protection so that the animation always stops at the desired endpoint. So what's happening is, as you drag, the prior animation is still ongoing, and it keeps resetting you back to where that animation was supposed to end.

Reason:
Angular uses a library called zone.js that overrides the browser's requestAnimationFrame and cancelAnimationFrame functions. The problem is, their implementation of cancelAnimationFrame is broken! This is a known bug with Angular/zone.js: https://github.com/angular/zone.js/issues/326

Your options:

  1. Disable animation for now using the animate option.
  2. Fix zone.js yourself. See my proposed change on their issue. I'm surprised this very serious bug has not been addressed yet. You can try to get this escalated with them.

@jwoyame Thanks! :)

Given this is the result of a broken implementation of requestAnimationFrame/cancelAnimationFrame, I'm closing this.

@jwoyame Wow, thanks for the detailed analysis!!

Thank @tom5760 for the fix! I just learned yesterday that zone.js existed, I didn't feel comfortable fixing it myself.

No problem @jwoyame, I'm not very familiar with zone.js, but I just implemented the fix you suggested! After testing it, it seems to have fixed the same issue I was having (Leaflet in Angular 2).

Your fix did work here too, thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ssured picture ssured  路  3Comments

CallMarl picture CallMarl  路  3Comments

piehei picture piehei  路  3Comments

jcarenza picture jcarenza  路  3Comments

timwis picture timwis  路  3Comments