From 71eab756484bf298384f5059f15d2fd86fb0b182 Mon Sep 17 00:00:00 2001 From: Alexander Danilov Date: Mon, 29 Apr 2019 19:36:08 +0300 Subject: [PATCH 01/15] Changing Canvas size when changing screen size --- src/plugin/leaflet.canvas-markers.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugin/leaflet.canvas-markers.js b/src/plugin/leaflet.canvas-markers.js index 315f50d..7476f3f 100644 --- a/src/plugin/leaflet.canvas-markers.js +++ b/src/plugin/leaflet.canvas-markers.js @@ -97,6 +97,7 @@ function layerFactory(L) { } this._update(); this._clear(); // clear layers in redraw bounds + this._updateCtx(); this._draw(); // draw layers this._redrawBounds = null; From 258ad34d98d414d64d3f9cd391c740c1e762421a Mon Sep 17 00:00:00 2001 From: Alexander Danilov Date: Sun, 28 Apr 2019 22:45:17 +0300 Subject: [PATCH 02/15] Fix typo --- src/plugin/leaflet.canvas-markers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugin/leaflet.canvas-markers.js b/src/plugin/leaflet.canvas-markers.js index 315f50d..f63280f 100644 --- a/src/plugin/leaflet.canvas-markers.js +++ b/src/plugin/leaflet.canvas-markers.js @@ -375,7 +375,7 @@ function layerFactory(L) { for (var i = 0; i < keys.length; i++) { if (groupID === keys[0]) { var add = true; - greak; + break; } } if (!add) @@ -564,7 +564,7 @@ function layerFactory(L) { var adj_x = iconSize[0] / 2; var adj_y = iconSize[1] / 2; - var anchor_y = + var ret = [({ minX: (pointPos.x - adj_x), minY: (pointPos.y - adj_y), From 5b67c61a92150ebc4ed08102b7d1592a6e7abe00 Mon Sep 17 00:00:00 2001 From: johndoe Date: Wed, 1 May 2019 12:45:50 +0300 Subject: [PATCH 03/15] fix broken removeMarker --- src/plugin/leaflet.canvas-markers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugin/leaflet.canvas-markers.js b/src/plugin/leaflet.canvas-markers.js index f63280f..bed82ed 100644 --- a/src/plugin/leaflet.canvas-markers.js +++ b/src/plugin/leaflet.canvas-markers.js @@ -521,7 +521,7 @@ function layerFactory(L) { data: marker }; - this._removeGeneric(marker, fn); + this._removeGeneric(val, fn); if (isDisplaying === true && redraw === true) { self._redraw(); From b0ab2d4b2018e49e30766a7122f62c43c3a390a0 Mon Sep 17 00:00:00 2001 From: Alexander Danilov Date: Tue, 30 Apr 2019 01:09:25 +0300 Subject: [PATCH 04/15] Preparation to support options.padding --- src/plugin/leaflet.canvas-markers.js | 46 +++++++++++++++++++--------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/plugin/leaflet.canvas-markers.js b/src/plugin/leaflet.canvas-markers.js index 315f50d..1e00c46 100644 --- a/src/plugin/leaflet.canvas-markers.js +++ b/src/plugin/leaflet.canvas-markers.js @@ -3,6 +3,13 @@ function layerFactory(L) { var CanvasIconLayer = (L.Layer ? L.Layer : L.Class).extend({ + options: { + // @option padding: Number = 0.1 + // How much to extend the clip area around the map view (relative to its size) + // e.g. 0.1 would be 10% of map view in each direction + padding: 0.1 + }, + initialize: function (options) { L.Util.setOptions(this, options); L.Util.stamp(this); @@ -39,7 +46,7 @@ function layerFactory(L) { _initContainer: function () { var container = this._container = document.createElement('canvas'); - this._map.on('viewreset', this._reset, this); + this._map.on('viewreset', this._redraw, this); this._map.on('zoom moveend', this._redraw, this); this._map.on('mousemove', this._onMouseMove, this); this._map.on('click', this._onClick, this); @@ -50,17 +57,12 @@ function layerFactory(L) { this._ctx = container.getContext('2d'); }, - _reset: function () { - this._update(); - this._updateTransform(this._center, this._zoom); - this._redraw(); - }, _updateTransform: function (center, zoom) { if (!this._map) return; var scale = this._map.getZoomScale(zoom, this._zoom), position = L.DomUtil.getPosition(this._container), - viewHalf = this._map.getSize().multiplyBy(0.5), + viewHalf = this._map.getSize().multiplyBy(0.5 + this.options.padding), currentCenterPoint = this._map.project(this._center, zoom), destCenterPoint = this._map.project(center, zoom), centerOffset = destCenterPoint.subtract(currentCenterPoint) @@ -96,6 +98,7 @@ function layerFactory(L) { this._redrawBounds.max._ceil(); } this._update(); + this._updateTransform(this._center, this._zoom); this._clear(); // clear layers in redraw bounds this._draw(); // draw layers @@ -105,7 +108,7 @@ function layerFactory(L) { delete this._markers; delete this._latlngMarkers; delete this._ctx; - this._map.off('viewreset', this._reset, this); + this._map.off('viewreset', this._redraw, this); this._map.off('zoom moveend', this._redraw, this); this._map.off('mousemove', this._onMouseMove, this); this._map.off('click', this._onClick, this); @@ -118,7 +121,7 @@ function layerFactory(L) { return; if (this._map._animatingZoom && this._bounds) { return; } - var p = 0, + var p = this.options.padding, size = this._map.getSize(), min = this._map.containerPointToLayerPoint(size.multiplyBy(-p)).round(); @@ -153,6 +156,18 @@ function layerFactory(L) { this._ctx.scale(2, 2); } }, + // @method pad(bufferRatio: Number): array + // Returns bounds created by extending or retracting the current bounds by a given ratio in each direction. + // For example, a ratio of 0.5 extends the bounds by 50% in each direction. + // Negative values will retract the bounds. + pad: function (mapBounds, bufferRatio) { + var sw = mapBounds._southWest, + ne = mapBounds._northEast, + heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio, + widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio; + + return [widthBuffer, heightBuffer]; + }, _draw: function () { var self = this; //If no markers don't draw @@ -179,13 +194,14 @@ function layerFactory(L) { tmp = []; } var mapBounds = self._map.getBounds(); + var _pad = self.pad(mapBounds, 0.1); //Only re-draw what we are showing on the map. self._latlngMarkers.search({ - minX: mapBounds.getWest(), - minY: mapBounds.getSouth(), - maxX: mapBounds.getEast(), - maxY: mapBounds.getNorth() + minX: mapBounds.getWest()-_pad[0], + minY: mapBounds.getSouth()-_pad[1], + maxX: mapBounds.getEast()+_pad[0], + maxY: mapBounds.getNorth()+_pad[1] }).forEach(function (e) { //Readjust Point Map if (!e.data._map) @@ -258,8 +274,8 @@ function layerFactory(L) { this._ctx.drawImage( marker.canvas_img, - pointPos.x - marker.options.icon.options.iconAnchor[0],//+(this._topLeftOffset?this._topLeftOffset.x/2:0), - pointPos.y - marker.options.icon.options.iconAnchor[1],//+(this._topLeftOffset?this._topLeftOffset.y/2:0), + pointPos.x - marker.options.icon.options.iconAnchor[0]-(this._topLeftOffset?this._topLeftOffset.x:0), + pointPos.y - marker.options.icon.options.iconAnchor[1]-(this._topLeftOffset?this._topLeftOffset.y:0), marker.options.icon.options.iconSize[0], marker.options.icon.options.iconSize[1] ); From 809a4e9b0d7ac63ed603f6fa1656fa962e9f0e14 Mon Sep 17 00:00:00 2001 From: Alexander Danilov Date: Tue, 30 Apr 2019 13:27:46 +0300 Subject: [PATCH 05/15] Correction marker positions when panning or resizing a window. --- src/plugin/leaflet.canvas-markers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugin/leaflet.canvas-markers.js b/src/plugin/leaflet.canvas-markers.js index 1e00c46..b24451a 100644 --- a/src/plugin/leaflet.canvas-markers.js +++ b/src/plugin/leaflet.canvas-markers.js @@ -274,8 +274,8 @@ function layerFactory(L) { this._ctx.drawImage( marker.canvas_img, - pointPos.x - marker.options.icon.options.iconAnchor[0]-(this._topLeftOffset?this._topLeftOffset.x:0), - pointPos.y - marker.options.icon.options.iconAnchor[1]-(this._topLeftOffset?this._topLeftOffset.y:0), + pointPos.x - marker.options.icon.options.iconAnchor[0]-this._map._mapPane._leaflet_pos.x-(this._topLeftOffset?this._topLeftOffset.x:0), + pointPos.y - marker.options.icon.options.iconAnchor[1]-this._map._mapPane._leaflet_pos.y-(this._topLeftOffset?this._topLeftOffset.y:0), marker.options.icon.options.iconSize[0], marker.options.icon.options.iconSize[1] ); From b2b477b06319c43f87cefc7abf001c5bc48d5aad Mon Sep 17 00:00:00 2001 From: Alexander Danilov Date: Thu, 2 May 2019 21:12:43 +0300 Subject: [PATCH 06/15] Simplification of coordinate calculation --- src/plugin/leaflet.canvas-markers.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugin/leaflet.canvas-markers.js b/src/plugin/leaflet.canvas-markers.js index b24451a..e567e70 100644 --- a/src/plugin/leaflet.canvas-markers.js +++ b/src/plugin/leaflet.canvas-markers.js @@ -272,10 +272,13 @@ function layerFactory(L) { else return; + var iconAnchor = L.point(marker.options.icon.options.iconAnchor); + var pos = this._map.containerPointToLayerPoint(pointPos.subtract(iconAnchor).subtract(this._topLeftOffset?this._topLeftOffset:L.Point(0,0))); + this._ctx.drawImage( marker.canvas_img, - pointPos.x - marker.options.icon.options.iconAnchor[0]-this._map._mapPane._leaflet_pos.x-(this._topLeftOffset?this._topLeftOffset.x:0), - pointPos.y - marker.options.icon.options.iconAnchor[1]-this._map._mapPane._leaflet_pos.y-(this._topLeftOffset?this._topLeftOffset.y:0), + pos.x, + pos.y, marker.options.icon.options.iconSize[0], marker.options.icon.options.iconSize[1] ); From 6a81b9cf7dbfb0fc0f2754931cc8d24618806bb6 Mon Sep 17 00:00:00 2001 From: johndoe Date: Wed, 1 May 2019 18:09:19 +0300 Subject: [PATCH 07/15] fix exception in mouse event handler with empty CanvasMarkerLayer `this._markers` is undefined in `_searchPoints`, called from event listeners. Now we check markers existence in the beginning of handlers. Note 1: Could be fixed in some another place: e.g. check `_markers` in `_searchPoints` ...or initialize (empty) `_markers` on CanvasMarkerLayer init Note 2: `!this._map` removed from condition in `_onMouseMove:` 'cause it's never should be true as we detach listeners on remove from map --- src/plugin/leaflet.canvas-markers.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugin/leaflet.canvas-markers.js b/src/plugin/leaflet.canvas-markers.js index bed82ed..ec34655 100644 --- a/src/plugin/leaflet.canvas-markers.js +++ b/src/plugin/leaflet.canvas-markers.js @@ -278,6 +278,8 @@ function layerFactory(L) { return this; }, _onClick: function (e) { + if (!this._markers) { return; } + var self = this; var point = e.containerPoint; @@ -298,7 +300,7 @@ function layerFactory(L) { } }, _onMouseMove: function (e) { - if (!this._map || this._map.dragging.moving() || this._map._animatingZoom) { return; } + if (!this._markers || this._map.dragging.moving() || this._map._animatingZoom) { return; } var point = e.containerPoint; this._handleMouseHover(e, point); From eab1eafb78a29501a46bb7ef4eccebc77468d78c Mon Sep 17 00:00:00 2001 From: johndoe Date: Wed, 8 May 2019 12:28:24 +0300 Subject: [PATCH 08/15] fixup! Preparation to support options.padding --- src/plugin/leaflet.canvas-markers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugin/leaflet.canvas-markers.js b/src/plugin/leaflet.canvas-markers.js index e567e70..7017bf5 100644 --- a/src/plugin/leaflet.canvas-markers.js +++ b/src/plugin/leaflet.canvas-markers.js @@ -194,7 +194,7 @@ function layerFactory(L) { tmp = []; } var mapBounds = self._map.getBounds(); - var _pad = self.pad(mapBounds, 0.1); + var _pad = self.pad(mapBounds, self.options.padding); //Only re-draw what we are showing on the map. self._latlngMarkers.search({ From ab64e182a15607424d46a6829dc82d42480fd5f3 Mon Sep 17 00:00:00 2001 From: johndoe Date: Sat, 11 May 2019 18:57:58 +0300 Subject: [PATCH 09/15] removeMarker: fix exception when CanvasMarkerLayer is not attached to map --- src/plugin/leaflet.canvas-markers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugin/leaflet.canvas-markers.js b/src/plugin/leaflet.canvas-markers.js index ec34655..b643019 100644 --- a/src/plugin/leaflet.canvas-markers.js +++ b/src/plugin/leaflet.canvas-markers.js @@ -514,7 +514,7 @@ function layerFactory(L) { if (marker["minX"]) marker = marker.data; var latlng = marker.getLatLng(); - var isDisplaying = self._map.getBounds().contains(latlng); + var isDisplaying = self._map && self._map.getBounds().contains(latlng); var val = { minX: latlng.lng, minY: latlng.lat, From 06a787334fb300dfc42d7d77a27e63e1d8ee4721 Mon Sep 17 00:00:00 2001 From: johndoe Date: Sun, 12 May 2019 11:57:08 +0300 Subject: [PATCH 10/15] fixup! fixup! Preparation to support options.padding --- src/plugin/leaflet.canvas-markers.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/plugin/leaflet.canvas-markers.js b/src/plugin/leaflet.canvas-markers.js index 7017bf5..1b2e787 100644 --- a/src/plugin/leaflet.canvas-markers.js +++ b/src/plugin/leaflet.canvas-markers.js @@ -46,8 +46,7 @@ function layerFactory(L) { _initContainer: function () { var container = this._container = document.createElement('canvas'); - this._map.on('viewreset', this._redraw, this); - this._map.on('zoom moveend', this._redraw, this); + this._map.on('zoom moveend viewreset', this._redraw, this); this._map.on('mousemove', this._onMouseMove, this); this._map.on('click', this._onClick, this); this._map.on('mouseout', this._handleMouseOut, this); @@ -108,8 +107,7 @@ function layerFactory(L) { delete this._markers; delete this._latlngMarkers; delete this._ctx; - this._map.off('viewreset', this._redraw, this); - this._map.off('zoom moveend', this._redraw, this); + this._map.off('zoom moveend viewreset', this._redraw, this); // todo: port to layers-features-back branch this._map.off('mousemove', this._onMouseMove, this); this._map.off('click', this._onClick, this); this._map.off('mouseout', this._handleMouseOut, this); From cd7d7d555df2cba7e12c01b53cc07318141cf9cc Mon Sep 17 00:00:00 2001 From: johndoe Date: Mon, 29 Apr 2019 19:04:34 +0300 Subject: [PATCH 11/15] return general Layer features lost in refactoring into Renderer Original intentions of that refactoring is not clear, perhaps it was intermediate step before transforming into true Renderer. But in current state it is not actually Renderer, so we need to revert some parts, to continue using it as independent Layer. Notes: `CanvasMarkerLayer` is still independent entity which does not fit flawlessly into Leaflet ecosystem. It would be much more convenient if instead of `CanvasMarkerLayer` we have `CanvasMarker`, able to be used as direct and transparent replacement for `L.Marker`. Though currently I am not sure how to do it best: - may be we need dedicated Renderer class - or may be it can be simpler, and all we need - `CanvasMarker` inherited from `L.Path`. --- src/plugin/leaflet.canvas-markers.js | 30 ++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/plugin/leaflet.canvas-markers.js b/src/plugin/leaflet.canvas-markers.js index 315f50d..dd8a3b6 100644 --- a/src/plugin/leaflet.canvas-markers.js +++ b/src/plugin/leaflet.canvas-markers.js @@ -8,23 +8,33 @@ function layerFactory(L) { L.Util.stamp(this); }, onAdd: function () { - if (!this._container) { + //if (!this._container) { this._initContainer(); // defined by renderer implementations if (this._zoomAnimated) { L.DomUtil.addClass(this._container, 'leaflet-zoom-animated'); } - } + //} // TODO: this is temporary fix to keep container on remove this.getPane().appendChild(this._container); L.DomUtil.toBack(this._container); this._update(); + this._updateTransform(this._center, this._zoom); // TODO: refactor all these update/redraw sequences into common functions this._updateCtx(); this._draw(); }, - onRemove: function () { + onRemove_bak: function () { this._destroyContainer(); + }, // TODO: this is temporary fix to keep container on remove + onRemove: function () { + this._map.off('viewreset', this._reset, this); + this._map.off('zoom moveend', this._redraw, this); + this._map.off('mousemove', this._onMouseMove, this); + this._map.off('click', this._onClick, this); + this._map.off('mouseout', this._handleMouseOut, this); + this._map.off('zoomanim', this._onAnimZoom, this); + this._container.remove(); }, _onAnimZoom: function (ev) { this._updateTransform(ev.center, ev.zoom); @@ -37,7 +47,7 @@ function layerFactory(L) { return {}; }, _initContainer: function () { - var container = this._container = document.createElement('canvas'); + var container = this._container = this._container || document.createElement('canvas'); // TODO: this is temporary fix to keep container on remove this._map.on('viewreset', this._reset, this); this._map.on('zoom moveend', this._redraw, this); @@ -267,14 +277,18 @@ function layerFactory(L) { _searchPoints: function (point) { return this._markers.search({ minX: point.x, minY: point.y, maxX: point.x, maxY: point.y }); }, - on: function (event, func) { + on: function (types, fn, context) { // TODO: this is temporary fix to handle all leaflet events (not only internal) + var internal = ['click', 'mouseover', 'mouseout']; var self = this; if (!self._userEvents) self._userEvents = {}; - L.Util.splitWords(event).forEach(function (e) { - self._userEvents[e] = func; + L.Util.splitWords(types).forEach(function (type) { + if (internal.indexOf(type) === -1) { + L.Evented.prototype._on.call(self, type, fn, context); + } else { + self._userEvents[type] = fn; + } }); - return this; }, _onClick: function (e) { From 4ade87994a021d5e4ac9bdfdacd538f415f531e1 Mon Sep 17 00:00:00 2001 From: johndoe Date: Sun, 12 May 2019 15:41:26 +0300 Subject: [PATCH 12/15] fix exception if image is not loaded (yet) / bad url / etc Was protected in marker add time, but not on zoom/pan Sample: ``` VM2992:16252 Uncaught DOMException: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The HTMLImageElement provided is in the 'broken' state. at NewClass._drawImage (:16252:23) at NewClass._drawMarker (:16239:22) at :16200:22 at Array.forEach () at NewClass._draw (:16179:16) at NewClass._redraw (:16077:18) at NewClass.fire (:1867:11) at NewClass._move (:5506:9) at NewClass._onZoomTransitionEnd (:5963:8) ``` --- src/plugin/leaflet.canvas-markers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugin/leaflet.canvas-markers.js b/src/plugin/leaflet.canvas-markers.js index b643019..eba2525 100644 --- a/src/plugin/leaflet.canvas-markers.js +++ b/src/plugin/leaflet.canvas-markers.js @@ -245,7 +245,7 @@ function layerFactory(L) { }); } } - } else { + } else if (self._imageLookup[marker.options.icon.options.iconUrl][1]) { // image may be not loaded / bad url self._drawImage(marker, pointPos); } }, From 7bffd6a881f41d51c6ce53d678c1c186bb7767d8 Mon Sep 17 00:00:00 2001 From: johndoe Date: Wed, 15 May 2019 13:12:28 +0300 Subject: [PATCH 13/15] fixup! fixup! fixup! Preparation to support options.padding --- src/plugin/leaflet.canvas-markers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugin/leaflet.canvas-markers.js b/src/plugin/leaflet.canvas-markers.js index 1b2e787..4f79484 100644 --- a/src/plugin/leaflet.canvas-markers.js +++ b/src/plugin/leaflet.canvas-markers.js @@ -7,7 +7,7 @@ function layerFactory(L) { // @option padding: Number = 0.1 // How much to extend the clip area around the map view (relative to its size) // e.g. 0.1 would be 10% of map view in each direction - padding: 0.1 + padding: L.Canvas.prototype.options.padding }, initialize: function (options) { From cef10c42ec86a7545961b5701d13fab6b00e516c Mon Sep 17 00:00:00 2001 From: johndoe Date: Wed, 15 May 2019 13:18:19 +0300 Subject: [PATCH 14/15] fix to expose L.CanvasIconLayer class This was originally meant but missed (see _full.js / _standalone.js) --- src/plugin/leaflet.canvas-markers.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugin/leaflet.canvas-markers.js b/src/plugin/leaflet.canvas-markers.js index eba2525..9b84b14 100644 --- a/src/plugin/leaflet.canvas-markers.js +++ b/src/plugin/leaflet.canvas-markers.js @@ -594,6 +594,8 @@ function layerFactory(L) { L.canvasIconLayer = function (options) { return new CanvasIconLayer(options); }; + + return CanvasIconLayer; }; module.exports = layerFactory; From d6e5ca5d8d922dad0fb5b80476e0792b1e5f384c Mon Sep 17 00:00:00 2001 From: johndoe Date: Wed, 15 May 2019 13:28:07 +0300 Subject: [PATCH 15/15] fix https://github.com/IITC-CE/Leaflet.Canvas-Markers/issues/11 --- src/plugin/leaflet.canvas-markers.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/plugin/leaflet.canvas-markers.js b/src/plugin/leaflet.canvas-markers.js index 2d2661e..7c92600 100644 --- a/src/plugin/leaflet.canvas-markers.js +++ b/src/plugin/leaflet.canvas-markers.js @@ -35,8 +35,7 @@ function layerFactory(L) { this._destroyContainer(); }, // TODO: this is temporary fix to keep container on remove onRemove: function () { - this._map.off('viewreset', this._reset, this); - this._map.off('zoom moveend', this._redraw, this); + this._map.off('moveend', this._redraw, this); // TODO: 'moveend' seems enough (https://github.com/IITC-CE/Leaflet.Canvas-Markers/issues/11) this._map.off('mousemove', this._onMouseMove, this); this._map.off('click', this._onClick, this); this._map.off('mouseout', this._handleMouseOut, this); @@ -56,7 +55,7 @@ function layerFactory(L) { _initContainer: function () { var container = this._container = this._container || document.createElement('canvas'); // TODO: this is temporary fix to keep container on remove - this._map.on('zoom moveend viewreset', this._redraw, this); + this._map.on('moveend', this._redraw, this); // TODO: 'moveend' seems enough (https://github.com/IITC-CE/Leaflet.Canvas-Markers/issues/11) this._map.on('mousemove', this._onMouseMove, this); this._map.on('click', this._onClick, this); this._map.on('mouseout', this._handleMouseOut, this); @@ -118,7 +117,7 @@ function layerFactory(L) { delete this._markers; delete this._latlngMarkers; delete this._ctx; - this._map.off('zoom moveend viewreset', this._redraw, this); // todo: port to layers-features-back branch + this._map.off('moveend', this._redraw, this); // TODO: 'moveend' seems enough (https://github.com/IITC-CE/Leaflet.Canvas-Markers/issues/11) this._map.off('mousemove', this._onMouseMove, this); this._map.off('click', this._onClick, this); this._map.off('mouseout', this._handleMouseOut, this);