Skip to content

Instantly share code, notes, and snippets.

@donSchoe
Forked from Sumbera/L.CanvasOverlay.js
Last active August 29, 2015 14:24
Show Gist options
  • Save donSchoe/296cdc1d8d8125f33902 to your computer and use it in GitHub Desktop.
Save donSchoe/296cdc1d8d8125f33902 to your computer and use it in GitHub Desktop.

Leaflet Full view Canvas Overlay - straightforward full screen canvas overlay that calls custom user function for drawing. Mostly extracted from here: [https://github.com/Leaflet/Leaflet.heat] added resize and few other parameters for callback

	//Example:
	L.canvasOverlay()
	   .params({data: points})     // optional add any custom data that will be passed to draw function
           .drawing(drawingOnCanvas)   // set drawing function
           .addTo(leafletMap);         // add this layer to leaflet map
            

	//Custom drawing function:
		function drawingOnCanvas(canvasOverlay, params) {
	            var ctx = params.canvas.getContext('2d');
	            params.options.data.map(function (d, i) {
	              // canvas drawing goes here
	            });
	        };
	        
	// parameters passed to custom draw function :
	 {
                                canvas   : <canvas>,
                                bounds   : <bounds in WGS84>
                                size     : <view size>,
                                zoomScale: <zoom scale is  1/resolution>,
                                zoom     : <current zoom>,
                                options  : <options passed >
             };

Other useful full view Leaflet Canvas sources here:

<!doctype html>
<html>
<head>
<title>Many Points with leaflet Canvas</title>
<meta charset="utf-8">
<style>
#map {
position: absolute;
height: 100%;
width: 100%;
background-color: #333;
}
</style>
</head>
<body>
<div id="map"></div>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
<script src="L.CanvasOverlay.js"></script>
<script src="http://www.sumbera.com/gist/data.js" charset="utf-8"></script>
<script>
var points = data; // data loaded from data.js
var leafletMap = L.map('map').setView([50.00, 14.44], 9);
L.tileLayer("http://{s}.sm.mapstack.stamen.com/(toner-lite,$fff[difference],$fff[@23],$fff[hsl-saturation@20])/{z}/{x}/{y}.png")
.addTo(leafletMap);
L.canvasOverlay()
.drawing(drawingOnCanvas)
.addTo(leafletMap);
function drawingOnCanvas(canvasOverlay, params) {
var ctx = params.canvas.getContext('2d');
ctx.clearRect(0, 0, params.canvas.width, params.canvas.height);
ctx.fillStyle = "rgba(255,116,0, 0.2)";
data.map(function (d, i) {
if (params.bounds.contains([d[0], d[1]])) {
dot = canvasOverlay._map.latLngToContainerPoint([d[0], d[1]]);
ctx.beginPath();
ctx.arc(dot.x, dot.y, 3, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
}
});
};
</script>
</body>
</html>
/*
Generic Canvas Overlay for leaflet,
Stanislav Sumbera, April , 2014
- added userDrawFunc that is called when Canvas need to be redrawn
- added few useful params fro userDrawFunc callback
- fixed resize map bug
inspired & portions taken from : https://github.com/Leaflet/Leaflet.heat
*/
L.CanvasOverlay = L.Class.extend({
initialize: function (userDrawFunc, options) {
this._userDrawFunc = userDrawFunc;
L.setOptions(this, options);
},
drawing: function (userDrawFunc) {
this._userDrawFunc = userDrawFunc;
return this;
},
params:function(options){
L.setOptions(this, options);
return this;
},
canvas: function () {
return this._canvas;
},
redraw: function () {
if (!this._frame) {
this._frame = L.Util.requestAnimFrame(this._redraw, this);
}
return this;
},
onAdd: function (map) {
this._map = map;
this._canvas = L.DomUtil.create('canvas', 'leaflet-heatmap-layer');
var size = this._map.getSize();
this._canvas.width = size.x;
this._canvas.height = size.y;
var animated = this._map.options.zoomAnimation && L.Browser.any3d;
L.DomUtil.addClass(this._canvas, 'leaflet-zoom-' + (animated ? 'animated' : 'hide'));
map._panes.overlayPane.appendChild(this._canvas);
map.on('moveend', this._reset, this);
map.on('resize', this._resize, this);
if (map.options.zoomAnimation && L.Browser.any3d) {
map.on('zoomanim', this._animateZoom, this);
}
this._reset();
},
onRemove: function (map) {
map.getPanes().overlayPane.removeChild(this._canvas);
map.off('moveend', this._reset, this);
map.off('resize', this._resize, this);
if (map.options.zoomAnimation) {
map.off('zoomanim', this._animateZoom, this);
}
this_canvas = null;
},
addTo: function (map) {
map.addLayer(this);
return this;
},
_resize: function (resizeEvent) {
this._canvas.width = resizeEvent.newSize.x;
this._canvas.height = resizeEvent.newSize.y;
},
_reset: function () {
var topLeft = this._map.containerPointToLayerPoint([0, 0]);
L.DomUtil.setPosition(this._canvas, topLeft);
this._redraw();
},
_redraw: function () {
var size = this._map.getSize();
var bounds = this._map.getBounds();
var zoomScale = (size.x * 180) / (20037508.34 * (bounds.getEast() - bounds.getWest())); // resolution = 1/zoomScale
var zoom = this._map.getZoom();
// console.time('process');
if (this._userDrawFunc) {
this._userDrawFunc(this,
{
canvas :this._canvas,
bounds : bounds,
size : size,
zoomScale: zoomScale,
zoom : zoom,
options: this.options
});
}
// console.timeEnd('process');
this._frame = null;
},
_animateZoom: function (e) {
var scale = this._map.getZoomScale(e.zoom),
offset = this._map._getCenterOffset(e.center)._multiplyBy(-scale).subtract(this._map._getMapPanePos());
this._canvas.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(offset) + ' scale(' + scale + ')';
}
});
L.canvasOverlay = function (userDrawFunc, options) {
return new L.CanvasOverlay(userDrawFunc, options);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment