diff options
| author | Adam Soltys <[email protected]> | 2026-11-02 15:36:59 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-11-02 15:36:59 -0700 |
| commit | 572a291a2f4f191bb104a00cba3593c147bb8e0e (patch) | |
| tree | 42fba20ff05d2aaad146ef17f79af4259cd77ace /src/app.js | |
| parent | 4d43840fe9c50c571dbb504e3b747d79a21b2e81 (diff) | |
| download | coinosv3-572a291a2f4f191bb104a00cba3593c147bb8e0e.tar.gz coinosv3-572a291a2f4f191bb104a00cba3593c147bb8e0e.zip | |
A zoomed-in picture is drawn again at its real scale once the pinch settles, so no faint grid shows across it. "When I zoom in on my image, I see very faint grid lines. Is that a compression artifact?" (Adam, 2026-11-02): no — Chrome keeps a will-change: transform layer rastered at 1× and scales that bitmap on the GPU, and the bitmap's tiles meet in faint seams, a regular grid over the sky. The hint stays on while a gesture moves the picture (no re-raster per frame) and is dropped once it comes to rest zoomed, so Chrome rasters the picture at the scale it is shown at: sharp, and seamless. At 1× the stylesheet's hint is back for the pager's swipe
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs
Diffstat (limited to 'src/app.js')
| -rw-r--r-- | src/app.js | 10 |
1 files changed, 10 insertions, 0 deletions
@@ -648,12 +648,22 @@ function attachZoom(box, img, { wheel = true } = {}) { const mx = Math.max(0, (img.offsetWidth * s - window.innerWidth) / 2), my = Math.max(0, (img.offsetHeight * s - window.innerHeight) / 2); x = Math.min(mx, Math.max(-mx, x)); y = Math.min(my, Math.max(-my, y)); }; + // Chrome keeps a will-change: transform layer rastered at 1× and scales + // the bitmap: zoomed in, the raster's tiles show as a faint grid of + // seams across the picture ("very faint grid lines", Adam, 2026-11-02). + // The hint is on while a gesture moves the picture (no re-raster per + // frame) and off once it settles zoomed, so the picture is drawn again + // at its real scale: sharp, and seamless. + let settle = 0; const apply = (animate) => { + clearTimeout(settle); img.style.transition = animate ? 'transform .2s ease' : 'none'; img.style.transform = s === 1 && !x && !y ? '' : `translate(${x}px, ${y}px) scale(${s})`; img.style.cursor = s > 1 ? 'grab' : ''; // zoomed, the finger pans the picture; at 1× the touch is the page's (a pager's swipe) img.style.touchAction = s > 1 ? 'none' : ''; + img.style.willChange = 'transform'; + settle = setTimeout(() => { img.style.willChange = s > 1 ? 'auto' : ''; }, animate ? 250 : 120); }; // scale to ns keeping the picture point under (cx, cy) where it is const zoomAt = (ns, cx, cy) => { |
