Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Animate MarkerView from current to another position #5242

Closed
tobrun opened this issue Jun 5, 2016 · 9 comments
Closed

Animate MarkerView from current to another position #5242

tobrun opened this issue Jun 5, 2016 · 9 comments
Labels
Android Mapbox Maps SDK for Android annotations Annotations on iOS and macOS or markers on Android

Comments

@tobrun
Copy link
Member

tobrun commented Jun 5, 2016

When we currently call setPosition on MarkerView the position changes immediately. It would be nice to support a similar feature as with setRotation and setAlpha to perform an Android SDK animation when the position changes.

Animating LatLng values

One approach for this is what we use in AnimatedMarkerActivity:

  final Marker marker = mapboxMap.addMarker(new MarkerOptions().position(brussels));
  ValueAnimator markerAnimator = ValueAnimator.ofObject(new LatLngEvaluator(), (Object[]) new LatLng[]{brussels, washington});
   markerAnimator.setDuration(5000);
  markerAnimator.setRepeatCount(ValueAnimator.INFINITE);
  markerAnimator.setRepeatMode(ValueAnimator.REVERSE);
  markerAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
  markerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
          @Override
          public void onAnimationUpdate(ValueAnimator animation) {
              if (marker != null) {
                 marker.setPosition((LatLng) animation.getAnimatedValue());
              }
           }
  });
  markerAnimator.start();

  private class LatLngEvaluator implements TypeEvaluator<LatLng> {

        private LatLng mLatLng = new LatLng();

        @Override
        public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
            mLatLng.setLatitude(startValue.getLatitude() + (endValue.getLatitude() - startValue.getLatitude()) * fraction);
            mLatLng.setLongitude(startValue.getLongitude() + (endValue.getLongitude() - startValue.getLongitude()) * fraction);
            return mLatLng;
        }
    }

While this works, it's not resulting in an smooth animation because the marker needs to go through jni for each update. I have been profiling the code the related code to make it run smooth but at this point, after doing a couple of improvements, I'm not sure if we will ever get the right UX.

Animating Pixel Coordinate values

Another approach is to use pixel coordinates instead of the LatLng coordinates above. This has the benefit that we don't need to pass through JNI to get the correct pixel coordinate value for each animation update but has the downside that we need to manage camera changes manually.

@tobrun tobrun added Android Mapbox Maps SDK for Android annotations Annotations on iOS and macOS or markers on Android labels Jun 5, 2016
@tobrun tobrun added this to the android-v4.2.0 milestone Jun 5, 2016
@tobrun tobrun modified the milestones: android-v4.1.0, android-v4.2.0 Jun 13, 2016
@tobrun
Copy link
Member Author

tobrun commented Jun 14, 2016

I have been working on Animating Pixel Coordinate values today and was able to get a rough version of it in place. I'm going to revisit this implementation tomorrow and see if it fulfils the use-case we envision it to do.

@tobrun
Copy link
Member Author

tobrun commented Jun 16, 2016

This is the Animating Pixel coordinate example:

ezgif com-video-to-gif 1

The most difficult to this approach is restoring the animation after the map changes:

  • Pan gesture:
    • ezgif com-video-to-gif 3
  • Zoom gesture:
    • ezgif com-video-to-gif 4

@tobrun
Copy link
Member Author

tobrun commented Jun 16, 2016

I'm now trying to solve some edge cases. One example of an edge case is panning a MarkerView out of bounds which will result in removing the MarkerView for caching purposes. This conflicts with doing an animation to a location that is visible on screen. Animating markers as a result should not be cached when we are animating them.

@tobrun
Copy link
Member Author

tobrun commented Jun 16, 2016

Views that aren't been animated will not be cached by the system.
This resolves this issue mentioned above.

ezgif com-video-to-gif 5

@tobrun
Copy link
Member Author

tobrun commented Jun 16, 2016

One issue that is not solved with this use-case is animating the position of a ViewMarker that is found outside the map:

ezgif com-video-to-gif 6

While I feel this is a bug and should be solved. I'm not sure that current timings will allow fixing this. As a work around users could animate from a certain LatLng on the edge of Map. We should look into making MarkerView caching optional.

@tobrun
Copy link
Member Author

tobrun commented Jun 16, 2016

Another issue is animating on map start when we receive the onMapReady callback + add a ViewMarker. When this occurs we need to wait for the ViewMarker to be added before executing any animations. Current workaround is:

                final MarkerView marker = mapboxMap.addMarker(new MarkerViewOptions().position(brussels));
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        marker.setPosition(utrecht, true);
                    }
                }, 1000);

@tobrun
Copy link
Member Author

tobrun commented Jun 17, 2016

We are looking at improving the performance of mbgl::updatePointAnnotation in #5385.

@tobrun
Copy link
Member Author

tobrun commented Jun 17, 2016

Since we are currently pointing on first approach that was already in place but fixed in ##5385 -> closing

@Yogesh9900
Copy link

But I want to move multiple markers at a time. Like a Uber. How should I do that. Can you please help me with this?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Android Mapbox Maps SDK for Android annotations Annotations on iOS and macOS or markers on Android
Projects
None yet
Development

No branches or pull requests

2 participants