From a454f26c4e43e6e10553e40bcde458599c200aa6 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Mon, 3 Apr 2023 15:23:31 +0200 Subject: [PATCH] Improve fling animation (#963) Co-authored-by: Ovidiu Voda --- platform/android/CHANGELOG.md | 2 ++ .../src/cpp/native_map_view.cpp | 2 +- .../mapboxsdk/maps/MapGestureDetector.java | 16 +++++++++++----- .../com/mapbox/mapboxsdk/maps/UiSettings.java | 19 +++++++++++++++++++ 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md index 624955b07..ff7ac4fca 100644 --- a/platform/android/CHANGELOG.md +++ b/platform/android/CHANGELOG.md @@ -6,6 +6,8 @@ MapLibre welcomes participation and contributions from everyone. Please read [`C ### ✨ Features and improvements +* Change to a more natural fling animation and allow setting `flingThreshold` and `flingAnimationBaseTime` in `UiSettings` ([#963](https://github.com/maplibre/maplibre-gl-native/pull/963)) + ### 🐞 Bug fixes ### ⛵ Dependencies diff --git a/platform/android/MapboxGLAndroidSDK/src/cpp/native_map_view.cpp b/platform/android/MapboxGLAndroidSDK/src/cpp/native_map_view.cpp index b10c7cf90..a3da861d4 100644 --- a/platform/android/MapboxGLAndroidSDK/src/cpp/native_map_view.cpp +++ b/platform/android/MapboxGLAndroidSDK/src/cpp/native_map_view.cpp @@ -329,7 +329,7 @@ void NativeMapView::moveBy(jni::JNIEnv&, jni::jdouble dx, jni::jdouble dy, jni:: mbgl::AnimationOptions animationOptions; if (duration > 0) { animationOptions.duration.emplace(mbgl::Milliseconds(duration)); - animationOptions.easing.emplace(mbgl::util::UnitBezier {0.25, 0.46, 0.45, 0.94}); + animationOptions.easing.emplace(mbgl::util::UnitBezier {0.1, 0.4, 0.35, 1.0}); } map->moveBy({dx, dy}, animationOptions); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java index 0e41e6311..0f59cdf39 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java @@ -419,7 +419,7 @@ final class MapGestureDetector { // calculate velocity vector for xy dimensions, independent from screen size double velocityXY = Math.hypot(velocityX / screenDensity, velocityY / screenDensity); - if (velocityXY < MapboxConstants.VELOCITY_THRESHOLD_IGNORE_FLING) { + if (velocityXY < uiSettings.getFlingThreshold()) { // ignore short flings, these can occur when other gestures just have finished executing return false; } @@ -427,11 +427,17 @@ final class MapGestureDetector { // tilt results in a bigger translation, limiting input for #5281 double tilt = transform.getTilt(); double tiltFactor = 1.5 + ((tilt != 0) ? (tilt / 10) : 0); - double offsetX = velocityX / tiltFactor / screenDensity; - double offsetY = velocityY / tiltFactor / screenDensity; // calculate animation time based on displacement - long animationTime = (long) (velocityXY / 7 / tiltFactor + MapboxConstants.ANIMATION_DURATION_FLING_BASE); + long animationTime = (long) (velocityXY / 7 / tiltFactor + uiSettings.getFlingAnimationBaseTime()); + + // screenDensity and influcentcetilt come in here via animationTime + // factor 1000 because speed is in pixels/s + // and the factor 0.28 was determined by testing: panning the map and releasing + // should result in fling animation starting at same speed as the move before + double offsetX = velocityX * animationTime * 0.28 / 1000; + double offsetY = velocityY * animationTime * 0.28 / 1000; + if (!uiSettings.isHorizontalScrollGesturesEnabled()) { // determine if angle of fling is valid for performing a vertical fling double angle = Math.abs(Math.toDegrees(Math.atan(offsetX / offsetY))); @@ -1154,4 +1160,4 @@ final class MapGestureDetector { initializeGesturesManager(gesturesManager, setDefaultMutuallyExclusives); initializeGestureListeners(context, attachDefaultListeners); } -} \ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java index 1a4bbcc86..1836e667c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java @@ -83,6 +83,9 @@ public final class UiSettings { private boolean deselectMarkersOnTap = true; + private long flingAnimationBaseTime = MapboxConstants.ANIMATION_DURATION_FLING_BASE; + private long flingThreshold = MapboxConstants.VELOCITY_THRESHOLD_IGNORE_FLING; + @Nullable private PointF userProvidedFocalPoint; @@ -316,6 +319,22 @@ public final class UiSettings { savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_BOTTOM)); } + public long getFlingAnimationBaseTime() { + return flingAnimationBaseTime; + } + + public long getFlingThreshold() { + return flingThreshold; + } + + public void setFlingAnimationBaseTime(long t) { + flingAnimationBaseTime = t; + } + + public void setFlingThreshold(long t) { + flingThreshold = t; + } + /** *

* Enables or disables the compass. The compass is an icon on the map that indicates the