Improve vide

This commit is contained in:
Andras Schmelczer 2026-07-14 16:22:23 +01:00
parent e544b946c9
commit 716e42a57d
7 changed files with 358 additions and 121 deletions

View file

@ -131,7 +131,8 @@ export async function smoothDragSliderThumb(
trackSelector: string,
fromCursor: { x: number; y: number },
toFraction: number,
durationMs = 520
durationMs = 520,
snapToValue?: number
): Promise<{ x: number; y: number }> {
const thumbBox = await page.locator(thumbSelector).boundingBox();
const trackBox = await page.locator(trackSelector).boundingBox();
@ -145,12 +146,45 @@ export async function smoothDragSliderThumb(
await page.mouse.down();
// The user explicitly prefers a longer render over stepped motion, so use
// enough real pointer updates for the thumb itself to read as continuous.
const dragMs = snapToValue == null ? durationMs : Math.max(200, durationMs - 400);
await smoothMove(
page,
{ x: thumbCx, y: thumbCy },
{ x: targetX, y: thumbCy },
{ durationMs, realMouse: true }
{ durationMs: dragMs, realMouse: true }
);
// Converge on the exact value WHILE the pointer is still down. A pixel
// drop lands a few steps off (thumb inset + snapping): the "20 minutes"
// drag settled on 15 and the UI contradicted the narration. Keyboard
// nudging after mouseup doesn't work here: the app's slider only accepts
// value changes inside a pointer session (onPointerDown starts the drag
// state, onPointerUp commits), so the correction must be pointer-driven.
let finalX = targetX;
if (snapToValue != null) {
const thumb = page.locator(thumbSelector);
const readAttr = async (name: string): Promise<number | null> => {
const raw = await thumb.getAttribute(name).catch(() => null);
const value = raw == null ? NaN : Number(raw);
return Number.isFinite(value) ? value : null;
};
const min = await readAttr('aria-valuemin');
const max = await readAttr('aria-valuemax');
const pxPerUnit =
min != null && max != null && max > min ? trackBox.width / (max - min) : null;
if (pxPerUnit != null) {
for (let i = 0; i < 24; i++) {
const now = await readAttr('aria-valuenow');
if (now == null || now === snapToValue) break;
let dx = (snapToValue - now) * pxPerUnit;
dx = Math.max(-60, Math.min(60, dx));
if (Math.abs(dx) < 1) dx = Math.sign(snapToValue - now);
finalX += dx;
await page.mouse.move(finalX, thumbCy, { steps: 3 });
await sleep(50);
}
}
}
await page.mouse.up();
return { x: targetX, y: thumbCy };
return { x: finalX, y: thumbCy };
}