(e: PointerEvent)
| 1226 | }; |
| 1227 | |
| 1228 | const onPointerUp = (e: PointerEvent): void => { |
| 1229 | if (disposed) return; |
| 1230 | if (!hasClickListeners()) return; |
| 1231 | if (!e.isPrimary) return; |
| 1232 | if (!tapCandidate || e.pointerId !== tapCandidate.pointerId) return; |
| 1233 | |
| 1234 | const dt = e.timeStamp - tapCandidate.startTimeMs; |
| 1235 | const dx = e.clientX - tapCandidate.startClientX; |
| 1236 | const dy = e.clientY - tapCandidate.startClientY; |
| 1237 | const distSq = dx * dx + dy * dy; |
| 1238 | |
| 1239 | tapCandidate = null; |
| 1240 | |
| 1241 | // Release capture if we have it; suppress the resulting lostpointercapture. |
| 1242 | try { |
| 1243 | if (canvas.hasPointerCapture(e.pointerId)) { |
| 1244 | suppressNextLostPointerCaptureId = e.pointerId; |
| 1245 | canvas.releasePointerCapture(e.pointerId); |
| 1246 | } |
| 1247 | } catch { |
| 1248 | // best-effort |
| 1249 | } |
| 1250 | |
| 1251 | const maxDist = DEFAULT_TAP_MAX_DISTANCE_CSS_PX; |
| 1252 | const isTap = dt <= DEFAULT_TAP_MAX_TIME_MS && distSq <= maxDist * maxDist; |
| 1253 | if (!isTap) return; |
| 1254 | |
| 1255 | const { match } = getNearestPointFromPointerEvent(e); |
| 1256 | emit('click', buildPayload(match, e)); |
| 1257 | }; |
| 1258 | |
| 1259 | canvas.addEventListener('pointermove', onPointerMove, { passive: true }); |
| 1260 | canvas.addEventListener('pointerleave', onPointerLeave, { passive: true }); |
nothing calls this directly
no test coverage detected