Hacky demo changes

This commit is contained in:
Andras Schmelczer 2026-05-06 19:36:04 +01:00
parent 7cba369308
commit ea7afd618c
39 changed files with 2041 additions and 745 deletions

View file

@ -12,30 +12,22 @@ export const sleep = (ms: number) =>
export const easeInOut = (t: number): number =>
t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
// Slight overshoot then settle — gives clicks a tactile feel when paired with ripple.
export const easeOutBack = (t: number): number => {
const c1 = 1.70158;
const c3 = c1 + 1;
return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);
};
interface MoveOptions {
durationMs?: number;
ease?: (t: number) => number;
realMouse?: boolean;
/**
* Override the per-step CDP cost used to size the loop. Default 35ms is
* right for free cursor moves. During a drag, every mouse.move fires a
* pointermove React re-render thumb position update on the same
* thread, pushing effective per-step cost to ~100ms. Pass that for drags
* Override the per-step CDP cost used to size the loop. During a drag, every
* mouse.move fires a pointermove -> React re-render -> thumb position update
* on the same thread, pushing effective per-step cost higher. Pass that for drags
* so the loop's wall duration matches `durationMs * RECORD_SCALE`.
*/
stepBudgetMs?: number;
}
// Empirical Playwright→Chromium CDP roundtrip cost for a mouse.move command
// while recording the 4K, software-GL dashboard. It is much higher than a
// simple page because every move competes with map rendering and video capture.
const CDP_MOVE_MS = 90;
// Empirical Playwright-to-Chromium CDP roundtrip cost for a mouse.move command
// while recording the software-GL dashboard.
const CDP_MOVE_MS = 70;
/**
* Move the real mouse from its current position to (x, y) along an eased path.
@ -51,10 +43,36 @@ export async function smoothMove(
page: Page,
from: { x: number; y: number },
to: { x: number; y: number },
{ durationMs = 600, ease = easeInOut, stepBudgetMs = CDP_MOVE_MS }: MoveOptions = {}
{
durationMs = 600,
ease = easeInOut,
realMouse = false,
stepBudgetMs = CDP_MOVE_MS,
}: MoveOptions = {}
): Promise<void> {
const wallDuration = durationMs * RECORD_SCALE;
const steps = Math.max(2, Math.min(28, Math.round(wallDuration / stepBudgetMs)));
if (!realMouse) {
const animated = await page.evaluate(
({ x, y, wallDuration }) => {
const move = (
window as typeof window & {
__demoMoveCursor?: (x: number, y: number, durationMs: number) => void;
}
).__demoMoveCursor;
if (!move) return false;
move(x, y, wallDuration);
return true;
},
{ x: to.x, y: to.y, wallDuration }
);
if (animated) {
await new Promise((resolve) => setTimeout(resolve, wallDuration));
await page.mouse.move(to.x, to.y);
return;
}
}
const steps = Math.max(2, Math.min(96, Math.round(wallDuration / stepBudgetMs)));
for (let i = 1; i <= steps; i++) {
const t = ease(i / steps);
const x = from.x + (to.x - from.x) * t;
@ -76,7 +94,7 @@ export async function fakeType(
delayMs: number
): Promise<void> {
const delay = delayMs * RECORD_SCALE;
const steps = Math.min(6, text.length);
const steps = text.length;
for (let i = 1; i <= steps; i++) {
const end = Math.ceil((text.length * i) / steps);
await page.evaluate(
@ -121,14 +139,13 @@ export async function smoothDragSliderThumb(
// smoothMove already applies RECORD_SCALE internally; pass human-time durations.
await smoothMove(page, fromCursor, { x: thumbCx, y: thumbCy }, { durationMs: 220 });
await page.mouse.down();
// Keep the drag to a few pointer updates. The map will redraw after commit;
// asking React/deck.gl for dozens of intermediate travel-time states is what
// made previous renders crawl and look stuttery.
// The user explicitly prefers a longer render over stepped motion, so use
// enough real pointer updates for the thumb itself to read as continuous.
await smoothMove(
page,
{ x: thumbCx, y: thumbCy },
{ x: targetX, y: thumbCy },
{ durationMs, stepBudgetMs: 360 }
{ durationMs, realMouse: true, stepBudgetMs: 135 }
);
await page.mouse.up();
return { x: targetX, y: thumbCy };