@@ -7,6 +7,7 @@ const LngLat = require('../geo/lng_lat');
7
7
const LngLatBounds = require ( '../geo/lng_lat_bounds' ) ;
8
8
const Point = require ( 'point-geometry' ) ;
9
9
const Evented = require ( '../util/evented' ) ;
10
+ const Transform = require ( '../geo/transform' ) ;
10
11
11
12
/**
12
13
* Options common to {@link Map#jumpTo}, {@link Map#easeTo}, and {@link Map#flyTo},
@@ -492,13 +493,26 @@ class Camera extends Evented {
492
493
startZoom = this . getZoom ( ) ,
493
494
startBearing = this . getBearing ( ) ,
494
495
startPitch = this . getPitch ( ) ,
496
+ startCenter = tr . center ,
495
497
496
498
zoom = 'zoom' in options ? + options . zoom : startZoom ,
497
499
bearing = 'bearing' in options ? this . _normalizeBearing ( options . bearing , startBearing ) : startBearing ,
498
500
pitch = 'pitch' in options ? + options . pitch : startPitch ;
499
501
500
- let toLngLat ,
501
- toPoint ;
502
+ let toLngLat ,
503
+ toPoint ,
504
+ offsetLocation ,
505
+ toLocation ,
506
+ fromLocation ,
507
+ endTransform ;
508
+
509
+ // Setup a Transform representing the state of the map at the end of the transition
510
+ endTransform = new Transform ( ) ;
511
+ endTransform . center = tr . center ;
512
+ endTransform . resize ( tr . width , tr . height ) ;
513
+ endTransform . zoom = zoom ;
514
+ endTransform . bearing = bearing ;
515
+ endTransform . pitch = 0 ; // fixes #3119 by pretending the map is not pitched; use pitch = 0 to revert to the old behavior
502
516
503
517
if ( 'center' in options ) {
504
518
toLngLat = LngLat . convert ( options . center ) ;
@@ -511,8 +525,6 @@ class Camera extends Evented {
511
525
toLngLat = tr . pointLocation ( toPoint ) ;
512
526
}
513
527
514
- const fromPoint = tr . locationPoint ( toLngLat ) ;
515
-
516
528
if ( options . animate === false ) options . duration = 0 ;
517
529
518
530
this . zooming = ( zoom !== startZoom ) ;
@@ -531,11 +543,30 @@ class Camera extends Evented {
531
543
this . fire ( 'zoomstart' , eventData ) ;
532
544
}
533
545
546
+ offsetLocation = endTransform . pointLocation ( toPoint ) ;
547
+ fromLocation = endTransform . pointLocation ( endTransform . centerPoint ) ;
548
+
549
+ toLocation = LngLat . convert ( [
550
+ toLngLat . lng - ( offsetLocation . lng - fromLocation . lng ) ,
551
+ toLngLat . lat - ( offsetLocation . lat - fromLocation . lat )
552
+ ] ) ;
553
+
534
554
clearTimeout ( this . _onEaseEnd ) ;
535
555
536
556
this . _ease ( function ( k ) {
557
+ // When zooming we need to scale our lat/lon interpolation because the distances change over the course of the transition
558
+ var k2 = k ,
559
+ deltaZoom = zoom - startZoom ,
560
+ totalDistanceExpansion = Math . pow ( 0.5 , deltaZoom ) - 1 ,
561
+ currentDelta ,
562
+ currentDistanceExpansion ;
563
+
537
564
if ( this . zooming ) {
538
565
tr . zoom = interpolate ( startZoom , zoom , k ) ;
566
+ currentDelta = tr . zoom - startZoom ;
567
+ currentDistanceExpansion = Math . pow ( 0.5 , currentDelta ) - 1 ;
568
+
569
+ k2 = currentDistanceExpansion / totalDistanceExpansion ;
539
570
}
540
571
541
572
if ( this . rotating ) {
@@ -545,8 +576,10 @@ class Camera extends Evented {
545
576
if ( this . pitching ) {
546
577
tr . pitch = interpolate ( startPitch , pitch , k ) ;
547
578
}
548
-
549
- tr . setLocationAtPoint ( toLngLat , fromPoint . add ( toPoint . sub ( fromPoint ) . _mult ( k ) ) ) ;
579
+
580
+ var lng = interpolate ( startCenter . lng , toLocation . lng , k2 ) ;
581
+ var lat = interpolate ( startCenter . lat , toLocation . lat , k2 ) ;
582
+ tr . center = LngLat . convert ( [ lng , lat ] ) ;
550
583
551
584
this . fire ( 'move' , eventData ) ;
552
585
if ( this . zooming ) {
0 commit comments