diff --git a/src/geo/transform.js b/src/geo/transform.js index e242d3482f4..8268689ef51 100644 --- a/src/geo/transform.js +++ b/src/geo/transform.js @@ -200,13 +200,21 @@ class Transform { * @private */ getVisibleUnwrappedCoordinates(tileID: CanonicalTileID) { - const ul = this.pointCoordinate(new Point(0, 0), 0); - const ur = this.pointCoordinate(new Point(this.width, 0), 0); - const w0 = Math.floor(ul.column); - const w1 = Math.floor(ur.column); const result = [new UnwrappedTileID(0, tileID)]; if (this._renderWorldCopies) { - for (let w = w0; w <= w1; w++) { + const utl = this.pointCoordinate(new Point(0, 0), 0); + const utr = this.pointCoordinate(new Point(this.width, 0), 0); + const ubl = this.pointCoordinate(new Point(this.width, this.height), 0); + const ubr = this.pointCoordinate(new Point(0, this.height), 0); + const w0 = Math.floor(Math.min(utl.column, utr.column, ubl.column, ubr.column)); + const w1 = Math.floor(Math.max(utl.column, utr.column, ubl.column, ubr.column)); + + // Add an extra copy of the world on each side to properly render ImageSources and CanvasSources. + // Both sources draw outside the tile boundaries of the tile that "contains them" so we need + // to add extra copies on both sides in case offscreen tiles need to draw into on-screen ones. + const extraWorldCopy = 1; + + for (let w = w0 - extraWorldCopy; w <= w1 + extraWorldCopy; w++) { if (w === 0) continue; result.push(new UnwrappedTileID(w, tileID)); } diff --git a/test/integration/render-tests/regressions/mapbox-gl-js#7271/expected.png b/test/integration/render-tests/regressions/mapbox-gl-js#7271/expected.png new file mode 100644 index 00000000000..fa168b2454f Binary files /dev/null and b/test/integration/render-tests/regressions/mapbox-gl-js#7271/expected.png differ diff --git a/test/integration/render-tests/regressions/mapbox-gl-js#7271/style.json b/test/integration/render-tests/regressions/mapbox-gl-js#7271/style.json new file mode 100644 index 00000000000..2b2fc291cf6 --- /dev/null +++ b/test/integration/render-tests/regressions/mapbox-gl-js#7271/style.json @@ -0,0 +1,48 @@ +{ + "version": 8, + "metadata": { + "test": { + "width": 512, + "height": 64 + } + }, + "center": [ + -10, + 0 + ], + "zoom": 0, + "sources": { + "image": { + "type": "image", + "coordinates": [ + [ + -270, + -80 + ], + [ + 90, + -80 + ], + [ + 90, + 80 + ], + [ + -270, + 80 + ] + ], + "url": "local://image/0.png" + } + }, + "layers": [ + { + "id": "image", + "type": "raster", + "source": "image", + "paint": { + "raster-fade-duration": 0 + } + } + ] +} diff --git a/test/unit/geo/transform.test.js b/test/unit/geo/transform.test.js index 07e857ed3d5..c6d24a9bc79 100644 --- a/test/unit/geo/transform.test.js +++ b/test/unit/geo/transform.test.js @@ -247,7 +247,7 @@ test('transform', (t) => { transform.center = { lng: -170.01, lat: 0.01 }; let unwrappedCoords = transform.getVisibleUnwrappedCoordinates(new CanonicalTileID(0, 0, 0)); - t.equal(unwrappedCoords.length, 2); + t.equal(unwrappedCoords.length, 4); //getVisibleUnwrappedCoordinates should honor _renderWorldCopies transform._renderWorldCopies = false;