diff --git a/src/ol/renderer/canvas/TileLayer.js b/src/ol/renderer/canvas/TileLayer.js index 91fe10f907..ff1cb839f2 100644 --- a/src/ol/renderer/canvas/TileLayer.js +++ b/src/ol/renderer/canvas/TileLayer.js @@ -20,6 +20,7 @@ import { equals, getIntersection, getTopLeft, + intersects, } from '../../extent.js'; import {cssOpacity} from '../../css.js'; import {fromUserExtent} from '../../proj.js'; @@ -463,26 +464,37 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer { const inTransition = transition && tile.getAlpha(getUid(this), frameState.time) !== 1; + let contextSaved = false; if (!inTransition) { if (clips) { // Clip mask for regions in this tile that already filled by a higher z tile - context.save(); currentClip = [x, y, x + w, y, x + w, y + h, x, y + h]; for (let i = 0, ii = clips.length; i < ii; ++i) { if (z !== currentZ && currentZ < clipZs[i]) { const clip = clips[i]; - context.beginPath(); - // counter-clockwise (outer ring) for current tile - context.moveTo(currentClip[0], currentClip[1]); - context.lineTo(currentClip[2], currentClip[3]); - context.lineTo(currentClip[4], currentClip[5]); - context.lineTo(currentClip[6], currentClip[7]); - // clockwise (inner ring) for higher z tile - context.moveTo(clip[6], clip[7]); - context.lineTo(clip[4], clip[5]); - context.lineTo(clip[2], clip[3]); - context.lineTo(clip[0], clip[1]); - context.clip(); + if ( + intersects( + [x, y, x + w, y + h], + [clip[0], clip[3], clip[4], clip[7]] + ) + ) { + if (!contextSaved) { + context.save(); + contextSaved = true; + } + context.beginPath(); + // counter-clockwise (outer ring) for current tile + context.moveTo(currentClip[0], currentClip[1]); + context.lineTo(currentClip[2], currentClip[3]); + context.lineTo(currentClip[4], currentClip[5]); + context.lineTo(currentClip[6], currentClip[7]); + // clockwise (inner ring) for higher z tile + context.moveTo(clip[6], clip[7]); + context.lineTo(clip[4], clip[5]); + context.lineTo(clip[2], clip[3]); + context.lineTo(clip[0], clip[1]); + context.clip(); + } } } clips.push(currentClip); @@ -502,7 +514,9 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer { transition ); if (clips && !inTransition) { - context.restore(); + if (contextSaved) { + context.restore(); + } this.renderedTiles.unshift(tile); } else { this.renderedTiles.push(tile); diff --git a/src/ol/renderer/canvas/VectorTileLayer.js b/src/ol/renderer/canvas/VectorTileLayer.js index dd22263ca1..1862ee8a9c 100644 --- a/src/ol/renderer/canvas/VectorTileLayer.js +++ b/src/ol/renderer/canvas/VectorTileLayer.js @@ -665,49 +665,18 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { const rotation = viewState.rotation; const tiles = this.renderedTiles; - const clips = []; - const clipZs = []; for (let i = tiles.length - 1; i >= 0; --i) { const tile = /** @type {import("../../VectorRenderTile.js").default} */ ( tiles[i] ); const transform = this.getTileRenderTransform(tile, frameState); const executorGroups = tile.executorGroups[getUid(layer)]; - let clipped = false; for (let t = 0, tt = executorGroups.length; t < tt; ++t) { const executorGroup = executorGroups[t]; if (!executorGroup.hasExecutors(replayTypes)) { // sourceTile has no instructions of the types we want to render continue; } - const currentZ = tile.tileCoord[0]; - let currentClip; - if (!clipped) { - currentClip = executorGroup.getClipCoords(transform); - if (currentClip) { - context.save(); - - // Create a clip mask for regions in this low resolution tile that are - // already filled by a higher resolution tile - for (let j = 0, jj = clips.length; j < jj; ++j) { - const clip = clips[j]; - if (currentZ < clipZs[j]) { - context.beginPath(); - // counter-clockwise (outer ring) for current tile - context.moveTo(currentClip[0], currentClip[1]); - context.lineTo(currentClip[2], currentClip[3]); - context.lineTo(currentClip[4], currentClip[5]); - context.lineTo(currentClip[6], currentClip[7]); - // clockwise (inner ring) for higher resolution tile - context.moveTo(clip[6], clip[7]); - context.lineTo(clip[4], clip[5]); - context.lineTo(clip[2], clip[3]); - context.lineTo(clip[0], clip[1]); - context.clip(); - } - } - } - } executorGroup.execute( context, 1, @@ -716,12 +685,6 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { hifi, replayTypes ); - if (!clipped && currentClip) { - context.restore(); - clips.push(currentClip); - clipZs.push(currentZ); - clipped = true; - } } } context.globalAlpha = alpha;