Skip to main content

Layer enter and leave events

Shared scripts and standalone SDK code use the MapLibre-shaped map.on('mouseenter', 'trees', listener) and map.on('mouseleave', 'trees', listener). Callers own tooltip and layer UI.

const entered = map.on('mouseenter', 'trees', event => {
  console.log(event.features[0].properties);
});
const left = map.on('mouseleave', 'trees', () => {
  console.log('Left the layer');
});
entered.unsubscribe();
left.unsubscribe();

Each listener retains its own hover state. The first valid mouse/pen movement hitting the selected layer enters; movement within its hit area does not repeatedly enter. An empty hit or a map-boundary leave exits once. Touch does not create delegated hover. Multiple IDs form a union; once and off retain the shared subscription rules.

Enter includes only selected layers' visible features; leave has an empty features array. Data is deeply frozen and retains historical camera/source/layer/feature identities. Unsubscribe, stop, rerun and destruction clear state. Removing or hiding a layer does not fabricate physical input: the next valid snapshot detects leave, and subscriptions continue following a recreated ID.

Without a selector, mouseenter/mouseleave are map-boundary notifications. Low-level PointerInput mouseleave accepts finite points outside the viewport and returns lngLat:null, features:; other input still requires logical pixels inside the viewport. Explicit query layers that do not exist still reject NOT_FOUND.

The SDK checks its 32 pending-callback budget before committing hover transitions; a rejected input cannot pretend to have transitioned. Observer failures follow existing SDK logging/common-script task termination policies. Actual query capabilities apply: common GeoJSON circle/line/fill support planar and spherical hits; arbitrary 3D occlusion and mobile application input remain pending. The same 18-check script passes native, desktop and both browser backends locally; this is not a formal release.

Naming reference: MapLibre on/off/once.

During a captured mouse drag, the SDK ends hover at the viewport boundary; releasing outside does not repeat leave. Pointer capture does not delay hover cleanup until release.