Browse Source

Prevent leaflet from resetting center and zoom when browser resizes (#4265)

This PR tries to solve #4182 by changing the update mechanism for center
and zoom yet again.

As it turned out, Vue's `updated()` lifecycle hook is not only called
when a prop is updated from the server, but also when the window resizes
(vertically). In this case the "center" and "zoom" props can be outdated
if the user navigated the map manually. But the props are used to call
`setView`, causing the map to reset to the last location sent from the
server.

Various test setups from this issue as well as previous issues seem to
work just right:
```py
l = ui.leaflet(zoom=5)
ui.button('set center', on_click=lambda: l.set_center((48.1373, 11.5755)))
```

```py
@ui.page('/')
async def page():
    m = ui.leaflet(zoom=5)
    central_park = m.generic_layer(name='polygon', args=[[
        (40.767809, -73.981249),
        (40.800273, -73.958291),
        (40.797011, -73.949683),
        (40.764704, -73.973741),
    ]])
    await m.initialized()
    bounds = await central_park.run_method('getBounds')
    m.run_map_method('fitBounds', [[bounds['_southWest'], bounds['_northEast']]])
```

```py
m = ui.leaflet(center=(48.1, 11.6), zoom=10)
m.on('map-moveend', lambda e: print(e.args['center'], e.args['zoom']))
ui.button('Berlin', on_click=lambda: m.run_map_method('flyTo', [52.5, 13.4], 9, {'duration': 1.0}))
```
Falko Schindler 3 months ago
parent
commit
14a34883fb
2 changed files with 2 additions and 5 deletions
  1. 0 3
      nicegui/elements/leaflet.js
  2. 2 2
      nicegui/elements/leaflet.py

+ 0 - 3
nicegui/elements/leaflet.js

@@ -123,9 +123,6 @@ export default {
       clearInterval(connectInterval);
     }, 100);
   },
-  updated() {
-    this.map?.setView(this.center, this.zoom);
-  },
   methods: {
     add_layer(layer, id) {
       const l = L[layer.type](...layer.args);

+ 2 - 2
nicegui/elements/leaflet.py

@@ -110,7 +110,7 @@ class Leaflet(Element, component='leaflet.js', default_classes='nicegui-leaflet'
             return
         self._props['center'] = center
         if self._send_update_on_value_change:
-            self.update()
+            self.run_map_method('setView', center, self.zoom)
 
     def set_zoom(self, zoom: int) -> None:
         """Set the zoom level of the map."""
@@ -118,7 +118,7 @@ class Leaflet(Element, component='leaflet.js', default_classes='nicegui-leaflet'
             return
         self._props['zoom'] = zoom
         if self._send_update_on_value_change:
-            self.update()
+            self.run_map_method('setView', self.center, zoom)
 
     def remove_layer(self, layer: Layer) -> None:
         """Remove a layer from the map."""