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

[core] easeTo camera animation looks buggy when camera needs to zoom out #15144

Closed
chloekraw opened this issue Jul 17, 2019 · 1 comment · Fixed by #15281
Closed

[core] easeTo camera animation looks buggy when camera needs to zoom out #15144

chloekraw opened this issue Jul 17, 2019 · 1 comment · Fixed by #15281
Assignees
Labels
Core The cross-platform C++ core, aka mbgl
Milestone

Comments

@chloekraw
Copy link
Contributor

Problem

Using -[MGLMapView setCamera:animated:] with MGLMapCamera set to a peak altitude makes it possible to manipulate the camera so that the animation from startPoint to endPoint requires zooming out, or moving from a higher to lower zoom level.

This results in a camera animation, powered by Transform::easeTo in core, that looks buggy. The animation first moves to the desired location and then zooms out, rather than creating one fluid motion that allows the camera to end at the desired latlng and zoom level.

I think the key change that needs to be made is in core. easeTo (and possibly flyTo) should make sure that the interpolation algorithm that controls the animation path scales across zoom level changes.

It's unclear whether this is only a problem when moving from higher to lower zoom levels, or if it's also a problem when moving from lower to higher zoom levels. In testing, it was tricky to set the altitude at just the right point in the iOS SDK that would result in an obvious zoom-in animation; this could be easier to test directly in core.

Steps to reproduce

Set the camera like so:

func mapViewDidFinishLoadingMap(_ mapView: MGLMapView) {
    let camera = MGLMapCamera(lookingAtCenter:
        CLLocationCoordinate2D(latitude: 37.80296867678598, longitude: -122.2494649887085),
                              altitude: 50000, pitch: 0, heading: 0)

    mapView.setCamera(camera, withDuration: 2, animationTimingFunction: nil)
}

Expected behavior

The camera should animate in one fluid motion from the starting point to the ending point.

Actual behavior

See "setCamerawithAltitude zooming out.MP4" video in setCamerawithAltitude videos.zip. You can see the camera zooming out in the last few seconds, which looks odd and unintuitive.

I also included a "setCamerawithAltitude zooming in.MP4" video for comparison. The animation is more subtle. It's hard to tell if the zoom change is also happening at the end of the animation but isn't dramatic enough to be noticeable to the human eye, or if the algorithm is correct when the starting zoom level is lower than the ending zoom level.

cc: @malwoodsantoro @tmpsantos @pozdnyakov @astojilj

@chloekraw chloekraw added the Core The cross-platform C++ core, aka mbgl label Jul 17, 2019
@chloekraw chloekraw added this to the release-queso milestone Jul 23, 2019
@1ec5
Copy link
Contributor

1ec5 commented Jul 26, 2019

Using -[MGLMapView setCamera:animated:] with MGLMapCamera set to a peak altitude makes it possible to manipulate the camera so that the animation from startPoint to endPoint requires zooming out, or moving from a higher to lower zoom level.

Note that peak altitude is a parameter passed into -[MGLMapView flyToCamera:withDuration:peakAltitude:completionHandler:]; it isn’t a parameter of -setCamera:… or an option on MGLMapCamera itself.

This results in a camera animation, powered by Transform::easeTo in core, that looks buggy. The animation first moves to the desired location and then zooms out, rather than creating one fluid motion that allows the camera to end at the desired latlng and zoom level.

At a glance, it looks like mbgl::Transform::easeTo() interpolates the scale factor. This avoids the usual mistake of interpolating the zoom level, but it could still be less than accurate. The most correct approach might be to convert to the spanned physical distance in projected meters and interpolate that span, but maybe there’s a simpler approach.

/ref #14520 (comment) and mapbox/mapbox-gl-js#4540

astojilj added a commit that referenced this issue Aug 2, 2019
…plementation.

When using flyTo for easeTo:
Limit zoom out to min(startZoom, targetZoom).
Reduce cinematic zoom in animation at the end of transition,
Linear zoom interpolation.

The patch also sets linear interpolation for flyTo edgeInsets animation, as it looks more appropriate to follow the approach taken for pitch and bearing.

Fixes: #15144
astojilj added a commit that referenced this issue Aug 8, 2019
…plementation.

When using flyTo for easeTo:
Limit zoom out to min(startZoom, targetZoom).
Reduce cinematic zoom in animation at the end of transition,
Linear zoom interpolation.

The patch also sets linear interpolation for flyTo edgeInsets animation, as it looks more appropriate to follow the approach taken for pitch and bearing.

Fixes: #15144
astojilj added a commit that referenced this issue Aug 8, 2019
…plementation.

When using flyTo for easeTo:
Limit zoom out to min(startZoom, targetZoom).
Reduce cinematic zoom in animation at the end of transition,
Linear zoom interpolation.

The patch also sets linear interpolation for flyTo edgeInsets animation, as it looks more appropriate to follow the approach taken for pitch and bearing.

Fixes: #15144
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
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants