diff options
Diffstat (limited to 'src/mbgl/map/transform.cpp')
-rw-r--r-- | src/mbgl/map/transform.cpp | 76 |
1 files changed, 35 insertions, 41 deletions
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp index e97f0da3f1..88b559592e 100644 --- a/src/mbgl/map/transform.cpp +++ b/src/mbgl/map/transform.cpp @@ -77,13 +77,13 @@ void Transform::jumpTo(const CameraOptions& camera) { } /** - * Change any combination of center, zoom, bearing, and pitch, with a smooth animation - * between old and new values. The map will retain the current values for any options - * not included in `options`. + * Change any combination of center, zoom, bearing, pitch and edgeInsets, with a + * smooth animation between old and new values. The map will retain the current + * values for any options not included in `options`. */ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& animation) { - const EdgeInsets& padding = camera.padding; - LatLng startLatLng = getLatLng(padding, LatLng::Unwrapped); + const EdgeInsets& padding = camera.padding.value_or(state.edgeInsets); + LatLng startLatLng = getLatLng(LatLng::Unwrapped); const LatLng& unwrappedLatLng = camera.center.value_or(startLatLng); const LatLng& latLng = state.bounds != LatLngBounds::unbounded() ? unwrappedLatLng : unwrappedLatLng.wrapped(); double zoom = camera.zoom.value_or(getZoom()); @@ -110,9 +110,6 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim const Point<double> startPoint = Projection::project(startLatLng, state.scale); const Point<double> endPoint = Projection::project(latLng, state.scale); - ScreenCoordinate center = getScreenCoordinate(padding); - center.y = state.size.height - center.y; - // Constrain camera options. zoom = util::clamp(zoom, state.getMinZoom(), state.getMaxZoom()); const double scale = state.zoomScale(zoom); @@ -130,6 +127,7 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim state.panning = unwrappedLatLng != startLatLng; state.scaling = scale != startScale; state.rotating = bearing != startBearing; + const EdgeInsets startEdgeInsets = state.edgeInsets; startTransition(camera, animation, [=](double t) { Point<double> framePoint = util::interpolate(startPoint, endPoint, t); @@ -143,9 +141,14 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim if (pitch != startPitch) { state.pitch = util::interpolate(startPitch, pitch, t); } - - if (!padding.isFlush()) { - state.moveLatLng(frameLatLng, center); + if (padding != startEdgeInsets) { + // Interpolate edge insets + state.edgeInsets = { + util::interpolate(startEdgeInsets.top(), padding.top(), t), + util::interpolate(startEdgeInsets.left(), padding.left(), t), + util::interpolate(startEdgeInsets.bottom(), padding.bottom(), t), + util::interpolate(startEdgeInsets.right(), padding.right(), t) + }; } }, duration); } @@ -159,8 +162,8 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim Where applicable, local variable documentation begins with the associated variable or function in van Wijk (2003). */ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &animation) { - const EdgeInsets& padding = camera.padding; - const LatLng& latLng = camera.center.value_or(getLatLng(padding, LatLng::Unwrapped)).wrapped(); + const EdgeInsets& padding = camera.padding.value_or(state.edgeInsets); + const LatLng& latLng = camera.center.value_or(getLatLng(LatLng::Unwrapped)).wrapped(); double zoom = camera.zoom.value_or(getZoom()); double bearing = camera.bearing ? -*camera.bearing * util::DEG2RAD : getBearing(); double pitch = camera.pitch ? *camera.pitch * util::DEG2RAD : getPitch(); @@ -170,15 +173,12 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima } // Determine endpoints. - LatLng startLatLng = getLatLng(padding, LatLng::Unwrapped).wrapped(); + LatLng startLatLng = getLatLng(LatLng::Unwrapped).wrapped(); startLatLng.unwrapForShortestPath(latLng); const Point<double> startPoint = Projection::project(startLatLng, state.scale); const Point<double> endPoint = Projection::project(latLng, state.scale); - ScreenCoordinate center = getScreenCoordinate(padding); - center.y = state.size.height - center.y; - // Constrain camera options. zoom = util::clamp(zoom, state.getMinZoom(), state.getMaxZoom()); pitch = util::clamp(pitch, util::PITCH_MIN, util::PITCH_MAX); @@ -278,6 +278,7 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima state.panning = true; state.scaling = true; state.rotating = bearing != startBearing; + const EdgeInsets startEdgeInsets = state.edgeInsets; startTransition(camera, animation, [=](double k) { /// s: The distance traveled along the flight path, measured in @@ -304,9 +305,14 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima if (pitch != startPitch) { state.pitch = util::interpolate(startPitch, pitch, k); } - - if (!padding.isFlush()) { - state.moveLatLng(frameLatLng, center); + if (padding != startEdgeInsets) { + // Interpolate edge insets + state.edgeInsets = { + util::interpolate(startEdgeInsets.top(), padding.top(), us), + util::interpolate(startEdgeInsets.left(), padding.left(), us), + util::interpolate(startEdgeInsets.bottom(), padding.bottom(), us), + util::interpolate(startEdgeInsets.right(), padding.right(), us) + }; } }, duration); } @@ -314,28 +320,16 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima #pragma mark - Position void Transform::moveBy(const ScreenCoordinate& offset, const AnimationOptions& animation) { - ScreenCoordinate centerOffset = { offset.x, -offset.y, }; - ScreenCoordinate centerPoint = getScreenCoordinate() - centerOffset; - easeTo(CameraOptions().withCenter(state.screenCoordinateToLatLng(centerPoint)), animation); -} - -LatLng Transform::getLatLng(const EdgeInsets& padding, LatLng::WrapMode wrap) const { - if (padding.isFlush()) { - return state.getLatLng(wrap); - } else { - return screenCoordinateToLatLng(padding.getCenter(state.size.width, state.size.height)); - } + ScreenCoordinate centerOffset = { offset.x, offset.y }; + ScreenCoordinate pointOnScreen = state.edgeInsets.getCenter(state.size.width, state.size.height) - centerOffset; + // Use unwrapped LatLng to carry information about moveBy direction. + easeTo(CameraOptions().withCenter(screenCoordinateToLatLng(pointOnScreen, LatLng::Unwrapped)), animation); } -ScreenCoordinate Transform::getScreenCoordinate(const EdgeInsets& padding) const { - if (padding.isFlush()) { - return { state.size.width / 2., state.size.height / 2. }; - } else { - return padding.getCenter(state.size.width, state.size.height); - } +LatLng Transform::getLatLng(LatLng::WrapMode wrap) const { + return state.getLatLng(wrap); } - #pragma mark - Zoom double Transform::getZoom() const { @@ -364,7 +358,7 @@ void Transform::setMaxZoom(const double maxZoom) { #pragma mark - Bearing void Transform::rotateBy(const ScreenCoordinate& first, const ScreenCoordinate& second, const AnimationOptions& animation) { - ScreenCoordinate center = getScreenCoordinate(); + ScreenCoordinate center = state.edgeInsets.getCenter(state.size.width, state.size.height); const ScreenCoordinate offset = first - center; const double distance = std::sqrt(std::pow(2, offset.x) + std::pow(2, offset.y)); @@ -576,10 +570,10 @@ ScreenCoordinate Transform::latLngToScreenCoordinate(const LatLng& latLng) const return point; } -LatLng Transform::screenCoordinateToLatLng(const ScreenCoordinate& point) const { +LatLng Transform::screenCoordinateToLatLng(const ScreenCoordinate& point, LatLng::WrapMode wrapMode) const { ScreenCoordinate flippedPoint = point; flippedPoint.y = state.size.height - flippedPoint.y; - return state.screenCoordinateToLatLng(flippedPoint).wrapped(); + return state.screenCoordinateToLatLng(flippedPoint, wrapMode); } } // namespace mbgl |