From 73d22f54b5ccee6800af1a6502615eefe32d4e2f Mon Sep 17 00:00:00 2001 From: Muhammad AlAref Date: Tue, 15 Oct 2024 15:57:37 -0700 Subject: [PATCH] Add id to pointer data to handle multi-touch screens --- packages/clarity-decode/src/interaction.ts | 3 ++- packages/clarity-js/src/interaction/encode.ts | 1 + packages/clarity-js/src/interaction/pointer.ts | 7 ++++++- packages/clarity-js/types/interaction.d.ts | 1 + 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/clarity-decode/src/interaction.ts b/packages/clarity-decode/src/interaction.ts index 8330ec96..7be4f5d8 100644 --- a/packages/clarity-decode/src/interaction.ts +++ b/packages/clarity-decode/src/interaction.ts @@ -17,7 +17,8 @@ export function decode(tokens: Data.Token[]): InteractionEvent { let pointerData: Interaction.PointerData = { target: tokens[2] as number, x: tokens[3] as number, - y: tokens[4] as number + y: tokens[4] as number, + id: tokens[5] as number | undefined, }; return { time, event, data: pointerData }; case Data.Event.Click: diff --git a/packages/clarity-js/src/interaction/encode.ts b/packages/clarity-js/src/interaction/encode.ts index a54d31fb..166d4c19 100644 --- a/packages/clarity-js/src/interaction/encode.ts +++ b/packages/clarity-js/src/interaction/encode.ts @@ -37,6 +37,7 @@ export default async function (type: Event, ts: number = null): Promise { tokens.push(pTarget.id); tokens.push(entry.data.x); tokens.push(entry.data.y); + if (entry.data.id !== undefined) { tokens.push(entry.data.id); } queue(tokens); baseline.track(entry.event, entry.data.x, entry.data.y); } diff --git a/packages/clarity-js/src/interaction/pointer.ts b/packages/clarity-js/src/interaction/pointer.ts index 4f5b1b01..0298bca3 100644 --- a/packages/clarity-js/src/interaction/pointer.ts +++ b/packages/clarity-js/src/interaction/pointer.ts @@ -58,8 +58,13 @@ function touch(event: Event, root: Node, evt: TouchEvent): void { x = x && frame ? x + Math.round(frame.offsetLeft) : x; y = y && frame ? y + Math.round(frame.offsetTop) : y; + // identifier is 0-based, unique for each touch point and resets when all fingers are lifted + // that is not a part of the spec, but it is how it is implemented in browsers + // tested in Chromium-based browsers as well as Firefox + const id = "identifier" in entry ? entry["identifier"] : undefined; + // Check for null values before processing this event - if (x !== null && y !== null) { handler({ time: t, event, data: { target: target(evt), x, y } }); } + if (x !== null && y !== null) { handler({ time: t, event, data: { target: target(evt), x, y, id } }); } } } } diff --git a/packages/clarity-js/types/interaction.d.ts b/packages/clarity-js/types/interaction.d.ts index a7d62418..5ea45738 100644 --- a/packages/clarity-js/types/interaction.d.ts +++ b/packages/clarity-js/types/interaction.d.ts @@ -104,6 +104,7 @@ export interface PointerData { target: Target; x: number; y: number; + id?: number; } export interface ClickData {