From 1d26d3facbede3bafc4f78bb339878bfc0039b93 Mon Sep 17 00:00:00 2001 From: Jungzl <13jungzl@gmail.com> Date: Thu, 23 Feb 2023 19:51:39 +0800 Subject: [PATCH 1/3] fix: `onMouseEnter` & `onMouseLeave` trigger between joined layers (#1671) --- src/mapbox/mapbox.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/mapbox/mapbox.ts b/src/mapbox/mapbox.ts index 4ed449c4d..ed1bc3524 100644 --- a/src/mapbox/mapbox.ts +++ b/src/mapbox/mapbox.ts @@ -786,6 +786,15 @@ export default class Mapbox { } }; + _uniqueLayersCount(features: MapboxGeoJSONFeature[] | null) { + if (!features) { + return 0; + } + return features.filter( + (feature, index) => features.findIndex(f => f.layer.id === feature.layer.id) === index + ).length; + } + _updateHover(e: MapMouseEvent) { const {props} = this; const shouldTrackHoveredFeatures = @@ -793,7 +802,7 @@ export default class Mapbox { if (shouldTrackHoveredFeatures) { const eventType = e.type; - const wasHovering = this._hoveredFeatures?.length > 0; + const hoveredLayersCount = this._uniqueLayersCount(this._hoveredFeatures); let features; if (eventType === 'mousemove') { try { @@ -806,14 +815,14 @@ export default class Mapbox { } else { features = []; } - const isHovering = features.length > 0; + const hoveringLayersCount = this._uniqueLayersCount(features); - if (!isHovering && wasHovering) { + if (hoveringLayersCount < hoveredLayersCount) { e.type = 'mouseleave'; this._onPointerEvent(e); } this._hoveredFeatures = features; - if (isHovering && !wasHovering) { + if (hoveringLayersCount > hoveredLayersCount) { e.type = 'mouseenter'; this._onPointerEvent(e); } From cfa48fe8a318eeb338c4c1be939500280e1a2f4f Mon Sep 17 00:00:00 2001 From: Jungzl <13jungzl@gmail.com> Date: Tue, 7 Mar 2023 10:03:54 +0800 Subject: [PATCH 2/3] fix: improve uniq func & handle edge case --- src/mapbox/mapbox.ts | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/mapbox/mapbox.ts b/src/mapbox/mapbox.ts index ed1bc3524..5668c46ba 100644 --- a/src/mapbox/mapbox.ts +++ b/src/mapbox/mapbox.ts @@ -786,13 +786,11 @@ export default class Mapbox { } }; - _uniqueLayersCount(features: MapboxGeoJSONFeature[] | null) { + _uniqueLayers(features: MapboxGeoJSONFeature[] | null) { if (!features) { - return 0; + return []; } - return features.filter( - (feature, index) => features.findIndex(f => f.layer.id === feature.layer.id) === index - ).length; + return [...new Set(features.map(f => f.layer.id))]; } _updateHover(e: MapMouseEvent) { @@ -802,7 +800,8 @@ export default class Mapbox { if (shouldTrackHoveredFeatures) { const eventType = e.type; - const hoveredLayersCount = this._uniqueLayersCount(this._hoveredFeatures); + const hoveredLayers = this._uniqueLayers(this._hoveredFeatures); + const hoveredLayersCount = hoveredLayers.length; let features; if (eventType === 'mousemove') { try { @@ -815,12 +814,21 @@ export default class Mapbox { } else { features = []; } - const hoveringLayersCount = this._uniqueLayersCount(features); + const hoveringLayers = this._uniqueLayers(features); + const hoveringLayersCount = hoveringLayers.length; if (hoveringLayersCount < hoveredLayersCount) { e.type = 'mouseleave'; this._onPointerEvent(e); } + if (hoveringLayersCount === hoveredLayersCount && hoveringLayersCount !== 0) { + if (!hoveringLayers.every(layer => hoveredLayers.includes(layer))) { + e.type = 'mouseleave'; + this._onPointerEvent(e); + e.type = 'mouseenter'; + this._onPointerEvent(e); + } + } this._hoveredFeatures = features; if (hoveringLayersCount > hoveredLayersCount) { e.type = 'mouseenter'; From b8845bfc6515ab78b560be787eb4a8948fb0066a Mon Sep 17 00:00:00 2001 From: Jungzl <13jungzl@gmail.com> Date: Tue, 7 Mar 2023 18:53:55 +0800 Subject: [PATCH 3/3] perf: array diff logic --- src/mapbox/mapbox.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mapbox/mapbox.ts b/src/mapbox/mapbox.ts index 5668c46ba..576f5525c 100644 --- a/src/mapbox/mapbox.ts +++ b/src/mapbox/mapbox.ts @@ -822,7 +822,7 @@ export default class Mapbox { this._onPointerEvent(e); } if (hoveringLayersCount === hoveredLayersCount && hoveringLayersCount !== 0) { - if (!hoveringLayers.every(layer => hoveredLayers.includes(layer))) { + if (hoveringLayers.some(layer => hoveredLayers.indexOf(layer) === -1)) { e.type = 'mouseleave'; this._onPointerEvent(e); e.type = 'mouseenter';