diff --git a/src/style/style.js b/src/style/style.js index 8a1e7181bd6..50f1d9b21a0 100644 --- a/src/style/style.js +++ b/src/style/style.js @@ -954,7 +954,7 @@ class Style extends Evented { _updatePlacement(transform: Transform, showCollisionBoxes: boolean, fadeDuration: number) { let symbolBucketsChanged = false; - let placementChanged = false; + let placementCommitted = false; const layerTiles = {}; @@ -985,17 +985,20 @@ class Style extends Evented { this._layerOrderChanged = false; } - if (!this.pauseablePlacement.isDone()) { + if (this.pauseablePlacement.isDone()) { + // the last placement finished running, but the next one hasn’t + // started yet because of the `stillRecent` check immediately + // above, so mark it stale to ensure that we request another + // render frame + this.placement.setStale(); + } else { this.pauseablePlacement.continuePlacement(this._order, this._layers, layerTiles); if (this.pauseablePlacement.isDone()) { - const placement = this.pauseablePlacement.placement; - placementChanged = placement.commit(this.placement, browser.now()); - if (!this.placement || placementChanged || symbolBucketsChanged) { - this.placement = placement; - this.collisionIndex = this.placement.collisionIndex; - } - this.placement.setRecent(browser.now(), placement.stale); + this.pauseablePlacement.placement.commit(this.placement, browser.now()); + this.placement = this.pauseablePlacement.placement; + this.collisionIndex = this.placement.collisionIndex; + placementCommitted = true; } if (symbolBucketsChanged) { @@ -1004,12 +1007,9 @@ class Style extends Evented { // placement is already stale while it is in progress this.pauseablePlacement.placement.setStale(); } - - } else { - this.placement.setStale(); } - if (placementChanged || symbolBucketsChanged) { + if (placementCommitted || symbolBucketsChanged) { for (const layerID of this._order) { const styleLayer = this._layers[layerID]; if (styleLayer.type !== 'symbol') continue; diff --git a/src/symbol/placement.js b/src/symbol/placement.js index fca2e781cd7..eef09402770 100644 --- a/src/symbol/placement.js +++ b/src/symbol/placement.js @@ -61,17 +61,16 @@ class JointPlacement { class Placement { transform: Transform; collisionIndex: CollisionIndex; - recentUntil: number; placements: { [string | number]: JointPlacement }; opacities: { [string | number]: JointOpacityState }; commitTime: number; + lastPlacementChangeTime: number; stale: boolean; fadeDuration: number; constructor(transform: Transform, fadeDuration: number) { this.transform = transform.clone(); this.collisionIndex = new CollisionIndex(this.transform); - this.recentUntil = -Infinity; this.placements = {}; this.opacities = {}; this.stale = false; @@ -204,7 +203,7 @@ class Placement { bucket.justReloaded = false; } - commit(prevPlacement: ?Placement, now: number) { + commit(prevPlacement: ?Placement, now: number): void { this.commitTime = now; let placementChanged = false; @@ -242,7 +241,15 @@ class Placement { } } - return placementChanged; + // this.lastPlacementChangeTime is the time of the last commit() that + // resulted in a placement change -- in other words, the start time of + // the last symbol fade animation + assert(!prevPlacement || prevPlacement.lastPlacementChangeTime !== undefined); + if (placementChanged) { + this.lastPlacementChangeTime = now; + } else if (typeof this.lastPlacementChangeTime !== 'number') { + this.lastPlacementChangeTime = prevPlacement ? prevPlacement.lastPlacementChangeTime : now; + } } updateLayerOpacities(styleLayer: StyleLayer, tiles: Array) { @@ -362,16 +369,13 @@ class Placement { } hasTransitions(now: number) { - return this.symbolFadeChange(now) < 1 || this.stale; + return this.stale || + now - this.lastPlacementChangeTime < this.fadeDuration; } stillRecent(now: number) { - return this.recentUntil > now; - } - - setRecent(now: number, stale: boolean) { - this.stale = stale; - this.recentUntil = now + this.fadeDuration; + return this.commitTime !== 'undefined' && + this.commitTime + this.fadeDuration > now; } setStale() {