Add callback for when the mouse enters or leaves a layer

This commit is contained in:
Eli Ribble 2026-04-24 00:31:03 +00:00
parent c1a8249dc0
commit 6992031007
No known key found for this signature in database
3 changed files with 58 additions and 3 deletions

View file

@ -4,9 +4,13 @@
<script setup lang="ts">
import maplibregl from "maplibre-gl";
import { inject, onMounted, onBeforeUnmount, Ref, watch } from "vue";
import { inject, onMounted, onBeforeUnmount, Ref, useAttrs, watch } from "vue";
type LayerType = maplibregl.LayerSpecification["type"];
interface Emits {
(e: "mouseenter"): void;
(e: "mouseleave"): void;
}
export interface Props {
filter?: maplibregl.FilterSpecification;
id: string;
@ -16,11 +20,21 @@ export interface Props {
sourceLayer: string;
type: LayerType;
}
const attrs = useAttrs();
const emit = defineEmits<Emits>();
const props = withDefaults(defineProps<Props>(), {});
type OnCallbackFunc = () => void;
type RegisterOnFunc = (
eventname: string,
layerid: string,
callback: OnCallbackFunc,
) => void;
type RegisterLayerFunc = (id: string, config: any) => void;
type UnregisterLayerFunc = (id: string) => void;
const map: Ref<maplibregl.Map | null> | undefined = inject("map");
const registerOn: RegisterOnFunc | undefined = inject("registerOn");
const registerLayer: RegisterLayerFunc | undefined = inject("registerLayer");
const unregisterLayer: UnregisterLayerFunc | undefined =
inject("unregisterLayer");
@ -41,8 +55,16 @@ const getLayerConfig = (): maplibregl.LayerSpecification => {
onMounted(() => {
if (registerLayer) {
registerLayer(props.id, getLayerConfig());
} else {
console.log("registerLayer is nully");
}
if (registerOn) {
registerOn("mouseenter", props.id, () => {
emit("mouseenter");
});
}
if (registerOn) {
registerOn("mouseleave", props.id, () => {
emit("mouseleave");
});
}
});

View file

@ -42,9 +42,29 @@ const map: Ref<maplibregl.Map | null> = shallowRef(null);
provide("map", map);
// Registry for tracking child components
const ons = new Map();
const sources = new Map();
const layers = new Map();
type OnCallbackFunc = () => void;
provide(
"registerOn",
(
eventname: keyof maplibregl.MapLayerEventType,
layerid: string,
callback: OnCallbackFunc,
) => {
console.log("register map.on", eventname, layerid);
ons.set(`${eventname}.${layerid}`, {
callback: callback,
eventname: eventname,
layerid: layerid,
});
if (map.value && map.value.loaded()) {
map.value.on(eventname, layerid, callback);
}
},
);
provide("registerSource", (id: string, config: any) => {
console.log("register source", id, config);
sources.set(id, config);
@ -113,6 +133,11 @@ function initializeMap() {
_map.addLayer(config);
}
});
ons.forEach((config, id) => {
console.log("adding map.on", config.eventname, config.layerid);
_map.on(config.eventname, config.layerid, config.callback);
});
});
map.value = _map;
}

View file

@ -147,6 +147,8 @@
['zoom'],
['+', 2, ['to-number', ['get', 'resolution']]],
]"
@mouseenter="doLayerMouseEnter()"
@mouseleave="doLayerMouseLeave()"
:paint="{ 'fill-opacity': 0.4, 'fill-color': '#dc3545' }"
source="tegola"
sourceLayer="mosquito_source"
@ -274,6 +276,12 @@ onMounted(async () => {
function doClickMap(cell: string) {
router.push("/_/cell/" + cell);
}
function doLayerMouseEnter() {
console.log("enter");
}
function doLayerMouseLeave() {
console.log("leave");
}
function mapBounds(): maplibregl.LngLatBounds {
if (session.organization?.service_area) {
return boundsFromAPI(session.organization?.service_area);