diff --git a/src/style/evaluation_parameters.js b/src/style/evaluation_parameters.js index 26cc2d375c9..78c83e7f6ce 100644 --- a/src/style/evaluation_parameters.js +++ b/src/style/evaluation_parameters.js @@ -24,6 +24,14 @@ class EvaluationParameters { this.transition = {}; } } + + crossFadingFactor() { + if (this.fadeDuration === 0) { + return 1; + } else { + return Math.min((this.now - this.zoomHistory.lastIntegerZoomTime) / this.fadeDuration, 1); + } + } } module.exports = EvaluationParameters; diff --git a/src/style/properties.js b/src/style/properties.js index 0ba5774239e..44efd4e1ed2 100644 --- a/src/style/properties.js +++ b/src/style/properties.js @@ -607,8 +607,7 @@ class CrossFadedProperty implements Property> { _calculate(min: T, mid: T, max: T, parameters: EvaluationParameters): ?CrossFaded { const z = parameters.zoom; const fraction = z - Math.floor(z); - const d = parameters.fadeDuration; - const t = d !== 0 ? Math.min((parameters.now - parameters.zoomHistory.lastIntegerZoomTime) / d, 1) : 1; + const t = parameters.crossFadingFactor(); return z > parameters.zoomHistory.lastIntegerZoom ? { from: min, to: mid, fromScale: 2, toScale: 1, t: fraction + (1 - fraction) * t } : { from: max, to: mid, fromScale: 0.5, toScale: 1, t: 1 - (1 - t) * fraction }; diff --git a/src/ui/map.js b/src/ui/map.js index 10472067dc3..db970383bc5 100755 --- a/src/ui/map.js +++ b/src/ui/map.js @@ -243,6 +243,7 @@ class Map extends Camera { _hash: Hash; _delegatedListeners: any; _fadeDuration: number; + _crossFadingFactor: number; scrollZoom: ScrollZoomHandler; boxZoom: BoxZoomHandler; @@ -270,6 +271,7 @@ class Map extends Camera { this._bearingSnap = options.bearingSnap; this._refreshExpiredTiles = options.refreshExpiredTiles; this._fadeDuration = options.fadeDuration; + this._crossFadingFactor = 1; const transformRequestFn = options.transformRequest; this._transformRequest = transformRequestFn ? (url, type) => transformRequestFn(url, type) || ({ url }) : (url) => ({ url }); @@ -1459,6 +1461,8 @@ class Map extends Camera { this._updateEase(); } + let crossFading = false; + // If the style has changed, the map is being zoomed, or a transition or fade is in progress: // - Apply style changes (in a batch) // - Recalculate paint properties. @@ -1476,6 +1480,12 @@ class Map extends Camera { transition: util.extend({ duration: 300, delay: 0 }, this.style.stylesheet.transition) }); + const factor = parameters.crossFadingFactor(); + if (factor !== 1 || factor !== this._crossFadingFactor) { + crossFading = true; + this._crossFadingFactor = factor; + } + this.style.update(parameters); } @@ -1505,7 +1515,7 @@ class Map extends Camera { this.fire('load'); } - if (this.style && this.style.hasTransitions()) { + if (this.style && (this.style.hasTransitions() || crossFading)) { this._styleDirty = true; } diff --git a/test/integration/render-tests/regressions/mapbox-gl-js#5740/expected.png b/test/integration/render-tests/regressions/mapbox-gl-js#5740/expected.png new file mode 100644 index 00000000000..c86291d37b3 Binary files /dev/null and b/test/integration/render-tests/regressions/mapbox-gl-js#5740/expected.png differ diff --git a/test/integration/render-tests/regressions/mapbox-gl-js#5740/style.json b/test/integration/render-tests/regressions/mapbox-gl-js#5740/style.json new file mode 100644 index 00000000000..2ab02ada1c6 --- /dev/null +++ b/test/integration/render-tests/regressions/mapbox-gl-js#5740/style.json @@ -0,0 +1,72 @@ +{ + "version": 8, + "metadata": { + "test": { + "fadeDuration": 1000, + "width": 64, + "height": 64, + "description": "Tests that fill-pattern cross-fading completes, by checking the rendering after the fade duration has elapsed.", + "operations": [ + [ + "wait" + ], + [ + "setZoom", + 1.1 + ], + [ + "wait", + 0 + ], + [ + "wait", + 1000 + ] + ] + } + }, + "sources": { + "geojson": { + "type": "geojson", + "data": { + "type": "Polygon", + "coordinates": [ + [ + [ + -10, + -10 + ], + [ + -10, + 10 + ], + [ + 10, + 10 + ], + [ + 10, + -10 + ], + [ + -10, + -10 + ] + ] + ] + } + } + }, + "sprite": "local://sprites/emerald", + "layers": [ + { + "id": "fill", + "type": "fill", + "source": "geojson", + "paint": { + "fill-antialias": false, + "fill-pattern": "generic_icon" + } + } + ] +} diff --git a/test/suite_implementation.js b/test/suite_implementation.js index 1ca5a62dbe5..91e52088fa0 100644 --- a/test/suite_implementation.js +++ b/test/suite_implementation.js @@ -38,7 +38,7 @@ module.exports = function(style, options, _callback) { preserveDrawingBuffer: true, axonometric: options.axonometric || false, skew: options.skew || [0, 0], - fadeDuration: 0 + fadeDuration: options.fadeDuration || 0 }); // Configure the map to never stop the render loop