Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | 5x 5x 6x 6x 6x 6x 6x 6x 4x 4x 4x 6x 9x 2x 2x 7x 9x 3x 3x 9x 6x 6x 6x 2x 2x 2x 9x | import type { Map, MapMouseEvent } from 'maplibre-gl';
/**
* Time to wait for a second click before handling a click on the map.
*/
export const DOUBLE_CLICK_DELAY = 300;
export interface SingleClickOptions {
delay?: number;
/**
* Called right away on a click, so it can be shown before it is handled.
*/
preview?: (e: MapMouseEvent) => void;
/**
* Called when a previewed click turns out to be part of a double click.
*/
cancel?: () => void;
}
/**
* Handle clicks on the map that are not part of a double click, so double
* clicking still zooms in. Returns a function to remove the handler.
*/
export function onSingleClick(map: Map, handler: (e: MapMouseEvent) => void, options: SingleClickOptions = {}): () => void {
const delay = options.delay ?? DOUBLE_CLICK_DELAY;
const pending = new Set<ReturnType<typeof setTimeout>>();
const clear = () => {
pending.forEach(clearTimeout);
pending.clear();
};
const cancel = () => {
const previewed = pending.size > 0;
clear();
if (previewed) options.cancel?.();
};
const click = (e: MapMouseEvent) => {
if (isRepeatClick(e.originalEvent)) {
cancel();
return;
}
options.preview?.(e);
const timer = setTimeout(() => {
pending.delete(timer);
handler(e);
}, delay);
pending.add(timer);
};
map.on('click', click);
map.on('dblclick', cancel);
return () => {
clear();
map.off('click', click);
map.off('dblclick', cancel);
};
}
/**
* The second or later click of a double click.
*/
export function isRepeatClick(e?: Event) {
return !!e && 'detail' in e && e.type === 'click' && (e as MouseEvent).detail > 1;
}
|