| 44 | }; |
| 45 | |
| 46 | const wheelDeltaToZoomFactor = (deltaCssPx: number): number => { |
| 47 | // Positive delta = scroll down = zoom out; negative = zoom in. |
| 48 | const abs = Math.abs(deltaCssPx); |
| 49 | if (!Number.isFinite(abs) || abs === 0) return 1; |
| 50 | |
| 51 | // Cap extreme deltas (some devices can emit huge values). |
| 52 | const capped = Math.min(abs, 200); |
| 53 | const sensitivity = 0.002; |
| 54 | return Math.exp(capped * sensitivity); |
| 55 | }; |
| 56 | |
| 57 | const isMiddleButtonDrag = (e: PointerEvent): boolean => |
| 58 | e.pointerType === 'mouse' && (e.buttons & 4) !== 0; |