New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Gestures update - two finger rotation / interactions filter / map events #719
Conversation
setIcon(Icons.gps_fixed); | ||
|
||
mapEventSubscription = mapEventStream.listen((MapEvent event) { | ||
if (event is MapEventMove && event.id == _eventKey) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is overkill to listen the stream but here is the example which checks event's id so it's safe to say it's coming from us rather than assume the first move was our one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How can we differentiate between move start and end events? Also, is there a way to dfferantiate among rotate/pan/zoom/double tap zoom? These would be super helpful if you could add them in your PR:D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can check map_events it is still not documented but you can distinguish events forinstance MapEventRotateStart
will be fired when map starts to rotate (when rotationThreshold
is reached the default can be changed in MapOptions
) and while rotating MapEventRotate
will be fired continuously and when rotation ends then MapEventRotateEnd
will be fired.
Example:
@override
void initState() {
super.initState();
mapController = MapController();
mapController.onReady.then((_) {
// at this point we can safely listen to [mapEventStream]
// use stream transformer or anything you want
subscription = mapController.mapEventStream.listen((MapEvent mapEvent) {
if (mapEvent is MapEventRotateStart) {
// do something
} else if (mapEvent is MapEventFlingEnd ) {
// do something
}
});
});
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the clear example. I didn't see map_events before now it all makes sense. By the way I am a little confused with this scenario: User can easily both pan zoom at the same time. In this case what events will be emitted?
MapEventMoveStart
MapEventRotateStart
...
MapEventMove
MapEventRotate
MapEventMove
MapEventRotate
MapEventMove
MapEventRotate
...
MapEventMoveEnd
MapEventRotateEnd
Something like this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Zoom
and move
are same event. You can read zoom
which was the zoom when event is emmited
and there is a targetZoom
property too. So if zoom != targetZoom
then zoom has been changed you can compare center
and targetCenter
too. Maybe there should be a getter which tells the same so it can be used like this: if (event is MapEventMove && event.isZoomChanged)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok if zoom and move are considered same, let me ask the same question with zoom+rotate? Do we need that extra getter in that case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If only pinchZoom
and rotation
are enabled then if only rotation happens then MapEventMove
won't be fired (but it is almost impossible to do that with fingers).
I think I'll implement zoom threshold too, so rotation and zoom can race. I mean user won't able to rotate and zoom at same time at least Google maps work this way.
There was some bug with rotation it has been fixed |
Arbitrary jumps fixed. |
This PR still has problems, for example: For a longer time (like 10 days) I'm going to take a nap so I cannot update this PR. |
In leaflet, you can disable the map dragging, and in this case you still can move the map using a pinch (the pinch allows zoom + move). It's useful when you zoom/unzoom to recenter. Maybe the "move" flag is too restrictive : it might be changed to "dragging" (like in leaflet), allowing the move during a pinch. flutter_map/lib/src/gestures/gestures.dart Lines 145 to 162 in 08e22d5
|
@christophemacabiau that's a good point. Next week I'll able to update PR. And |
Hi @maRci002 , Thanks for your work. |
@christophemacabiau maybe it is a good idea, however stream is async (I think this isn't problem) and maybe someone wants more info than Maybe for this task adding funcation listeners to |
Thanks @maRci002 for your hint. I am somewhat lost in the coordinates spaces used. In handleScaleUpdate I need the touch event coordinates in the default CRS (3857). There is something I missed, can you give me some hint please? |
Yes it is relative to top left corner (note: in current implementation the GestureDetector itself isn't rotated and enlarged so now you can tap 0-0 position, but in handleScaleUpdate we have to play with rotation)
|
Hi! Is there any news? |
Hello, is there anymore news on this pull request, or is it dead? |
Y'all can use it already by adding this PR to dependencies:
flutter:
sdk: flutter
...
flutter_map:
git:
url: git://github.com/maRci002/flutter_map.git
ref: feature/gesture-update Dragging when map is rotated works flawlessly! |
Hello, this PR adds two finger
rotation support
, the map will fire events, and gives opportunity to disable / mix interactions.For instance you can move map only with fling events or enable only zoom / rotation interactions if GPS is on (I updated some examples, i.e.
LiveLocationPage
).There are a lot of issues which ask for
onMoveStart
/onMoveEnd callbacks
, just listen tomapEventStream
and filter these events (MapEventMoveStart
/MapEventMoveEnd
), however take care becauseMap may use fling animation
if the velocity is high enough so the final location will be different fromMapEventMoveEnd
's targetLocation, so there are two options:MapEventFlingEnd
andMapEventFlingNotStarted
It is possible there is an ongoing fling animation (or double tap zoom animation) and flags updated during the animation so basicly the new flags don't contain any fling flag, then
MapEventFlingEnd
will be emitted, this behavior can be distinguished easily from normal fling end event by checking theevent's source
, in normal case source isMapEventSource.flingAnimationController
.Added an example page where these interaction filters can be tried and map events are listened.
closes #148
closes #701
closes #361
closes #498
closes #396
closes #723
closes #736