I want to save the showing map in my div as an image. I tried the following code but it does not show the map content but just the map contollers.
I used the snippet but Actually I don't know why it doesn't show the appened picture on the snippet. it shows the appened picture (without map content) for me.
$(function () {
var map = L.map('map').setView([10.505, 20], 2);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(map);
map.zoomControl.setPosition('bottomright');
});
$("#geo-btn").on("click", function (e) {
var container = L.DomUtil.get('map');
if (container != null) {
container._leaflet_id = null;
}
var map = L.map('map').setView([10.505, 20], 2);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(map);
var states = JSON.parse(`[{
"type": "Feature",
"properties": { "party": "Republican" },
"geometry": {
"type": "Polygon",
"coordinates": [[
[-104.05, 48.99],
[-97.22, 48.98],
[-96.58, 45.94],
[-104.03, 45.94],
[-104.05, 48.99]
]]
}
}, {
"type": "Feature",
"properties": { "party": "Democrat" },
"geometry": {
"type": "Polygon",
"coordinates": [[
[-109.05, 41.00],
[-102.06, 40.99],
[-102.03, 36.99],
[-109.04, 36.99],
[-109.05, 41.00]
]]
}
}]`);
L.geoJSON(states, {
style: function (feature) {
switch (feature.properties.party) {
case 'Republican': return { color: "#ff0000" };
case 'Democrat': return { color: "#0000ff" };
}
}
}).addTo(map);
});
$("#img-save").on("click", function () {
html2canvas(document.getElementById("map")).then(canvas => {
document.body.appendChild(canvas);
});
});
#map {
height: 500px;
border: red solid 1px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9 580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ=="
crossorigin="" />
<!-- Make sure you put this AFTER Leaflet's CSS -->
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"
integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ=="
crossorigin=""></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
<title>Geo</title>
</head>
<body>
<body>
<button id="geo-btn"> Click to Show</button>
<button id="img-save">Show Image</button>
<div id="map"></div>
<div id="result-img"></div>
</body>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</html>
CodePudding user response:
I think this should work for you
$(function() {
const map = L.map('map').setView([10.505, 20], 2);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(map);
map.zoomControl.setPosition('bottomright');
});
$("#geo-btn").on("click", function(e) {
const container = L.DomUtil.get('map');
if (container != null) {
container._leaflet_id = null;
}
const map = L.map('map').setView([10.505, 20], 2);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(map);
const states = JSON.parse(`[{
"type": "Feature",
"properties": { "party": "Republican" },
"geometry": {
"type": "Polygon",
"coordinates": [[
[-104.05, 48.99],
[-97.22, 48.98],
[-96.58, 45.94],
[-104.03, 45.94],
[-104.05, 48.99]
]]
}
}, {
"type": "Feature",
"properties": { "party": "Democrat" },
"geometry": {
"type": "Polygon",
"coordinates": [[
[-109.05, 41.00],
[-102.06, 40.99],
[-102.03, 36.99],
[-109.04, 36.99],
[-109.05, 41.00]
]]
}
}]`);
L.geoJSON(states, {
style: function(feature) {
switch (feature.properties.party) {
case 'Republican':
return {
color: "#ff0000"
};
case 'Democrat':
return {
color: "#0000ff"
};
}
}
}).addTo(map);
});
$("#img-save").on("click", function() {
const clone = document.getElementById("map").cloneNode(true);
document.getElementById('foo').appendChild(clone);
});
#map {
height: 500px;
border: red solid 1px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9 580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ==" crossorigin="" />
<!-- Make sure you put this AFTER Leaflet's CSS -->
<script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ==" crossorigin=""></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
<title>Geo</title>
</head>
<body>
<button id="geo-btn"> Click to Show</button>
<button id="img-save">Show Image</button>
<div id="map"></div>
<div id="result-img"></div>
</body>
<div id="foo"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</html>
you just need these lines:
const clone = document.getElementById("map").cloneNode(true);
document.getElementById('foo').appendChild(clone);
I hope this helps
CodePudding user response:
Check out: https://jsfiddle.net/PatrickHume/1rscqwkL/1/, as the image download doesn't work in SO's code runner, click the 'Click to Show' first then click 'Show Image' and it will download the image
it uses: https://github.com/tsayen/dom-to-image and https://github.com/eligrey/FileSaver.js/
$(function() {
const map = L.map('map').setView([10.505, 20], 2);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(map);
map.zoomControl.setPosition('bottomright');
});
$("#geo-btn").on("click", function(e) {
const container = L.DomUtil.get('map');
if (container != null) {
container._leaflet_id = null;
}
const map = L.map('map').setView([10.505, 20], 2);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(map);
const states = JSON.parse(`[{
"type": "Feature",
"properties": { "party": "Republican" },
"geometry": {
"type": "Polygon",
"coordinates": [[
[-104.05, 48.99],
[-97.22, 48.98],
[-96.58, 45.94],
[-104.03, 45.94],
[-104.05, 48.99]
]]
}
}, {
"type": "Feature",
"properties": { "party": "Democrat" },
"geometry": {
"type": "Polygon",
"coordinates": [[
[-109.05, 41.00],
[-102.06, 40.99],
[-102.03, 36.99],
[-109.04, 36.99],
[-109.05, 41.00]
]]
}
}]`);
L.geoJSON(states, {
style: function(feature) {
switch (feature.properties.party) {
case 'Republican':
return {
color: "#ff0000"
};
case 'Democrat':
return {
color: "#0000ff"
};
}
}
}).addTo(map);
$("#img-save").on("click", function() {
const clone = document.getElementById("map").cloneNode(true);
document.getElementById('foo').appendChild(clone);
domtoimage.toBlob(document.getElementById('foo'))
.then(function(blob) {
window.saveAs(blob, 'my-node.png');
});
});
});
#map {
height: 500px;
border: red solid 1px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9 580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ==" crossorigin="" />
<!-- Make sure you put this AFTER Leaflet's CSS -->
<title>Geo</title>
</head>
<body>
<button id="geo-btn"> Click to Show</button>
<button id="img-save">Show Image</button>
<div id="map"></div>
<div id="result-img"></div>
</body>
<div id="foo"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ==" crossorigin=""></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
<script src="https://cdn.bootcss.com/FileSaver.js/2014-11-29/FileSaver.min.js"></script>
<script src="https://cdn.bootcss.com/dom-to-image/2.6.0/dom-to-image.min.js"></script>
</html>
Hope this helps