maplibregl = (await import("https://esm.sh/maplibre-gl@4.7.1")).default
map = {
const container = document.createElement("div");
container.className = "talks-map";
yield container;
const m = new maplibregl.Map({
container,
style: "https://tiles.openfreemap.org/styles/liberty",
center: [4, 46],
zoom: 3
});
m.addControl(new maplibregl.NavigationControl(), "top-right");
m.on("load", () => {
if (!talks_map_data.length) return;
const bounds = new maplibregl.LngLatBounds();
talks_map_data.forEach((t) => {
const marker = new maplibregl.Marker({ color: "#eb6864" })
.setLngLat([t.lng, t.lat])
.addTo(m);
const el = marker.getElement();
el.style.cursor = "pointer";
el.title = t.event;
let leaveTimeout = null;
el.addEventListener("mouseenter", () => {
clearTimeout(leaveTimeout);
window.__talksHoverPreview && window.__talksHoverPreview(t.alias);
});
el.addEventListener("mouseleave", () => {
// MapLibre repositions marker elements on every map render, so the
// pin can shift a pixel or two under the cursor while it's loading
// tiles, firing spurious enter/leave pairs. Debounce the "leave" so
// a near-immediate re-enter cancels it instead of flip-flopping the
// panel content.
leaveTimeout = setTimeout(() => {
window.__talksHoverEnd && window.__talksHoverEnd();
}, 150);
});
el.addEventListener("click", () => {
window.__talksSelect && window.__talksSelect(t.alias);
});
bounds.extend([t.lng, t.lat]);
});
m.fitBounds(bounds, { padding: 60, maxZoom: 8 });
});
}Talks
A selection of talks I’ve given. Hover a title to preview it, click to pin it below.
Hover or click a talk above to see it here.