Skip to content

Commit

Permalink
Fix globe/mercator projection transition (visgl#2229)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pessimistress authored Jul 14, 2023
1 parent 5d68c5b commit 16f8860
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 4 deletions.
20 changes: 16 additions & 4 deletions src/mapbox/mapbox.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import {transformToViewState, applyViewStateToTransform, cloneTransform} from '../utils/transform';
import {
transformToViewState,
applyViewStateToTransform,
cloneTransform,
syncProjection
} from '../utils/transform';
import {normalizeStyle} from '../utils/style-utils';
import {deepEqual} from '../utils/deep-equal';

Expand Down Expand Up @@ -394,7 +399,11 @@ export default class Mapbox<MapT extends MapInstance = MapInstance> {
map.on('resize', () => {
this._renderTransform.resize(map.transform.width, map.transform.height);
});
map.on('styledata', () => this._updateStyleComponents(this.props, {}));
map.on('styledata', () => {
this._updateStyleComponents(this.props, {});
// Projection can be set in stylesheet
syncProjection(map.transform, this._renderTransform);
});
map.on('sourcedata', () => this._updateStyleComponents(this.props, {}));
for (const eventName in pointerEvents) {
map.on(eventName, this._onPointerEvent);
Expand Down Expand Up @@ -728,11 +737,14 @@ export default class Mapbox<MapT extends MapInstance = MapInstance> {

const tr = this._map.transform;
// Make sure camera matches the current props
this._map.transform = this._renderTransform;
map.transform = this._renderTransform;

this._onAfterRepaint = () => {
// Mapbox transitions between non-mercator projection and mercator during render time
// Copy it back to the other
syncProjection(this._renderTransform, tr);
// Restores camera state before render/load events are fired
this._map.transform = tr;
map.transform = tr;
};
}

Expand Down
5 changes: 5 additions & 0 deletions src/types/lib.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type {PaddingOptions, LngLat, Point, LngLatLike, PointLike} from './common';
import type {Projection} from './style-spec';

export interface IControl<MapT extends MapInstance = MapInstance> {
onAdd(map: MapT): HTMLElement;
Expand Down Expand Up @@ -217,6 +218,10 @@ export type Transform = {
getBounds: () => any;
locationPoint: (lngLat: LngLat) => Point;
pointLocation: (p: Point) => LngLat;

// Mapbox only
getProjection?: () => Projection;
setProjection?: (projection: Projection) => void;
};

export type MapInstanceInternal<MapT extends MapInstance> = MapT & {
Expand Down
18 changes: 18 additions & 0 deletions src/utils/transform.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type {MapboxProps} from '../mapbox/mapbox';
import type {Transform, ViewState} from '../types';
import {deepEqual} from './deep-equal';

/**
* Make a copy of a transform
Expand All @@ -12,6 +13,23 @@ export function cloneTransform(tr: Transform): Transform {
return newTransform;
}

/**
* Copy projection from one transform to another. This only applies to mapbox-gl transforms
* @param src the transform to copy projection settings from
* @param dest to transform to copy projection settings to
*/
export function syncProjection(src: Transform, dest: Transform): void {
if (!src.getProjection) {
return;
}
const srcProjection = src.getProjection();
const destProjection = dest.getProjection();

if (!deepEqual(srcProjection, destProjection)) {
dest.setProjection(srcProjection);
}
}

/**
* Capture a transform's current state
* @param transform
Expand Down

0 comments on commit 16f8860

Please sign in to comment.