How to Get a Leaflet Map Canvas to Have a 100% Height

How to get a leaflet map canvas to have a 100% height?

Using height: 100% does work, it only needs the parent containers to have a size too (working demo):

html, body { 
height: 100%;
}
#map {
width: 100%;
height: 100%;
}

Resizing a leaflet map on container resize

The problem is that the resizing of the #map-container div is done via a css transition. The transition hasn't started yet, let alone ended, when the call to invalidateSize happens so the leaflet map cannot recognize any change of dimensions of its surrounding div.

Triggering the map-container-resize event with a delay solved the problem. This way :

setTimeout(function(){ map.invalidateSize()}, 400);

Strange default size in leaflet map

jQuery Mobile has its own way to create pages from div's, so you may better stick to JQM events.

Here is a great post of Omar which explain how to solve this (typical) issue when loading Google Maps. You should wait for pagecontainershow or use a placeholder to pre-load the maps in advance.

In my example below, you will find a variation of this approach for Leaflet which uses the same canvasHeight() function (see also the answers here: set content height 100% jquery mobile).

I noticed you are about to implement a footer button for the geo-location feature, so for your convenience i show you also a possible way to do that (credits: Getting current user location automatically every “x” seconds to put on Leaflet map?).

Please note: i had to reposition the default map attribution so it won't overlap with the footer button.

var map, actualPosition, actualAccuracy, autoUpdate;

function canvasHeight(canvas) {
var mapPage = $("#page-map"),
screen = $.mobile.getScreenHeight(),
header = $(".ui-header", mapPage).hasClass("ui-header-fixed") ? $(".ui-header", mapPage).outerHeight() - 1 : $(".ui-header", mapPage).outerHeight(),
footer = $(".ui-footer", mapPage).hasClass("ui-footer-fixed") ? $(".ui-footer", mapPage).outerHeight() - 1 : $(".ui-footer", mapPage).outerHeight(),
newHeight = screen - header - footer;
$(canvas).height(newHeight);
}

$(window).on("throttledresize orientationchange", function() {
canvasHeight("#map");
})

function onLocationFound(e) {
var radius = e.accuracy / 2;
actualPosition = L.marker(e.latlng).addTo(map);
actualAccuracy = L.circle(e.latlng, radius).addTo(map);
}

function onLocationError(e) {
alert(e.message);
}

function showLocation() {
if (actualPosition) {
map.removeLayer(actualPosition);
map.removeLayer(actualAccuracy);
}
map.locate({setView: true,maxZoom: 16});
}

function loadMap(canvas) {
map = L.map(canvas).setView([43.7178, -79.3762], 11);
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png").addTo(map);
map.on('locationfound', onLocationFound);
map.on('locationerror', onLocationError);
// Your custom initialization
//getGeoJson();
//getTPSJson();
}

function toggleAutoUpdate() {
if (autoUpdate) {
$("#autoUpdate").removeClass("ui-btn-active");
clearInterval(autoUpdate);
autoUpdate = null;
if (actualPosition) {
map.removeLayer(actualPosition);
map.removeLayer(actualAccuracy);
}
} else {
$("#autoUpdate").addClass("ui-btn-active");
showLocation();
autoUpdate = setInterval(function() {
showLocation();
// Your custom Update
//getGeoJson();
}, 10 * 1000);
}
}

$(document).on("pagecontainershow", function(e, ui) {
if (ui.toPage.prop("id") == "page-map") {
canvasHeight("#map");
if (!map) {
loadMap("map");
}
}
});
#map {
margin: 0;
padding: 0;
}

#page-map .footer {
position: fixed;
z-index: 1000;
bottom: .1em;
width: 100%;
}

#footer-button {
width: 100%;
text-align: center;
background: transparent;
}

#map-attribution {
text-align: center;
background: rgba(255, 255, 255, 0.7);
}

.leaflet-control-attribution.leaflet-control {
display: none;
}

