From 983eca9b48edeceae5ae3ba4eac48f90b7b32c5c Mon Sep 17 00:00:00 2001 From: Jasper Borsboom Date: Wed, 16 May 2018 12:39:40 +0200 Subject: [PATCH 1/2] Add support for heatmap.js layer Heatmap.js (using the leaflet plugin) uses its own canvas for rendering. if we allow leaflet-image to apply its usual logic behind canvas layers, the output is distorted. instead, i have it draw the heatmap's own exportable dataURL. I'm hoping that the way i wrote this is compatible with environments without heatmap.js. --- leaflet-image.js | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/leaflet-image.js b/leaflet-image.js index 030a2c4..44d1333 100644 --- a/leaflet-image.js +++ b/leaflet-image.js @@ -36,7 +36,18 @@ module.exports = function leafletImage(map, callback) { layerQueue.defer(handlePathRoot, map._pathRoot); } else if (map._panes) { var firstCanvas = map._panes.overlayPane.getElementsByTagName('canvas').item(0); - if (firstCanvas) { layerQueue.defer(handlePathRoot, firstCanvas); } + if (firstCanvas) { + if (firstCanvas.classList.contains("heatmap-canvas")) { + map.eachLayer(function(layer) { + if (layer._heatmap) { + layerQueue.defer(handleHeatMap, layer); + } + }); + + } else { + layerQueue.defer(handlePathRoot, firstCanvas); + } + } } map.eachLayer(drawMarkerLayer); layerQueue.awaitAll(layersDone); @@ -194,7 +205,26 @@ module.exports = function leafletImage(map, callback) { console.error('Element could not be drawn on canvas', root); // eslint-disable-line no-console } } - + + function handleHeatMap(heatmap, callback) { + var canvas = document.createElement('canvas'); + canvas.width = dimensions.x; + canvas.height = dimensions.y; + + var ctx = canvas.getContext('2d'); + + var im = new Image(); + im.crossOrigin = ''; + im.src = heatmap._heatmap.getDataURL(); + + im.onload = function() { + ctx.drawImage(im, 0, 0); + callback(null, { + canvas: canvas + }); + }; + } + function handleMarkerLayer(marker, callback) { var canvas = document.createElement('canvas'), ctx = canvas.getContext('2d'), @@ -385,4 +415,4 @@ module.exports = function leafletImage(map, callback) { })); },{}]},{},[1])(1) -}); \ No newline at end of file +}); From 46f8c34e380c1b8c555389c1c9dd577e22c919bc Mon Sep 17 00:00:00 2001 From: Jasper Borsboom Date: Wed, 16 May 2018 13:49:28 +0200 Subject: [PATCH 2/2] Fixed bug Since we want to render heatmap even if it's not the first canvas element, i have it cycle through all. this fixes an issue where if you removed the heatmap and re-added it later it wouldn't be drawn. --- leaflet-image.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/leaflet-image.js b/leaflet-image.js index 44d1333..e38fd3a 100644 --- a/leaflet-image.js +++ b/leaflet-image.js @@ -36,16 +36,19 @@ module.exports = function leafletImage(map, callback) { layerQueue.defer(handlePathRoot, map._pathRoot); } else if (map._panes) { var firstCanvas = map._panes.overlayPane.getElementsByTagName('canvas').item(0); + var canvases = map._panes.overlayPane.getElementsByTagName('canvas'); if (firstCanvas) { - if (firstCanvas.classList.contains("heatmap-canvas")) { + if (!firstCanvas.classList.contains("heatmap-canvas")) { + layerQueue.defer(handlePathRoot, firstCanvas); + } + } + for (var i = 0; i < canvases.length; i++) { + if (canvases.item(i).classList.contains("heatmap-canvas")) { map.eachLayer(function(layer) { if (layer._heatmap) { layerQueue.defer(handleHeatMap, layer); } }); - - } else { - layerQueue.defer(handlePathRoot, firstCanvas); } } }