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

Mapbox Animating Camera #9808

Open
d-prukop opened this issue Aug 18, 2017 · 19 comments
Open

Mapbox Animating Camera #9808

d-prukop opened this issue Aug 18, 2017 · 19 comments
Labels
Core The cross-platform C++ core, aka mbgl feature gl-ios iOS Mapbox Maps SDK for iOS navigation For the Mapbox Navigation SDK for Android or iOS or navigation use cases in general Qt Mapbox Maps SDK for Qt, aka Qt Location Mapbox GL

Comments

@d-prukop
Copy link
Contributor

This is a ticket to track the discussion around implementing a new camera system for the various platforms.

The goal is to provide a camera system that allows independent animations to run on each of the map camera parameters. It should use a familiar API's for each of the platforms. This will give developers and designers the ability to have total control of the experience. It will also allow for the easy use of plug-in camera animation libraries and physics simulations for those who want to use certain styles of animation.

Further down the line, we should be able to introduce design tools for crafting animations and sharing those creations.

Some background and prior thinking:
“Fresh new camera”: mapbox/mapbox-gl-js#3583
“Concurrent Transition Animations”: #3625
“Reimplement camera transitions with Core Animation”: #8176

The new camera system will be able to animate each of the following parameters on independent timelines:

  • center coordinate
  • zoom level
  • bearing
  • pitch
  • anchor
  • roll ?? (yes!!??)

Animations will be handled on the various platforms and committed to the core with the frequency (or frame rate) controlled by the platform.

cc @mapbox/gl @pveugen

@d-prukop d-prukop added Android Mapbox Maps SDK for Android Core The cross-platform C++ core, aka mbgl feature iOS Mapbox Maps SDK for iOS navigation For the Mapbox Navigation SDK for Android or iOS or navigation use cases in general Qt Mapbox Maps SDK for Qt, aka Qt Location Mapbox GL labels Aug 18, 2017
@d-prukop
Copy link
Contributor Author

@jfirebaugh Can we figure out a way to prefetch tiles using the platform based animations?

@1ec5
Copy link
Contributor

1ec5 commented Aug 18, 2017

mbgl currently treats anchor as a frame of reference for zoom and angle, but not as a degree of freedom in its own right. (Similarly, padding affects the frame of reference for center.) Would you suggest turning it into an animatable degree of freedom? What are the tradeoffs?

@d-prukop
Copy link
Contributor Author

I'm thinking of anchor as an animatable parameter. Setting this explicitly has been the easiest way to control the effect. I haven't given much thought to the tradeoffs of setting this implicitly.

@1ec5
Copy link
Contributor

1ec5 commented Aug 18, 2017

Currently, to change the camera’s padding (as the user perceives it), you’d need to reapply the current center coordinate with the new padding. The anchor is often provided by gesture recognizers (to be under the mouse cursor) when specifying a camera to animate to, but if you ask the map for its current anchor, you’ll always get an unset value. In this sense, anchor could just as well have been a member of AnimationOptions instead of CameraOptions.

If we were to keep the current anchor implementation but allow for concurrent animations, the developer would for instance ease to a camera with a new anchor value, and any subsequent animation frames would have to account for that anchor when computing the center coordinate. On the other hand, if we turn anchor into its own degree of freedom, then there could be conflicting anchors when (say) the user makes a rotation gesture in the middle of a programmatic rotation.

@d-prukop
Copy link
Contributor Author

That's a good point about the anchor moving to the point between touches on rotate. I'm very much thinking about this in the specific context of navigation where any touch/move on the map should cancel all animation. Any call to transition to the following mode (by tapping resume or re-center or using a timeout) should result in the anchor point moving to somewhere in the lower third of the screen. Calls for transition to the overhead view should move the anchor to the center of the defined viewport.

@kkaefer
Copy link
Member

kkaefer commented Aug 21, 2017

@d-prukop see #2006 for a discussion on tile prefetching.

@kkaefer
Copy link
Member

kkaefer commented Aug 21, 2017

See #9813 for cache eviction strategy when prefetching tiles.

@zugaldia
Copy link
Member

Capturing chat today (cc: @tobrun). Looks like ObjectAnimator is a good starting point to achieve this on the Android side.

@d-prukop
Copy link
Contributor Author

Had a chat with @1ec5 yesterday. The plan is to experiment with using CoreAnimation to do camera animations without changing anything on core.

@1ec5
Copy link
Contributor

1ec5 commented Aug 22, 2017

The plan is to experiment with using CoreAnimation to do camera animations without changing anything on core.