/* Don't show scrollbars on SO code snippet */
.ui-mobile .ui-page {
min-height: 100px !important;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.1.0/leaflet.css">
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.1.0/leaflet.js"></script>
</head>
<body>
<div data-role="page" id="page-map">
<div data-role="header" data-position="fixed" data-theme="a">
<a href="#" data-rel="back" data-transition="slide" data-direction="reverse">Back</a>
<h1>Toronto CAD Map</h1>
</div>

<div id="map" data-role="content">
<div class="footer">
<div id="footer-button">
<button id="autoUpdate" onclick="toggleAutoUpdate();" class="ui-btn ui-btn-inline ui-corner-all ui-icon-location ui-btn-icon-notext"></button>
</div>
<div id="map-attribution">
<a href="http://leafletjs.com" title="A JS library for interactive maps">Leaflet</a> Map data © 2011 OpenStreetMap contributors, Imagery © 2012 CloudMade
</div>
</div>
</div>
</div>
</body>
</html>

How to get Leaflet for R use 100% of Shiny dashboard height

I personally found, that setting the height relative to window-size is more satisfying. Height as percentage does not work, because the dashboardBody has undefined height. But relative to the whole document is okay.

100% of the dashoboardBody makes 100vh (ccs3-unit) minus header (minimum 50px) minus dashboardBody padding (2* 15px).

So, set the height to 100vh - 80px and you should be fine.

Since shiny does not support css3-units, this has to be included directly to the document, like in the code below.

library(shiny)
library(shinydashboard)
library(leaflet)

ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
tags$style(type = "text/css", "#map {height: calc(100vh - 80px) !important;}"),
leafletOutput("map")
)
)

server <- function(input, output) {
output$map <- renderLeaflet({
leaflet() %>% addTiles() %>% setView(42, 16, 4)
})
}

runApp(shinyApp(ui, server), launch.browser = TRUE)

Have fun!

map does not expand to full size on load when using jquery mobile

Your #map-canvas is wrapped with div's. They must all allow to expand the height to 100%.

Correct your JSFiddle with this ...

html, body, #map-page, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}

How to stretch the map under the visible area?

I hope you found this solution useful.

let mapExtent = [0.00000000, -4100.00000000, 4100.00000000, 0.00000000];

let minZoom = 0;

let maxZoom = 6;

let maxBounds = [

[0, 0],

[-4100, 4100]

];

let mapMaxResolution = 0.2500000;

let mapMinResolution = Math.pow(2, maxZoom) * mapMaxResolution;

let crs = L.CRS.Simple;

crs.scale = function(zoom) {

console.log(zoom);

return Math.pow(2, zoom) / mapMinResolution;

};

crs.zoom = function(scale) {

return Math.log(scale * mapMinResolution) / Math.LN2;

};

let map = L.map('map', {

crs,

minZoom,

maxZoom,

maxBounds,

zoomSnap: 0, // important

maxBoundsViscosity: 1.0,

attributionControl: false,

zoomControl: true

});

L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {

attribution: '© <a href="http://openstreetmap.org">OpenStreetMap</a> contributors',

maxNativeZoom: 4,

noWrap: true,

minZoom,

maxZoom

}).addTo(map);

map.fitBounds([

crs.unproject(L.point(mapExtent[2], mapExtent[3])),

crs.unproject(L.point(mapExtent[0], mapExtent[1]))

]);

map.on('zoomend', function() {

document.querySelector('.zoom').innerText = map.getZoom();

});
html,

body {

height: 100%;

margin: 0;

}

#map {

width: 100%;

height: 100%;

}

.zoom {

font-size: 4rem;

font-weight: 700;

position: fixed;

bottom: 20px;

left: 20px;

z-index: 999;

color: #fff;

}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.css">

<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.js"></script>

<div class="zoom"></div>

<div id='map'></div>

Leaflet - Gray stripes after panning

The solution was to trigger a resizing event via window.dispatchEvent(new Event('resize')) every time the user enters the tab page holding all the tabs including the map tab.

The map is reacting to this by adjusting itself to the "new" size.

Leaflet - Map shadowed and not clickable when size is set to a percentage

The culprit is most probably:

div {
height: 100%;
width: 100%;
}

...which looks to enlarge the Leaflet attribution control over your map container as well.

This explains the "shadow" effect and loss of interactivity.

Avoid such general selector for such layout styling.



Related Topics



Leave a reply



Submit