From 9291106e0a3ea0edf1c1f45233677d8bffaac510 Mon Sep 17 00:00:00 2001 From: ishdemon Date: Sun, 26 Sep 2021 19:08:45 +0530 Subject: [PATCH] Fixed jerk animation while rotating marker due to wrong logic. Used MapsUtil's ComputeHeading() --- app/build.gradle | 1 + .../example/ubercaranimation/MainActivity.kt | 19 +++++++++++++++++-- .../ubercaranimation/util/AnimationUtils.kt | 2 +- build.gradle | 10 ++++------ gradle/wrapper/gradle-wrapper.properties | 2 +- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 5a9eb87..1c1f06a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -36,4 +36,5 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' // Google Map dependency implementation 'com.google.android.gms:play-services-maps:17.0.0' + implementation 'com.google.maps.android:maps-utils-ktx:3.2.0' } diff --git a/app/src/main/java/com/mindorks/example/ubercaranimation/MainActivity.kt b/app/src/main/java/com/mindorks/example/ubercaranimation/MainActivity.kt index dfa832e..59eb6d4 100644 --- a/app/src/main/java/com/mindorks/example/ubercaranimation/MainActivity.kt +++ b/app/src/main/java/com/mindorks/example/ubercaranimation/MainActivity.kt @@ -3,6 +3,7 @@ package com.mindorks.example.ubercaranimation import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.util.Log import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.google.android.gms.maps.CameraUpdateFactory @@ -10,6 +11,7 @@ import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.OnMapReadyCallback import com.google.android.gms.maps.SupportMapFragment import com.google.android.gms.maps.model.* +import com.google.maps.android.SphericalUtil import com.mindorks.example.ubercaranimation.util.AnimationUtils import com.mindorks.example.ubercaranimation.util.MapUtils @@ -23,6 +25,7 @@ class MainActivity : AppCompatActivity(), OnMapReadyCallback { private var blackPolyline: Polyline? = null private var movingCabMarker: Marker? = null private var previousLatLng: LatLng? = null + private var prevBearing: Double? = null private var currentLatLng: LatLng? = null private lateinit var handler: Handler private lateinit var runnable: Runnable @@ -114,8 +117,10 @@ class MainActivity : AppCompatActivity(), OnMapReadyCallback { movingCabMarker?.setAnchor(0.5f, 0.5f) animateCamera(currentLatLng!!) } else { + prevBearing = SphericalUtil.computeHeading(previousLatLng!!, currentLatLng!!) previousLatLng = currentLatLng currentLatLng = latLng + Log.wtf("PrevBearing:", "$prevBearing") val valueAnimator = AnimationUtils.carAnimator() valueAnimator.addUpdateListener { va -> if (currentLatLng != null && previousLatLng != null) { @@ -125,9 +130,19 @@ class MainActivity : AppCompatActivity(), OnMapReadyCallback { multiplier * currentLatLng!!.longitude + (1 - multiplier) * previousLatLng!!.longitude ) movingCabMarker?.position = nextLocation - val rotation = MapUtils.getRotation(previousLatLng!!, nextLocation) + + /*** Calculating the difference between bearings and only animating the diff value rotation, which removes the jerk + * Just make sure the next location update doesn't come before this valueAnimator ends, adjust the + * valueAnimator's duration less than the location update (animationDuration < UpdateInterval) */ + val offsetBearing = (SphericalUtil.computeHeading(previousLatLng!!,nextLocation) - prevBearing!!) + val rotation = prevBearing!! + multiplier * offsetBearing + Log.wtf("animated_bearing:", "$rotation") + + /***Non animated rotation but Jerk free, Uncomment below line & comment out the above 3 lines to use this */ + //val rotation = SphericalUtil.computeHeading(previousLatLng!!,currentLatLng) + if (!rotation.isNaN()) { - movingCabMarker?.rotation = rotation + movingCabMarker?.rotation = rotation.toFloat() } movingCabMarker?.setAnchor(0.5f, 0.5f) animateCamera(nextLocation) diff --git a/app/src/main/java/com/mindorks/example/ubercaranimation/util/AnimationUtils.kt b/app/src/main/java/com/mindorks/example/ubercaranimation/util/AnimationUtils.kt index a446a78..103eccc 100644 --- a/app/src/main/java/com/mindorks/example/ubercaranimation/util/AnimationUtils.kt +++ b/app/src/main/java/com/mindorks/example/ubercaranimation/util/AnimationUtils.kt @@ -14,7 +14,7 @@ object AnimationUtils { fun carAnimator(): ValueAnimator { val valueAnimator = ValueAnimator.ofFloat(0f, 1f) - valueAnimator.duration = 3000 + valueAnimator.duration = 2000 valueAnimator.interpolator = LinearInterpolator() return valueAnimator } diff --git a/build.gradle b/build.gradle index 991db60..ed4f6ca 100644 --- a/build.gradle +++ b/build.gradle @@ -1,14 +1,13 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.3.71' + ext.kotlin_version = '1.5.30' repositories { google() - jcenter() - + mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:3.6.1' + classpath 'com.android.tools.build:gradle:7.0.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong @@ -19,8 +18,7 @@ buildscript { allprojects { repositories { google() - jcenter() - + mavenCentral() } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c2979f1..c2a846d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip