maplibre / maplibre-gl-js

MapLibre GL JS - Interactive vector tile maps in the browser
https://maplibre.org/maplibre-gl-js/docs/
Other
6.69k stars 717 forks source link

Awkward animation of dashes at certain zoom levels #4583

Open westnordost opened 2 months ago

westnordost commented 2 months ago

This issue report is copied from https://github.com/maplibre/maplibre-native/issues/2433, because the issue exists for both:

Describe the bug When crossing certains zoom levels (possibly near whole numbers, but I did not check), dashed lines have some sort of animation, which look out of place.

https://github.com/user-attachments/assets/09c61ed3-e0f6-47ac-a9fa-d23e1ee6fb88

https://github.com/user-attachments/assets/7e341229-13be-49c1-a3b1-0c6fff3d7796

To Reproduce Steps to reproduce the behavior:

  1. Have a line layer with dashes, in this case { "id": "steps", "source": "jawg-streets", "source-layer": "road", "filter": ["all", ["in", ["get", "class"], ["literal", ["path"]]], ["in", ["get", "type"], ["literal", ["steps"]]], ["==", ["geometry-type"], "LineString"], ["!", ["in", ["get", "structure"], ["literal", ["bridge", "tunnel"]]]]], "type": "line","paint": {"line-color": "#f6eee6", "line-width": ["interpolate", ["exponential", 2], ["zoom"], 14.0, 0.35, 16.0, 0.7, 24.0, 179.2], "line-dasharray": [0.6, 0.4]} },

  2. Scroll map to have some dashes in view

  3. Zoom

Try it here: https://streetcomplete.app/map-jawg/ Zoom in on any highway=steps or private roads. These have dashes in this style.

Expected behavior Dashes should appear stable, i.e. without anything moving.

More information https://github.com/maplibre/maplibre-native/issues/2433

The issue occurs because MapLibre assumes that the map style itself does not dynamically interpolate the size of the (dashed) lines depending on the zoom level. The style used in the the StreetComplete style linked above scales the line-widths of roads, outlines etc. with the zoom level while most other styles don't.

HarelM commented 2 months ago

Any chance you can create a minimal reproduction using jsbin/codepen/stackblitz?

westnordost commented 2 months ago

Hm sorry, I am not a web developer, I don't know nothing of that. But you can reproduce it here: https://streetcomplete.app/map-jawg/ This also just loads maplibre-gl and the style. If you want to minimize the style, you can remove all layers except those that use a "line-dasharray". (See step 1 in "how to reproduce")

CommanderStorm commented 2 months ago

@westnordost FYI, you can disable/get around this by using a step function like the following ^^

{
"line-dasharray": [
        "step",
        ["zoom"],
        ["literal", [0, 1]],
        20,
        ["literal", [0.1, 0.4]],
        21,
        ["literal", [0.1, 0.3]],
        22,
        ["literal", [0.05, 0.2]],
      ],
}