diff --git a/app/components/MapLegend.tsx b/app/components/MapLegend.tsx
index c19e72a..835dfe3 100644
--- a/app/components/MapLegend.tsx
+++ b/app/components/MapLegend.tsx
@@ -35,12 +35,14 @@ export function MapLegend({
) : selectedLabel ? (
<>
Viewing {selectedLabel}
- . Click another area to change · drag to pan · scroll to zoom.
+ . Click another area to change · click-drag to pan · Ctrl+scroll or
+ pinch to zoom.
>
) : (
- Click an area to filter, or use the location filter. Drag to pan ·
- scroll or pinch to zoom.
+ Click an area to filter, or use the location filter. Click-drag to
+ pan · Ctrl+scroll or pinch to zoom · two fingers on touch. Normal
+ scroll moves the page.
)}
diff --git a/app/components/OpportunityMap.tsx b/app/components/OpportunityMap.tsx
index d574ca8..eaebc34 100644
--- a/app/components/OpportunityMap.tsx
+++ b/app/components/OpportunityMap.tsx
@@ -331,6 +331,20 @@ export function OpportunityMap({
const zoom = d3
.zoom()
.scaleExtent([1, 14])
+ // Page scroll wins for one-finger touch and normal trackpad/mouse wheel.
+ // Map pan/zoom: primary-button drag, Ctrl/Meta+wheel (pinch), two-finger touch.
+ .filter((event) => {
+ if (event.type === "wheel") {
+ // Pinch is delivered as wheel+ctrlKey; plain two-finger scroll must
+ // reach the page, so only accept modified wheel here.
+ return event.ctrlKey || event.metaKey;
+ }
+ if (event.type === "touchstart" || event.type === "touchmove") {
+ return event.touches.length >= 2;
+ }
+ // Primary mouse button drag pans the map.
+ return event.button === 0;
+ })
.on("zoom", (event) => {
zoomRoot.attr("transform", event.transform.toString());
});
@@ -398,7 +412,7 @@ export function OpportunityMap({
{isAutoFramed && (
@@ -441,7 +455,7 @@ export function OpportunityMap({