Skip to content

Commit

Permalink
make panning while zooming more linear
Browse files Browse the repository at this point in the history
fix #2070

easeTo used to interpolate locations based on projected values. As zoom
changed the new screen distance of these projected values changed either
speeding up or slowing down the panning.

With this change, the new center moves across the screen from it's
previous point location to it's new point location linearly.
  • Loading branch information
ansis committed Feb 16, 2016
1 parent 4a713d4 commit 143f358
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 17 deletions.
30 changes: 20 additions & 10 deletions js/ui/camera.js
Original file line number Diff line number Diff line change
Expand Up @@ -500,9 +500,7 @@ util.extend(Camera.prototype, /** @lends Map.prototype */{
}, options);

var tr = this.transform,
offset = Point.convert(options.offset).rotate(-tr.angle),
from = tr.point,
startWorldSize = tr.worldSize,
offset = Point.convert(options.offset),
startZoom = this.getZoom(),
startBearing = this.getBearing(),
startPitch = this.getPitch(),
Expand All @@ -512,8 +510,21 @@ util.extend(Camera.prototype, /** @lends Map.prototype */{
pitch = 'pitch' in options ? +options.pitch : startPitch,

scale = tr.zoomScale(zoom - startZoom),
to = 'center' in options ? tr.project(LngLat.convert(options.center)).sub(offset.div(scale)) : from,
around = 'center' in options ? null : LngLat.convert(options.around);
toLngLat,
toPoint;

if ('center' in options) {
toLngLat = LngLat.convert(options.center);
toPoint = tr.centerPoint.add(offset.div(scale));
} else if ('around' in options) {
toLngLat = LngLat.convert(options.around);
toPoint = tr.locationPoint(toLngLat);
} else {
toPoint = tr.centerPoint.add(offset.div(scale));
toLngLat = tr.pointLocation(toPoint);
}

var fromPoint = tr.locationPoint(toLngLat);

this.zooming = (zoom !== startZoom);
this.rotating = (startBearing !== bearing);
Expand All @@ -525,11 +536,8 @@ util.extend(Camera.prototype, /** @lends Map.prototype */{
}

this._ease(function (k) {
if (this.zooming && around) {
tr.setZoomAround(interpolate(startZoom, zoom, k), around);
} else {
if (this.zooming) tr.zoom = interpolate(startZoom, zoom, k);
tr.center = tr.unproject(from.add(to.sub(from).mult(k)), startWorldSize);
if (this.zooming) {
tr.zoom = interpolate(startZoom, zoom, k);
}

if (this.rotating) {
Expand All @@ -540,6 +548,8 @@ util.extend(Camera.prototype, /** @lends Map.prototype */{
tr.pitch = interpolate(startPitch, pitch, k);
}

tr.setLocationAtPoint(toLngLat, fromPoint.add(toPoint.sub(fromPoint)._mult(k)));

this.fire('move', eventData);
if (this.zooming) {
this.fire('zoom', eventData);
Expand Down
14 changes: 7 additions & 7 deletions test/js/ui/camera.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ test('camera', function(t) {
t.test('noop', function(t) {
var camera = createCamera();
camera.easeTo({ duration: 0 });
t.deepEqual(camera.getCenter(), { lng: 0, lat: 0 });
t.deepEqual(fixedLngLat(camera.getCenter()), { lng: 0, lat: 0 });
t.equal(camera.getZoom(), 0);
t.equal(camera.getBearing(), 0);
t.end();
Expand All @@ -564,7 +564,7 @@ test('camera', function(t) {
t.test('noop with offset', function(t) {
var camera = createCamera();
camera.easeTo({ offset: [100, 0], duration: 0 });
t.deepEqual(camera.getCenter(), { lng: 0, lat: 0 });
t.deepEqual(fixedLngLat(camera.getCenter()), { lng: 0, lat: 0 });
t.equal(camera.getZoom(), 0);
t.equal(camera.getBearing(), 0);
t.end();
Expand All @@ -573,14 +573,14 @@ test('camera', function(t) {
t.test('pans with specified offset', function(t) {
var camera = createCamera();
camera.easeTo({ center: [100, 0], offset: [100, 0], duration: 0 });
t.deepEqual(camera.getCenter(), { lng: 29.6875, lat: 0 });
t.deepEqual(fixedLngLat(camera.getCenter()), { lng: 29.6875, lat: 0 });
t.end();
});

t.test('pans with specified offset relative to viewport on a rotated camera', function(t) {
var camera = createCamera({ bearing: 180 });
camera.easeTo({ center: [100, 0], offset: [100, 0], duration: 0 });
t.deepEqual(camera.getCenter(), { lng: 170.3125, lat: 0 });
t.deepEqual(fixedLngLat(camera.getCenter()), { lng: 170.3125, lat: 0 });
t.end();
});

Expand Down Expand Up @@ -721,7 +721,7 @@ test('camera', function(t) {
t.test('noop', function(t) {
var camera = createCamera();
camera.flyTo({ animate: false });
t.deepEqual(camera.getCenter(), { lng: 0, lat: 0 });
t.deepEqual(fixedLngLat(camera.getCenter()), { lng: 0, lat: 0 });
t.equal(camera.getZoom(), 0);
t.equal(camera.getBearing(), 0);
t.end();
Expand All @@ -730,7 +730,7 @@ test('camera', function(t) {
t.test('noop with offset', function(t) {
var camera = createCamera();
camera.flyTo({ offset: [100, 0], animate: false });
t.deepEqual(camera.getCenter(), { lng: 0, lat: 0 });
t.deepEqual(fixedLngLat(camera.getCenter()), { lng: 0, lat: 0 });
t.equal(camera.getZoom(), 0);
t.equal(camera.getBearing(), 0);
t.end();
Expand All @@ -746,7 +746,7 @@ test('camera', function(t) {
t.test('pans with specified offset relative to viewport on a rotated camera', function(t) {
var camera = createCamera({ bearing: 180 });
camera.easeTo({ center: [100, 0], offset: [100, 0], animate: false });
t.deepEqual(camera.getCenter(), { lng: 170.3125, lat: 0 });
t.deepEqual(fixedLngLat(camera.getCenter()), { lng: 170.3125, lat: 0 });
t.end();
});

Expand Down

0 comments on commit 143f358

Please sign in to comment.