This experiment would be focused specifically on one use case, a turn-by-turn navigation map view that only needs short-distance easing animations. The hope is that we can at least experiment with Core Animation integration purely at the SDK level. However, we’ll eventually need more from mbgl when we generalize this work to account for long-distance animations or flight animations.

@tobrun
Copy link
Member

tobrun commented Aug 23, 2017

I did a quick test on Android. In gif below you can see two Android SDK animators running together to animate bearing and tilt independently.

ezgif com-video-to-gif 19

Above is created using the Android SDK animator framework:

    final NativeCameraPosition cameraPosition = mapView.getCameraPosition();

    // Animate tilt
    ValueAnimator tiltAnimator = ValueAnimator.ofFloat(0f, 60.0f);
    tiltAnimator.setStartDelay(1000);
    tiltAnimator.setDuration(4000);
    tiltAnimator.setInterpolator(new FastOutSlowInInterpolator());
    tiltAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      public void onAnimationUpdate(ValueAnimator animation) {
        cameraPosition.setTilt(((Float) animation.getAnimatedValue()).doubleValue());
      }
    });

    // Animate bearing
    ValueAnimator bearingAnimator = ValueAnimator.ofFloat(0.0f, 160.0f);
    bearingAnimator.setDuration(6000);
    bearingAnimator.setInterpolator(new FastOutLinearInInterpolator());
    bearingAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        cameraPosition.setBearing(((Float)animation.getAnimatedValue()).doubleValue());
      }
    });

    // Combine animations and start
    AnimatorSet animatorSet = new AnimatorSet();
    animatorSet.setStartDelay(1500);
    animatorSet.play(tiltAnimator);
    animatorSet.play(bearingAnimator);
    animatorSet.start();

Note that I didn't change anything to core but I had to rework a couple of things in the android binding to make this work. Bringing a feature like this would mean increasing the API surface on the Android SDK.

@1ec5
Copy link
Contributor

1ec5 commented Aug 23, 2017

However, we’ll eventually need more from mbgl when we generalize this work to account for long-distance animations or flight animations.

From core GL, we’ll mainly need to use mbgl::Projection, which is already conveniently in a standalone namespace, ready to use within MGLMapView’s implementation. mapbox/mapbox-gl-js#3112 illustrates the problems we’d run into without projecting and unprojecting at the right times. You wouldn’t notice the problem unless the map is tilted or the animation spans a long distance.

@ericrwolfe
Copy link
Contributor

Awesome to see this moving, tagging myself to follow along.

@d-prukop
Copy link
Contributor Author

d-prukop commented Aug 26, 2017

Here's a version of the camera for iOS.
ios_camera_test
I was able to get this working with UIView animations. I'd like to eventually get it working with the UIViewPropertyAnimator.

Here's a look at the use of the UIKit API to animate our custom camera.

[UIView animateWithDuration:1.0 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        self.camera.lng = -122.400067;
        self.camera.lat = 37.788336;
    } completion:^(BOOL finished) {
      
    }];
    
    [UIView animateWithDuration:1.5 delay:0.6 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        self.camera.zoomLevel = 800;
    } completion:^(BOOL finished) {
        
    }];
    
    [UIView animateWithDuration:1.0 delay:1.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        self.camera.bearing = 135;
    } completion:^(BOOL finished) {
        
    }];
    
    [UIView animateWithDuration:1.0 delay:1.5 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        self.camera.pitch = 60;
    } completion:^(BOOL finished) {
        
    }];

@tobrun
Copy link
Member

tobrun commented Sep 15, 2017

PR unblocking this feature for the Android binding in #10001.

@tobrun
Copy link
Member

tobrun commented Jan 18, 2018

Removing android label, API for that landed.

@julianrex
Copy link
Contributor

Tagging myself and @fabian-guerra just for reference.

@stale
Copy link

stale bot commented Jan 28, 2019

This issue has been automatically detected as stale because it has not had recent activity and will be archived. Thank you for your contributions.

@stale
Copy link

stale bot commented Jul 27, 2019

This issue has been automatically detected as stale because it has not had recent activity and will be archived. Thank you for your contributions.

@stale stale bot closed this as completed Jul 27, 2019
@fabian-guerra fabian-guerra reopened this Jul 29, 2019
@stale stale bot removed the archived Archived because of inactivity label Jul 29, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Core The cross-platform C++ core, aka mbgl feature gl-ios iOS Mapbox Maps SDK for iOS navigation For the Mapbox Navigation SDK for Android or iOS or navigation use cases in general Qt Mapbox Maps SDK for Qt, aka Qt Location Mapbox GL
Projects
None yet
Development

No branches or pull requests

8 participants