Skip to content

fullscreen 全屏

使用 leaflet 、leaflet.fullscreen、vue 实现地图全屏。

实现 dom 元素全屏并不是很复杂的事情但既然已经有插件,那我们就来看下插件的使用方式。

示例

安装依赖

提示

它依赖于 screenfull 虽然官方没有指出(一个跨浏览器使用 JavaScript Fullscreen API 的简单包装器)

leaflet.fullscreen 仓库

screenfull 仓库

shell
pnpm i leaflet.fullscreen screenfull

有两种使用方式

一种是在地图初始化的时候直接添加全屏控件

js

const map = new L.Map('map', {
    fullscreenControl: true,
    fullscreenControlOptions: {
        position: 'topleft'
    }
});

第二种如下手动创建后添加到地图

代码实现

vue
<script setup>
import { ref, defineAsyncComponent, computed } from 'vue';
import 'leaflet.fullscreen/Control.FullScreen.css';
import 'leaflet.fullscreen/Control.FullScreen.js';

const InitMap = defineAsyncComponent(() =>
  import('../../components/InitMapTianditu.vue')
);

// 全屏状态
const fullScreenState = ref(false);

const initFullscreenControl = (map) => {
  L.control
    .fullscreen({
      position: 'topleft', // 按钮的位置 topleft, topright, bottomright or bottomleft, 默认 topleft
      title: '全屏显示', // 更改按钮的标题
      titleCancel: '退出全屏', // 全屏打开时更改按钮的标题
      content: null, // 改变按钮的内容可以html 默认null
      forceSeparateButton: true, // 强制设置为单独按钮与缩放按钮分离,默认 false
      forcePseudoFullscreen: true, // 即使全屏 API 可用,也强制使用伪全屏,默认 false
      fullscreenElement: false // 进入全屏的 dom 元素,默认 false 使用 map._container
    })
    .addTo(map);

  // 进入全屏的事件
  map.on('enterFullscreen', function () {
    fullScreenState.value = true;
    console.log('entered fullscreen');
  });

  // 退出全屏的事件
  map.on('exitFullscreen', function () {
    fullScreenState.value = false;
    console.log('exited fullscreen');
  });
};

const mapObj = ref();

const toggleFullscreenButName = computed(() =>
  fullScreenState.value ? '退出全屏' : '进入全屏'
);

// 手动切换全屏状态
const toggleFullscreen = () => {
  mapObj.value.toggleFullscreen();
};

const mapLoad = (map) => {
  mapObj.value = map;
  initFullscreenControl(map);
};
</script>

<template>
  <!--  todo 这里设置层级只是特殊处理 vitePress 元素层级,项目使用无需设置  -->
  <init-map
    :style="{ 'z-index': fullScreenState ? 999 : 0 }"
    @map-load="mapLoad"
  ></init-map>

  <CButton class="mt-10" @click="toggleFullscreen">
    {{ toggleFullscreenButName }}
  </CButton>
</template>

<style scoped></style>
vue
<script setup>
import { onMounted, onUnmounted, ref } from 'vue';
import L from 'leaflet';

const props = defineProps({
  center: {
    type: Array,
    default: [32.0237855, 118.8075675]
  }
})

const emit = defineEmits(['mapLoad']);

const mapRef = ref();

const initMap = () => {
  const map = L.map(mapRef.value, {
    center: props.center,
    zoom: 11,
    minZoom: 1,
    maxZoom: 18
  });

  const mapType = 'vec';
  L.tileLayer(
    'https://t{s}.tianditu.gov.cn/' +
      mapType +
      '_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=' +
      mapType +
      '&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=b72aa81ac2b3cae941d1eb213499e15e',
    {
      subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
      attribution:
        '&copy; <a href="http://lbs.tianditu.gov.cn/home.html">天地图 GS(2022)3124号 - 甲测资字1100471</a>'
    }
  ).addTo(map);

  const mapLabelType = 'cva';
  L.tileLayer(
    'https://t{s}.tianditu.gov.cn/' +
      mapLabelType +
      '_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=' +
      mapLabelType +
      '&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=b72aa81ac2b3cae941d1eb213499e15e',
    {
      subdomains: ['0', '1', '2', '3', '4', '5', '6', '7']
    }
  ).addTo(map);

  // 地图初始化完成发送事件
  emit('mapLoad', map);

  return map;
};

const mapObj = ref();

// 在 onMounted 中初始化地图
onMounted(() => {
  mapObj.value = initMap();
});

const removeMap = () => {
  if (mapObj.value) {
    mapObj.value.remove();
  }
};

// 在组件卸载时删除地图
onUnmounted(() => {
  removeMap();
});
</script>

<template>
  <div ref="mapRef" class="map"></div>
</template>

<style scoped>
.map {
  height: 40vh;
  z-index: 0;
}
</style>

贡献者

Released under the MIT License.