【问题标题】:How to embed a Leaflet map into a Reveal.js presentation?如何将 Leaflet 地图嵌入到 Reveal.js 演示文稿中?
【发布时间】:2013-11-21 11:17:46
【问题描述】:

我正在尝试创建一个在 Reveal.js 之上运行的演示文稿,该演示文稿将在其中一张幻灯片中包含一个 Leaflet.js 地图。我已经在我的 Reveal.js 演示文稿中包含了所有必要的 Javascript 和 CSS 文件,我可以让地图出现在幻灯片上。

但是,问题是:地图图块显示不正确。我看到的不是实际的地图图块,而是灰色背景和一些水平黑线。我可以放大/缩小并平移地图,并且黑线会相应移动。

Javascript 控制台中没有错误消息,并且浏览器似乎正在按照应有的方式从服务器下载地图图块。我认为问题与 Leaflet 地图图块的 CSS 代码有关 - Leaflet.css 中的 .leaflet-tile - 在某种程度上与 Reveal.js 不兼容。

问题是:有谁知道如何解决这个问题?还是没有解决办法的死胡同?

<div id="map"> 有以下 CSS:

#map {
    height:400px;
    width:100%;
}

编辑: 一个明显的解决方法是使用<iframe> 标签将地图嵌入到演示文稿中。似乎工作得很好,也许将框架分开会更好。然而,不利的一面是,如果演示文稿中有多个地图,每个地图都在其自己的<iframe> 中,则会为每个 iframe 将 Leaflet.js 的副本加载到内存中。

编辑 #2: 一个更好的解决方案似乎是使用 Polymaps 而不是 Leaflet.js。似乎可以将多个 Polymaps 地图嵌入到 reveal.js 演示文稿中。没有问题。

【问题讨论】:

    标签: javascript css leaflet reveal.js


    【解决方案1】:

    我发现使用 web 组件很容易做到这一点,这样,shadow dom 将保护我的传单地图免受揭示 css 的邪恶之手

    here is a repo with an example

    <link rel="import" href="./leaflet-map.html">
    ...
    <div class="reveal">
      <div class="slides">
        <section data-state="map">
           <leaflet-map></leaflet-map>
        </section>
      </div>
    </div>
    

    这是网页组件

    <template id="leaflet-map-template">
    <link rel="stylesheet" href="./bower_components/leaflet/dist/leaflet.css">
    <div id="mapid" style="height: 500px"></div>
        <!-- LEAFLET JS -->
    </template>
    <script src="./bower_components/leaflet/dist/leaflet.js"></script>
    <script>
        class LeafletMap extends HTMLElement {
            constructor () {
                super();
                let tmpl = document.currentScript.ownerDocument.querySelector('template')
                let shadowRoot = this.attachShadow({mode: 'open'})
                shadowRoot.appendChild(tmpl.content.cloneNode(true))
    
                let mapDiv = this.shadowRoot.getElementById('mapid')
                this.map = L.map(mapDiv).setView([19.39682052576622, -99.13478851318361], 13)
                // this.setAttribute('map', map)
                // Tiles de open street maps
                //L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png").addTo(map)
    
                L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
                    maxZoom: 18,
                    attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
                        '<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
                        'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
                    id: 'mapbox.streets'
                }).addTo(this.map)
                let myIcon = L.icon({
                    iconUrl: './lentes.png',
    
                    iconSize:     [40, 40], // size of the icon
                    iconAnchor:   [20, 20], // point of the icon which will correspond to marker's location
                    tooltipAnchor: [20,0]
                })
                L.marker(
                    [19.418657758792698, -99.14065182209016],
                    {icon: myIcon}
                ).bindTooltip('Ranchito').addTo(this.map)
            }
    
            resize() {
                this.map.invalidateSize()
            }
        }
        window.customElements.define('leaflet-map', LeafletMap)
    </script>
    

    【讨论】:

      【解决方案2】:

      这可能是因为#map 元素在初始化时被隐藏(由于隐藏的幻灯片),所以它无法读取尺寸..

      一旦您的幻灯片可见,请尝试使用map.invalidateSize(false);..

      Reveal.addEventListener( 'slidechanged', function( event ) {
          // event.previousSlide, event.currentSlide, event.indexh, event.indexv
          if (event.indexh == 5){ // assuming your 5th slide is the one with the map
              map.invalidateSize(false); // assuming that map holds the the reference to your leaflet instance
          }
      } );
      

      【讨论】:

      • 感谢您的建议。但是,我试过了,但它似乎没有改变任何东西......我知道 invalidateSize() 只调整容器大小 - 在我的情况下,容器显示正确,问题只涉及地图图块。
      • 我认为使尺寸无效会导致重绘,并希望通过强制重绘瓷砖来解决它。如果将地图放在页面中是否有效(不是在幻灯片中,而是在 body 的根部) ?你也有页面的现场演示(或者可以在 jsfiddle 中重新创建它?)
      • 如果我将地图放在 HTML 的正文中,则可以正确显示图块。只要将地图放入&lt;div class="reveal"&gt; 元素中,图块就会变成灰色。不幸的是,我目前没有现场演示,可能不值得设置一个,因为 iframes 可以用来解决这个问题。无论如何,再次感谢您的努力!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-18
      • 1970-01-01
      • 2015-09-10
      • 1970-01-01
      • 2017-11-27
      • 2010-09-07
      • 2017-03-15
      相关资源
      最近更新 更多