Improve fling animation (#963)

Co-authored-by: Ovidiu Voda <ovi.voda@gmail.com>
This commit is contained in:
Helium314
2023-04-03 15:23:31 +02:00
committed by GitHub
parent 3a8f732be2
commit a454f26c4e
4 changed files with 33 additions and 6 deletions

View File

@@ -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

View File

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

View File

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

View File

@@ -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;
}
/**
* <p>
* Enables or disables the compass. The compass is an icon on the map that indicates the