Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework Camera#easeTo to address problems with pitch #3130

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 138 additions & 0 deletions debug/linear-ease.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<!DOCTYPE html>
<html>
<head>
<title>Mapbox GL JS debug page</title>
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">

<link rel='stylesheet' href='/dist/mapbox-gl.css' />
<style>
body { margin: 0; padding: 0; }
html, body, #map { height: 100%; }

.mapboxgl-marker {
width: 10px;
height: 10px;
background: red;
margin-top: -5px;
margin-left: -5px;
border-radius: 5px;
cursor: pointer;
}

#centerpoint {
position: absolute;
top: 50%;
left: 50%;
}

#dot {
width: 30px;
height: 30px;
background-color: #444;
position: relative;
right: 15px;
bottom: 15px;
z-index: 1000;
border-radius: 100px;
border: 3px solid #FFF;
box-sizing: border-box;
box-shadow: 1px 1px 5px #444;
}
</style>
</head>

<body>
<div id='map'></div>

<script src='/dist/mapbox-gl-dev.js'></script>
<script src='/debug/access-token-generated.js'></script>

<script>
var getCirclePoints = function(center, radiusInKm, points) {
if(!points) points = 64;

var km = radiusInKm;

var ret = [];
var distanceX = km/(111.320*Math.cos(center.lat*Math.PI/180));
var distanceY = km/110.574;

var theta, x, y;
for(var i=0; i<points; i++) {
theta = (i/points)*(2*Math.PI);
x = distanceX*Math.cos(theta);
y = distanceY*Math.sin(theta);

ret.push([center.lng+x, center.lat+y]);
}
ret.push(ret[0]);
return ret;
};

var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
center: [-93.6, 41.6],
zoom: 5,
pitch: 60
});

map.on('load', function() {
var i=0;

var waypoints = getCirclePoints(map.getCenter(), 500, 16);

map.addSource("polygon", {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [waypoints]
}
}]
}
});

map.addLayer({
"id": "polygon",
"type": "fill",
"source": "polygon",
"layout": {},
"paint": {
"fill-color": "blue",
"fill-opacity": 0.6
}
});

var duration = 3000;

var panToNextWaypoint = function() {
var waypoint = waypoints.shift();
waypoints.push(waypoint);

map.panTo(waypoint, {
duration: duration,
easing: function(t) {
return t;
}
});
};

setInterval(panToNextWaypoint, duration);

map.on('click', function() {
if(map.getPitch() === 0) {
map.setPitch(60);
} else {
map.setPitch(0);
}
});
});
</script>
<div id="centerpoint"><div id="dot"></div></div>
</body>
</html>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense that you built a debug page to use while developing this feature.

Because repository size, simplicity, and stability is important to us, we would prefer not to merge this file into master. Can you please remove this file from the PR?

43 changes: 39 additions & 4 deletions js/ui/camera.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var browser = require('../util/browser');
var LngLat = require('../geo/lng_lat');
var LngLatBounds = require('../geo/lng_lat_bounds');
var Point = require('point-geometry');
var Transform = require('../geo/transform');

/**
* Options common to {@link Map#jumpTo}, {@link Map#easeTo}, and {@link Map#flyTo},
Expand Down Expand Up @@ -408,13 +409,27 @@ util.extend(Camera.prototype, /** @lends Map.prototype */{
startZoom = this.getZoom(),
startBearing = this.getBearing(),
startPitch = this.getPitch(),
startCenter = tr.center,

zoom = 'zoom' in options ? +options.zoom : startZoom,
bearing = 'bearing' in options ? this._normalizeBearing(options.bearing, startBearing) : startBearing,
pitch = 'pitch' in options ? +options.pitch : startPitch,

toLngLat,
toPoint;
toPoint,

offsetLocation,
toLocation,
fromLocation,
endTransform;

// Setup a Transform representing the state of the map at the end of the transition
endTransform = new Transform();
endTransform.center = tr.center;
endTransform.resize(tr.width, tr.height);
endTransform.zoom = zoom;
endTransform.bearing = bearing;
endTransform.pitch = 0; // fixes #3119 by pretending the map is not pitched; use pitch = 0 to revert to the old behavior

if ('center' in options) {
toLngLat = LngLat.convert(options.center);
Expand All @@ -427,8 +442,6 @@ util.extend(Camera.prototype, /** @lends Map.prototype */{
toLngLat = tr.pointLocation(toPoint);
}

var fromPoint = tr.locationPoint(toLngLat);

if (options.animate === false) options.duration = 0;

this.zooming = (zoom !== startZoom);
Expand All @@ -442,11 +455,31 @@ util.extend(Camera.prototype, /** @lends Map.prototype */{
this.fire('zoomstart', eventData);
}

offsetLocation = endTransform.pointLocation(toPoint);
fromLocation = endTransform.pointLocation(endTransform.centerPoint);

toLocation = LngLat.convert([
toLngLat.lng - (offsetLocation.lng - fromLocation.lng),
toLngLat.lat - (offsetLocation.lat - fromLocation.lat)
]);

clearTimeout(this._onEaseEnd);

this._ease(function (k) {
// When zooming we need to scale our lat/lon interpolation because the distances change over the course of the transition
var k2 = k,
deltaZoom = zoom - startZoom,
totalDistanceExpansion = Math.pow(0.5, deltaZoom) - 1,
currentDelta,
currentDistanceExpansion;

if (this.zooming) {
tr.zoom = interpolate(startZoom, zoom, k);

currentDelta = tr.zoom - startZoom;
currentDistanceExpansion = Math.pow(0.5, currentDelta) - 1;

k2 = currentDistanceExpansion / totalDistanceExpansion;
}

if (this.rotating) {
Expand All @@ -457,7 +490,9 @@ util.extend(Camera.prototype, /** @lends Map.prototype */{
tr.pitch = interpolate(startPitch, pitch, k);
}

tr.setLocationAtPoint(toLngLat, fromPoint.add(toPoint.sub(fromPoint)._mult(k)));
var lng = interpolate(startCenter.lng, toLocation.lng, k2);
var lat = interpolate(startCenter.lat, toLocation.lat, k2);
tr.center = LngLat.convert([lng, lat]);

this.fire('move', eventData);
if (this.zooming) {
Expand Down