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
This commit is contained in:
Martin Raifer
2025-02-10 13:44:17 +01:00
parent 97600e3ce8
commit 9e110cfda4
4 changed files with 30 additions and 36 deletions
+3
View File
@@ -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
+3 -14
View File
@@ -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 {
+1 -22
View File
@@ -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;
}
+23
View File
@@ -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);
}