From fd557a1551b2ec9d51b5346b4881e7aa98265c5e Mon Sep 17 00:00:00 2001 From: Zeb Burke-Conte Date: Fri, 11 Dec 2020 20:53:09 -0800 Subject: [PATCH] Fix mouse events on overzoomed canvas tiles When using maxZoom and maxNativeZoom to "overzoom" tiles to higher zoom levels, the existing Canvas.Tile logic incorrectly calculates where the mouse is within the tile, because it does not scale the real pixels to the canvas' pixels, which are now 2, 4, 8, etc times larger. This means that features cannot be hovered or clicked on. This commit adds logic to scale offsets and mouse locations according to the overzoom factor, which restores the behavior of non-overzoomed tiles. --- src/Leaflet.Renderer.Canvas.Tile.js | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/Leaflet.Renderer.Canvas.Tile.js b/src/Leaflet.Renderer.Canvas.Tile.js index 163b66d..5c04628 100644 --- a/src/Leaflet.Renderer.Canvas.Tile.js +++ b/src/Leaflet.Renderer.Canvas.Tile.js @@ -29,7 +29,23 @@ L.Canvas.Tile = L.Canvas.extend({ }, getOffset: function() { - return this._tileCoord.scaleBy(this._size).subtract(this._map.getPixelOrigin()); + return this._tileCoord + .scaleBy(this._size) + .multiplyBy(this.getOverZoomFactor()) + .subtract(this._map.getPixelOrigin()) + .divideBy(this.getOverZoomFactor()); + }, + + getOverZoomFactor: function() { + var numberOfZoomLevels = Math.max(0, this._map.getZoom() - this._tileCoord.z); + return Math.pow(2, numberOfZoomLevels); + }, + + getPointFromMouseEvent: function(e) { + return this._map + .mouseEventToLayerPoint(e) + .divideBy(this.getOverZoomFactor()) + .subtract(this.getOffset()); }, onAdd: L.Util.falseFn, @@ -43,7 +59,7 @@ L.Canvas.Tile = L.Canvas.extend({ }, _onClick: function (e) { - var point = this._map.mouseEventToLayerPoint(e).subtract(this.getOffset()), layer, clickedLayer; + var point = this.getPointFromMouseEvent(e), layer, clickedLayer; for (var id in this._layers) { layer = this._layers[id]; @@ -60,7 +76,7 @@ L.Canvas.Tile = L.Canvas.extend({ _onMouseMove: function (e) { if (!this._map || this._map.dragging.moving() || this._map._animatingZoom) { return; } - var point = this._map.mouseEventToLayerPoint(e).subtract(this.getOffset()); + var point = this.getPointFromMouseEvent(e); this._handleMouseHover(e, point); },