Search code examples
vue.jsmapboxmapbox-gl-jsmapbox-gl

MapBox: Legend not working when full screen


I have a legend inside the map, is working fine when the map is not full screen, but when the map is full screen the legend is not showing.

To Reproduce

Steps to reproduce the behavior:

  1. Open the map and see the legend is present and working fine
  2. Click full screen icon
  3. The legend is not present
  4. Click full screen icon again to remove the full screen, now the legend is present and working fine

Expected behavior

The legend should work fine when full screen.

Screenshots

Normal screen, working fine:

image

Full screen, not showing the legend:

image

Additional context

Code example available on codesandbox https://codesandbox.io/s/ecstatic-wave-c3qmg. You should open the link https://c3qmg.csb.app/ on another page to be able to see the fullscreen icon.

Code extract:

<template>
  <!-- MapBox map -->
  <MglMap
    ref="customMap"
    :mapStyle="map.mapStyle"
    :zoom="map.zoom"
    :center="map.center"
    :attributionControl="false"
    @mousemove="mouseMoved"
    @click="mapClick"
  >
    <MglFullscreenControl position="top-left" />
    <MglNavigationControl position="top-left" />
    <MglScaleControl position="bottom-left" />

    <!-- Custom html legend, using the feature selected-->
    <MapLegend :feature="selectedFeature" />

    <div
      v-for="geoJsonLayer in getGeoJsonLayers.mapLayers"
      :key="geoJsonLayer.id"
    >
      <!-- Fill geojson -->
      <MglGeojsonLayer
        :sourceId="geoJsonLayer.sourceId"
        :source="geoJsonLayer.source"
        :layerId="geoJsonLayer.layerId"
        :layer="geoJsonLayer.layer"
      />

      <!-- Source is not needed but the source id is needed :) when you are using an already defined source above -->
      <!-- Outline geojson -->
      <MglGeojsonLayer
        :sourceId="`${geoJsonLayer.outlineLayerId}-source`"
        :layerId="geoJsonLayer.outlineLayerId"
        :layer="geoJsonLayer.outlineLayer"
      />
    </div>
  </MglMap>
</template>

Node packages installed:

├── @highcharts/[email protected]
├── @vue/[email protected]
├── @vue/[email protected]
├── @vue/[email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]

Solution

  • By default, the Mapbox GL JS fullscreen control only makes the map container itself full screen. Nothing else on the screen will be visible.

    So you need to pass the container element through to Vue-Mapbox's MglFullScreenControl as the container parameter, along these lines:

      <div id="mycontainer">
        <MglMap
          :accessToken="accessToken"
          :mapStyle="mapStyle"
          :zoom="zoom"
          :center="center"
          ref="map"
          class="default-map-xl"
        >
          <MglFullscreenControl position="top-left" :container="containerElement"/>
          <MapBoxLegend :selectedFeature="selectedFeature" />
        </MglMap>
    

    There's probably a better way to do this, but you can set that element as a data property once your component mounts.

      data() {
        return {
          //...
          containerElement: null
        };
      },  
      mounted() {
        this.containerElement = document.getElementById('mycontainer')
      }
    

    I forked your code sandbox here.