vue-leaflet / Vue2Leaflet

Vue 2 components for Leaflet maps
https://vue2-leaflet.netlify.app
MIT License
1.96k stars 380 forks source link

Maps do not render correctly in Bootstrap Modals #56

Closed securit closed 7 years ago

securit commented 7 years ago

When the map is created, the container width/height for your 'map-canvas' element has not yet been adjusted to the width/height of the modal dialog. This causes the map size to be incorrect (smaller) than what it should be and for the x and y coordinates of the tiles to be wrong. In particular if I inspect the generated code for my vue2leaflet map I see:

<div id="vmap" class="col-xs-4" style="height: 300px;">
  <div class="vue2leaflet-map leaflet-container leaflet-touch leaflet-fade-anim leaflet-grab leaflet-touch-drag leaflet-touch-zoom" style="position: relative; outline: none;" tabindex="0">
    <div></div> 
    <div></div>
    <div class="leaflet-pane leaflet-map-pane" style="transform: translate3d(0px, 0px, 0px);">
      <div class="leaflet-pane leaflet-tile-pane"><div class="leaflet-layer " style="z-index: 1; opacity: 1;">
      <div class="leaflet-tile-container leaflet-zoom-animated" style="z-index: 18; transform: translate3d(0px, 0px, 0px) scale(1);"><img alt="" role="presentation" src="//a.tile.openstreetmap.org/13/8039/5128.png" class="leaflet-tile leaflet-tile-loaded" style="width: 256px; height: 256px; transform: translate3d(-17px, -235px, 0px); opacity: 1;">

The transform: translate3d(-17px, -235px, 0px) is placing the map tiles above and to the left of where they should be.

This is noted elsewhere on the internet and they stipulated that this can be fixed by calling map.invalidateSize() which will work by re-adjusting the width/height bounds of the leaflet Map's container.

Have you exposed invalidateSize()? If so, how do I call it?

KoRiGaN commented 7 years ago

Hi @securit,

You can access the leaflet map object. So for example you have an application like

<div id="app">
    <v-map ref="map" :zoom="zoom" :center="center">
      <v-tilelayer :url="url" :attribution="attribution"></v-tilelayer>
      <v-marker :lat-lng="marker"></v-marker>
    </v-map>
  </div>
this.$refs.map.mapObject.invalidateSize();

Let me know if that fixes your issue.

Mickaël

KoRiGaN commented 7 years ago

Closed as no answer for 2 weeks

securit commented 7 years ago

Sorry I only just got back to this.

I managed to get this to work inside Laravel Spark by implementing the this.$refs.map.mapObject.invalidatedSize() inside the VUE mounted method of my component. I had been calling it within the created method, but that is fired before the template is processed. See https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram.

zhangya5847 commented 7 years ago

I have the same problem.When i implement this.$refs.map.mapObject.invalidateSize() inside the mounted method,it doesn't work.