Skip to content

Commit

Permalink
reduce symbol overlap when zooming out quickly (#8628)
Browse files Browse the repository at this point in the history
  • Loading branch information
ansis authored Sep 30, 2019
1 parent 39e43d1 commit a0b5c3b
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/style/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -1200,7 +1200,7 @@ class Style extends Evented {
// tiles will fully display symbols in their first frame
const forceFullPlacement = this._layerOrderChanged || fadeDuration === 0;

if (forceFullPlacement || !this.pauseablePlacement || (this.pauseablePlacement.isDone() && !this.placement.stillRecent(browser.now()))) {
if (forceFullPlacement || !this.pauseablePlacement || (this.pauseablePlacement.isDone() && !this.placement.stillRecent(browser.now(), transform.zoom))) {
this.pauseablePlacement = new PauseablePlacement(transform, this._order, forceFullPlacement, showCollisionBoxes, fadeDuration, crossSourceCollisions, this.placement);
this._layerOrderChanged = false;
}
Expand Down
30 changes: 24 additions & 6 deletions src/symbol/placement.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,14 @@ export class Placement {
variableOffsets: {[CrossTileID]: VariableOffset };
placedOrientations: {[CrossTileID]: number };
commitTime: number;
prevZoomAdjustment: number;
lastPlacementChangeTime: number;
stale: boolean;
fadeDuration: number;
retainedQueryData: {[number]: RetainedQueryData};
collisionGroups: CollisionGroups;
prevPlacement: ?Placement;
zoomAtLastRecencyCheck: number;

constructor(transform: Transform, fadeDuration: number, crossSourceCollisions: boolean, prevPlacement?: Placement) {
this.transform = transform.clone();
Expand Down Expand Up @@ -636,13 +638,13 @@ export class Placement {

commit(now: number): void {
this.commitTime = now;
this.zoomAtLastRecencyCheck = this.transform.zoom;

const prevPlacement = this.prevPlacement;
let placementChanged = false;

const increment = (prevPlacement && this.fadeDuration !== 0) ?
(this.commitTime - prevPlacement.commitTime) / this.fadeDuration :
1;
this.prevZoomAdjustment = prevPlacement ? prevPlacement.zoomAdjustment(this.transform.zoom) : 0;
const increment = prevPlacement ? prevPlacement.symbolFadeChange(now) : 1;

const prevOpacities = prevPlacement ? prevPlacement.opacities : {};
const prevOffsets = prevPlacement ? prevPlacement.variableOffsets : {};
Expand Down Expand Up @@ -893,16 +895,32 @@ export class Placement {
symbolFadeChange(now: number) {
return this.fadeDuration === 0 ?
1 :
(now - this.commitTime) / this.fadeDuration;
((now - this.commitTime) / this.fadeDuration + this.prevZoomAdjustment);
}

zoomAdjustment(zoom: number) {
// When zooming out quickly, labels can overlap each other. This
// adjustment is used to reduce the interval between placement calculations
// and to reduce the fade duration when zooming out quickly. Discovering the
// collisions more quickly and fading them more quickly reduces the unwanted effect.
return Math.max(0, (this.transform.zoom - zoom) / 1.5);
}

hasTransitions(now: number) {
return this.stale ||
now - this.lastPlacementChangeTime < this.fadeDuration;
}

stillRecent(now: number) {
return this.commitTime + this.fadeDuration > now;
stillRecent(now: number, zoom: number) {
// The adjustment makes placement more frequent when zooming.
// This condition applies the adjustment only after the map has
// stopped zooming. This avoids adding extra jank while zooming.
const durationAdjustment = this.zoomAtLastRecencyCheck === zoom ?
(1 - this.zoomAdjustment(zoom)) :
1;
this.zoomAtLastRecencyCheck = zoom;

return this.commitTime + this.fadeDuration * durationAdjustment > now;
}

setStale() {
Expand Down

0 comments on commit a0b5c3b

Please sign in to comment.