Open IMMSPgisgroup opened 5 years ago
Cannot reproduce (using Leaflet 1.5.1 and Firefox 69 on Debian). https://plnkr.co/edit/6SgcGdbjgU3me18QBKhJ?p=preview
As I see in documentation:
Global switches
Global switches are created for rare cases and generally make Leaflet to not detect a particular browser feature even if it's there. You need to set the switch as a global variable to true before including Leaflet on the page, like this:
<script>L_NO_TOUCH = true;</script> <script src="leaflet.js"></script>
Switch Description L_NO_TOUCH
Forces Leaflet to not use touch events even if it detects them. L_DISABLE_3D
Forces Leaflet to not use hardware-accelerated CSS 3D transforms for positioning (which may cause glitches in some rare environments) even if they're supported.
But in https://plnkr.co/edit/6SgcGdbjgU3me18QBKhJ?p=preview
<script src="https://unpkg.com/leaflet/dist/leaflet-src.js"></script>
<script>L_DISABLE_3D = true;</script>
Note, that in @IvanSanchez sample L_DISABLE_3D
is below LeafletJS loading. For this reason, maybe, bug not reproduced.
In addition, I see now if
zoomDelta: 0.25
bug is reproduced. But if zoomDelta not fractional, bug not reproduced. For zoomDelta = 0.5 zoom work, but very strange.
With best regards, IMMSPgisgroup
@IMMSPgisgroup @IvanSanchez
Yes, you are right. The problem is in zoomDelta
property. When you try to zoom Leaflet will limit your zoom level. For this reason it calls _limitZoom
function here.
Inside this function it checks if 3d is turned on or off. If it turned on that Leaflet round new zoom level based on zoomDelta
set in map options. If it turned off than Leaflet rounds zoom level to integer.
It means if map has current zoom level 2.0 and user clicks on zoom button in zoom control, _zoomIn
function in zoomControl will be called and it adds zoomDelta
to the current zoom level here. New zoom level becomes 2.25. But before Leaflet animate zoom change, it calls _limitZoom
function that rounds new zoom level to 2.0. It means zoom won't change.
Fix is simple:
Use the same code in _zoomIn
and _zoomOut
function of zoomControl as in zoomIn
and zoomOut
functions in Map class. There zoomDelta
is ignored if 3d is turned off here
delta = delta || (Browser.any3d ? this.options.zoomDelta : 1);
Perhaps offtopic here, but I've found that L_DISABLE_3D
prevents pinch zoom (and make map offsets wrong). Reported here: https://github.com/Leaflet/Leaflet/issues/1759#issuecomment-603777006
To add to this topic, zoomSnap
doesn't work using L_DISABLE_3D
. Reported here: https://github.com/thedirtyfew/dash-leaflet/issues/188
@albavilanova for what reason do you need to set L_DISABLE_3D
to true?
Hi @Falke-Design, sorry for the delay, I do not know the reason since it was somebody else who set it. However, today I noticed that if I don't include L_DISABLE_3D=true
I have problems changing the basemap in our dashboard (I need to zoom to apply the changes).
We've removed L_DISABLE_3D
for the upcoming v2 of Leaflet, instead opting to always enable 3d acceleration now that it's widely supported by all browsers. If this issue still occurs we should see if we can create a fix for it.
Hi @jonkoops, it is good to know that 3d acceleration will be enabled by default, then we are sure that there will be no problems with the zoom snap. I created this piece of code to exemplify what's happening when changing the layers in case you want to test this bug in the upcoming version, you can run the app, remove L_DISABLE_3D and rerun it to see the difference:
import dash
from dash import html
from dash import dcc
import dash_leaflet as dl
from dash.dependencies import Output
from dash.dependencies import Input
leaflet = "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.css"
app = dash.Dash(__name__,
external_stylesheets=[leaflet])
app.index_string = '''
<!DOCTYPE html>
<html>
<head>
<script>
L_DISABLE_3D=true;
L_PREFER_CANVAS=true;
L_SCROLL_WHEEL_ZOOM=false;
</script>
{%metas%}
<title>{%title%}</title>
{%favicon%}
{%css%}
</head>
<body>
{%app_entry%}
<footer>
{%config%}
{%scripts%}
{%renderer%}
</footer>
</body>
</html>
'''
zoom_properties = {
"zoomSnap": 0.1,
"wheelPxPerZoomLevel": 120,
"wheelDebounceTime": 80,
"minZoom": 2
}
map_layers = {"carto-positron": {"name": "Light",
"url": "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",
"attribution": "© <a href='https://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors © <a href='https://carto.com/attributions'>CARTO</a>"
},
"esri-world": {"name": "ESRI",
"url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
"attribution": "Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community"
}
}
@dash.callback(
Output('map', 'children'),
Input('view-dropdown', 'value')
)
def update_figure(tile_layer):
print(f'Applying {tile_layer} tile layer')
fig = dl.Map(dl.TileLayer(
url=map_layers[tile_layer]['url'],
attribution=map_layers[tile_layer]['attribution']),
style={'width': '100%', 'height': '800px'},
zoom=6.2,
center=[40, -3.7],
**zoom_properties)
return fig
app.layout = html.Div(children=[dcc.Dropdown(
id='view-dropdown',
options=[
{'label': map_layers[style]['name'],
'value': style}
for style in map_layers],
value='carto-positron',
style={'width': '300px', 'float': 'right',
'margin-bottom': '10px'}
),
html.Div(
id='map'),
])
if __name__ == '__main__':
app.run_server(debug=True, port=7779)
You will notice that the center of the map changes when switching between layers, zooming in and out gets the map back to its correct position (weirdly).
Zoom controls on map do not work if
L_DISABLE_3D = true
.Sample: https://plnkr.co/edit/S6LVFcI4fsPpSVnP5V5h?p=preview
My LeafletJS version - 1.5.1. OS - Windows 10 Pro 1903 (64-bit). Browser - Mozilla Firefox 69.0.1 (64-bit).
With best regards, IMMSPgisgroup