Viewer: stay sharp while zooming
Deploy web Studio / deploy (push) Successful in 1m5s

Pan/zoom gestures move the drawing as a CSS-transformed layer, a picture
at the scale last drawn. A long touchpad pinch showed an ever more
stretched, blurry view (3.6x at the end of a 1.2 s pinch), and every zoom
ended with a blur-then-snap 180 ms after its last step.

Now the view is drawn anew during the gesture once the picture is 30% off
in scale (at most every 120 ms; draw() keeps the gesture state), and at its
true scale 90 ms after the last step. Measured in Brave at 1.5x pixel
density: sharp ~130 ms instead of ~240 ms after a pinch, crisp on the way.
Cost at 6x CPU slowdown: 11.4 -> 14.6 ms per wheel step in the Studio,
9.1 -> 10.5 on a page, still no frame over 50 ms.

check_web: a long pinch is drawn anew on the way and sharp within 150 ms.
This commit is contained in:
grabowski committed 2026-10-25 16:53:10 +07:00
1 parent cddf834e56
commit ccfd619a99
3 files changed
+50 -9

No files matched your search

+22
View File
@@ -359,6 +359,28 @@ try:
check(herd == "1 bull, 1 cow, 1 calf" and abs(rot - 45) < 1e-6, f"elephants: {herd}; the lane bends at {rot} degrees")
shot(pg, "web-country.jpg")
# a long pinch (Ctrl + small wheel steps) stays sharp: the view is drawn anew during the
# gesture whenever the stretched picture is 30% off, and at its true scale soon after it ends
pg.evaluate("""() => { const svg = document.querySelector('.iso-stage .iso-svg'); window.__vbs = [];
new MutationObserver(() => __vbs.push(performance.now())).observe(svg, {attributes: true, attributeFilter: ['viewBox']}); }""")
sb = pg.locator(".iso-stage").bounding_box()
pg.mouse.move(sb["x"] + sb["width"] * 0.6, sb["y"] + sb["height"] * 0.5)
pg.keyboard.down("Control")
t0 = pg.evaluate("performance.now()")
for i in range(40):
pg.mouse.wheel(0, -8)
pg.wait_for_timeout(12)
t1 = pg.evaluate("performance.now()")
pg.keyboard.up("Control")
pg.wait_for_timeout(400)
draws = pg.evaluate("__vbs")
during = [t for t in draws if t0 <= t <= t1]
after = [t - t1 for t in draws if t > t1]
tf = pg.evaluate("document.querySelector('.iso-stage .iso-svg').style.transform")
check(len(during) >= 2 and after and after[0] < 150 and tf == "",
f"a long pinch is drawn anew {len(during)} times on the way and sharp {round(after[0]) if after else None} ms after it ends")
pg.evaluate("__studio.view.fit()")
# ---------------------------------------------------------------- a system asking for less motion
# (Windows: Animation effects off): the view starts still, but the button stays and turns it on
rctx = b.new_context(viewport={"width": 1200, "height": 800}, reduced_motion="reduce")