如何将Leaflet地图嵌入到Reveal.js演示文稿中?

时间:2013-11-21 11:17:46

标签: javascript css leaflet reveal.js

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

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

Javascript控制台中没有错误消息,浏览器似乎正在从服务器下载地图切片。我相信这个问题与Leaflet地图图块的CSS代码有关 - 在leaflet.css中.leaflet-tile - 与Reveal.js不相容。

问题是:有谁知道如何解决这个问题?或者它是一个没有可能的解决方案的deadend?

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

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

编辑:一个明显的解决方法是使用<iframe>标记将地图嵌入到演示文稿中。似乎工作得很好,也许最好保持框架分离。但是,缺点是,如果演示文稿中有多个地图,每个地图都在其自己的<iframe>内,则会将每个iframe的Leaflet.js副本加载到内存中。

编辑#2:似乎更好的解决方案是使用Polymaps代替 Leaflet.js 。似乎可以将几个 Polymaps 地图嵌入到 reveal.js presentaion中。没问题。

2 个答案:

答案 0 :(得分:0)

可能会发生这种情况,因为#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
    }
} );

答案 1 :(得分:0)

我发现使用Web组件很容易做到这一点,因此,影子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>

这是Web组件

<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>