1

我有一个非常奇怪的问题,我无法解决。关键是我通过 Vue2Leaflet 显示谷歌地图。在创建 Google 地图的屏幕截图时,由于 CSS Google 字体,它会向我抛出一个错误。

谷歌地图插件到传单:vue2-leaflet-googlemutant

要从地图上截取屏幕截图,我使用传单插件leaflet-simple-map-screenshotter

更详细的错误描述在这里:https ://github.com/grinat/leaflet-simple-map-screenshoter/issues/10

代码:

<template>
  <LMap
    :zoom="zoom"
    :max-zoom="maxZoom"
    :center="center"
    ref="map"
    :watch="true"
    :options="{ zoomControl: false, preferCanvas: true, doubleClickZoom: false }"
    style="z-index:1; background-color: white; height: 100%; width: 100%"
  >
    <v-tilelayer-googlemutant apikey="YOUR_KEY" :options="optionsSatellite"></v-tilelayer-googlemutant>
  </LMap>
</template>

<script>
import {
  LMap,
  LMarker,
  LWMSTileLayer,
  LTileLayer,
  LControlZoom,
  LFeatureGroup,
  LPopup,
  LControl,
  LControlScale
} from "vue2-leaflet";

import Vue2LeafletGoogleMutant from "vue2-leaflet-googlemutant";

import * as L from "leaflet";

import "leaflet-simple-map-screenshoter";

export default {
  name: "App",

  components: {
    LMap,
    LMarker,
    "l-wms-tile-layer": LWMSTileLayer,
    LTileLayer,
    LControlZoom,
    LFeatureGroup,
    LPopup,
    LControl,
    LControlScale,
    "v-tilelayer-googlemutant": Vue2LeafletGoogleMutant
  },

  data: () => ({
    zoom: 16,
    maxZoom: 22,
    map: {},
    center: [47.41322, -1.219482],
    bounds: null,
    optionsSatellite: {
      type: "satellite",
      streetViewControl: true
    },
    createArrow: false
  }),

  mounted() {
    this.$nextTick(() => {
      this.map = this.$refs.map.mapObject;

      let pluginOptions = {
        cropImageByInnerWH: true, // crop blank opacity from image borders
        hidden: false, // hide screen icon
        domtoimageOptions: {}, // see options for dom-to-image
        position: "topleft", // position of take screen icon
        screenName: "screen", // string or function
        hideElementsWithSelectors: [".leaflet-control-container"], // by default hide map controls All els must be child of _map._container
        mimeType: "image/png", // used if format == image,
        caption: null, // streeng or function, added caption to bottom of screen
        captionFontSize: 15,
        captionFont: "Arial",
        captionColor: "black",
        captionBgColor: "white",
        captionOffset: 5
      };

      this.simpleMapScreenshoter = L.simpleMapScreenshoter(pluginOptions).addTo(
        this.map
      );

      // For simpleMapScreenshoter
      const format = "image";

      setTimeout(() => {
        this.simpleMapScreenshoter
          .takeScreen(format, pluginOptions)
          .then(image => {
            console.log("Image: ", image);
          })
          .catch(e => {
            console.error(e);
          });
      }, 600);
    });
  }
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

代码沙箱

错误:

Error while reading CSS rules from https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Google+Sans:400,500,700 SecurityError: Failed to read the 'cssRules' property from 'CSSStyleSheet': Cannot access rules

4

1 回答 1

1

这是解决方案。 https://codesandbox.io/s/lealfet-google-map-screenshot-m4myt?file=/src/App.vue

<template>
  <div class="map">
    <l-map ref="map" style="width:100%; height: 100%" :zoom="zoom" :center="center">
      <v-tilelayer-googlemutant apikey="YOUR_API_KEY" :options="optionsSatellite"/>

      <LControl>
        <button @click="saveMapImage">Make Screenshot</button>
      </LControl>
    </l-map>
  </div>
</template>

<script>
import "leaflet";
import "leaflet/dist/leaflet.css";

import { LMap, LTileLayer, LControl } from "vue2-leaflet";
import VTilelayerGooglemutant from "vue2-leaflet-googlemutant";
import { SimpleMapScreenshoter } from "leaflet-simple-map-screenshoter";

export default {
  name: "App",

  components: { LMap, LTileLayer, LControl, VTilelayerGooglemutant },

  data: () => ({
    zoom: 16,
    map: {},
    center: [47.41322, -1.219482],
    optionsSatellite: {
      type: "satellite",
      streetViewControl: true
    }
  }),

  mounted() {
    this.$nextTick(() => {
      this.map = this.$refs.map.mapObject;
    });
  },

  methods: {
    saveMapImage() {
      let pluginOptions = {
        cropImageByInnerWH: true, // crop blank opacity from image borders
        hidden: true, // hide screen icon
        domtoimageOptions: {
          cacheBust: true,
          crossOrigin: "anonymous"
        }, // see options for dom-to-image
        position: "topleft", // position of take screen icon
        screenName: "screen", // string or function
        hideElementsWithSelectors: [".leaflet-control-container"], // by default hide map controls All els must be child of _map._container
        //mimeType: "image/png", // used if format == image,
        caption: null // streeng or function, added caption to bottom of screen
        //captionFontSize: 15,
        //captionFont: "Arial",
        //captionColor: "black",
        //captionBgColor: "white",
        //captionOffset: 5
      };

      this.simpleMapScreenshoter = new SimpleMapScreenshoter(
        pluginOptions
      ).addTo(this.map);

      // For simpleMapScreenshoter
      const format = "image"; // 'image' - return base64, 'canvas' - return canvas

      this.map.on("simpleMapScreenshoter.takeScreen", this.beforeScreenshot);

      setTimeout(() => {
        this.simpleMapScreenshoter
          .takeScreen(format, pluginOptions)
          .then(image => {
            console.log("Image screenshoter: ", image);
          });
      }, 100);
    },

    beforeScreenshot(e) {
      console.log("Before Screenshooter: ", e);
      Array.from(document.styleSheets).forEach(sheet => {
        const node = sheet.ownerNode;
        if (
          node &&
          node.href &&
          node.href.indexOf("fonts.googleapis.com") > -1
        ) {
          node.parentElement.removeChild(node);
        }
      });
    }
  }
};
</script>

<style>
.map {
  height: 100vh;
  width: 100vw;
}
#screenshot {
  width: 100px;
}
</style>

我必须感谢mikeu的帮助

注意:它不适用于全屏!

于 2020-07-22T07:26:08.940 回答