From 9e110cfda41787aeda5547d6b37e5fa56330587c Mon Sep 17 00:00:00 2001 From: Martin Raifer Date: Mon, 10 Feb 2025 13:44:17 +0100 Subject: [PATCH] make background map tile edges opaque Replaces the workaround of the tile rendering issues on Chrome at odd zoom levels. The svg filter `#alpha-slope5` alters the alpha channel of background tiles such that everything but (almost) transparent pixels are rendered fully opaque. closes #10747 --- CHANGELOG.md | 3 +++ css/80_app.css | 17 +++-------------- modules/renderer/tile_layer.js | 23 +---------------------- modules/svg/defs.js | 23 +++++++++++++++++++++++ 4 files changed, 30 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58d099744..a4f4764d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ _Breaking developer changes, which may affect downstream projects or sites that * Prevent degenerate ways caused by deleting a corner of a triangle ([#10003], thanks [@k-yle]) * Fix briefly disappearing data layer during background layer tile layer switching transition ([#10748]) * Preserve imagery offset during tile layer switching transition ([#10748]) +* Fix over-saturated map tiles near the border of the tile service's coverage area ([#10747], thanks [@hlfan]) #### :earth_asia: Localization #### :hourglass: Performance #### :mortar_board: Walkthrough / Help @@ -53,7 +54,9 @@ _Breaking developer changes, which may affect downstream projects or sites that #### :hammer: Development [#10003]: https://github.com/openstreetmap/iD/pull/10003 +[#10747]: https://github.com/openstreetmap/iD/issues/10747 [#10748]: https://github.com/openstreetmap/iD/issues/10748 +[@hlfan]: https://github.com/hlfan # 2.31.1 diff --git a/css/80_app.css b/css/80_app.css index 091b14580..7bb23fcc1 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -4373,26 +4373,15 @@ img.tile { overflow: hidden; } -/* Workaround to remove visible grid around tile borders on Chrome - Only works with browser zoom multiple of 25 (75%, 100%, 125%...) - Should be removed when https://issues.chromium.org/issues/40084005 is resolved. - See https://github.com/openstreetmap/iD/pull/10594 */ -@media (-webkit-device-pixel-ratio = 1) or (-webkit-device-pixel-ratio = 1.25) or (-webkit-device-pixel-ratio = 1.5) or (-webkit-device-pixel-ratio = 1.75) - or (-webkit-device-pixel-ratio = 2) or (-webkit-device-pixel-ratio = 2.25) or (-webkit-device-pixel-ratio = 2.5) or (-webkit-device-pixel-ratio = 2.75) - or (-webkit-device-pixel-ratio = 3) or (-webkit-device-pixel-ratio = 3.25) or (-webkit-device-pixel-ratio = 3.5) or (-webkit-device-pixel-ratio = 3.75) - or (-webkit-device-pixel-ratio = 4) or (-webkit-device-pixel-ratio = 4.25) or (-webkit-device-pixel-ratio = 4.5) or (-webkit-device-pixel-ratio = 4.75) - or (-webkit-device-pixel-ratio = 5) or (-webkit-device-pixel-ratio = 0.25) or (-webkit-device-pixel-ratio = 0.5) or (-webkit-device-pixel-ratio = 0.75) { - .layer-background img.tile, - .map-in-map-background img.tile { - mix-blend-mode: plus-lighter; - } +.layer-background img.tile, +.map-in-map-background img.tile { + filter: url(#alpha-slope5); } .layer-background img.tile-removing, .map-in-map-background img.tile-removing { opacity: 0; z-index: 1; - mix-blend-mode: normal; } .tile-label-debug { diff --git a/modules/renderer/tile_layer.js b/modules/renderer/tile_layer.js index ed0407939..5af70a3a8 100644 --- a/modules/renderer/tile_layer.js +++ b/modules/renderer/tile_layer.js @@ -16,30 +16,9 @@ export function rendererTileLayer(context) { var _zoom; var _source; var _underzoom = 0; - var _epsilon = 0; - - // Workaround to remove visible grid around tile borders on Chrome with dynamic epsilon for specific browser zoom levels - // Should be removed when https://issues.chromium.org/issues/40084005 is resolved - // See https://github.com/openstreetmap/iD/pull/10594 - if (window.chrome) { - updateEpsilon(); - window.addEventListener('resize', updateEpsilon); - } - function updateEpsilon() { - const pageZoom = Math.round(window.devicePixelRatio * 100); - if (pageZoom % 25 === 0) { - _epsilon = 0; // uses mix-blend-mode: plus-lighter - } else if (pageZoom === 90) { - _epsilon = 0.005; - } else if (pageZoom === 110) { - _epsilon = 0.002; - } else { - _epsilon = 0.003; - } - } function tileSizeAtZoom(d, z) { - return ((d.tileSize * Math.pow(2, z - d[2])) / d.tileSize) + _epsilon; + return (d.tileSize * Math.pow(2, z - d[2])) / d.tileSize; } diff --git a/modules/svg/defs.js b/modules/svg/defs.js index a1857035c..340170887 100644 --- a/modules/svg/defs.js +++ b/modules/svg/defs.js @@ -187,6 +187,29 @@ export function svgDefs(context) { .attr('width', function (d) { return d; }) .attr('height', function (d) { return d; }); + // add svg filters + const filters = _defsSelection.selectAll('filter') + .data(['alpha-slope5']) + .enter() + .append('filter') + .attr('id', d => d); + // Alters the alpha channel such that everything but + // (almost) transparent pixels are rendered fully opaque: + // This is used in a workaround for how chrome is rendering + // the edges of `img` elements when the page zoom is not a + // "round value": the semi-transparent pixels of neighboring + // tiles cannot "add up" to a fully opaque background layer. + // See https://github.com/openstreetmap/iD/issues/10747 + // and https://github.com/openstreetmap/iD/pull/10594 + const alphaSlope5 = filters.filter('#alpha-slope5') + .append('feComponentTransfer'); + alphaSlope5.append('feFuncR').attr('type', 'identity'); + alphaSlope5.append('feFuncG').attr('type', 'identity'); + alphaSlope5.append('feFuncB').attr('type', 'identity'); + alphaSlope5.append('feFuncA') + .attr('type', 'linear') + .attr('slope', 5); + // add symbol spritesheets addSprites(_spritesheetIds, true); }