Custom button to download a map as an image

My goal is to capture the current state of the map (including the legend) and download it as a PNG image file named “map.png”. So, i used the html2canvas library to capture the map as an image first, and then create a download link for it,”downloadBtn”, for triggering the download.

Here is the my complete code :

<!DOCTYPE html>
<html>
<head>
    <title>Leaflet Map with Rainbow Legend and Download</title>
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
    <style>
        #map {
            height: 600px;
            width: 100%;
        }
        .legend {
            background-color: white;
            padding: 10px;
            line-height: 18px;
            color: #555;
        }
        .legend i {
            width: 18px;
            height: 18px;
            float: left;
            margin-right: 8px;
            opacity: 0.7;
        }
        #downloadBtn {
            position: absolute;
            top: 10px;
            right: 10px;
            z-index: 1000;
            background-color: white;
            border: 2px solid rgba(0,0,0,0.2);
            border-radius: 4px;
            padding: 5px 10px;
            font-size: 14px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div id="map"></div>
    <button id="downloadBtn">Download Map</button>

    <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
    <script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
    <script>
        // Initialize the map
        var map = L.map('map').setView([51.505, -0.09], 13);
        // Add a base layer (e.g., OpenStreetMap)
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '© OpenStreetMap contributors'
        }).addTo(map);
        // Function to generate rainbow color based on a value between 0 and 1
        function getRainbowColor(value) {
            var hue = Math.floor((1 - value) * 240);  // 240 for blue, 0 for red
            return "hsl(" + hue + ", 100%, 50%)";     // Use HSL for hue-based color
        }
        // Create a custom legend control
        var legend = L.control({ position: 'bottomright' });
        legend.onAdd = function(map) {
            var div = L.DomUtil.create('div', 'legend');
            var labels = [];
            var grades = [0, 0.25, 0.5, 0.75, 1];  // Define the range for the legend
            // Loop through the grades and generate labels with a rainbow color
            for (var i = 0; i < grades.length; i++) {
                var color = getRainbowColor(grades[i]);
                div.innerHTML +=
                    '<i style="background:' + color + '"></i> ' +
                    grades[i] + (grades[i + 1] ? '&ndash;' + grades[i + 1] + '<br>' : '+');
            }
            return div;
        };
        // Add the legend to the map
        legend.addTo(map);

        // Function to download the map as an image
        function downloadMap() {
            html2canvas(document.getElementById('map')).then(function(canvas) {
                var link = document.createElement('a');
                link.download = 'map.png';
                link.href = canvas.toDataURL();
                link.click();
            });
        }

        // Add click event listener to the download button
        document.getElementById('downloadBtn').addEventListener('click', downloadMap);
    </script>
</body>
</html>

The downloaded image file shows a map with no actual map content loaded.
Result :
enter image description here