Revert canvas sizing to window.innerWidth/innerHeight, gate resize on width change
Deploy / deploy (push) Successful in 33s

The container-rect-based sizing (getBoundingClientRect on the parent
element) broke on real mobile Safari - the hero stopped rendering
entirely, most likely a layout-timing dependency window.innerWidth/
innerHeight never had. Revert to the simple, reliable measurement.

For the actual jump: mobile browsers only change window.innerHeight
(not width) as the address bar hides/shows during scroll, firing
`resize` with no real layout change to react to. Genuine resizes
(orientation change, desktop window drag) always change the width
too, so gate the redraw on that instead of reacting to every resize
event or trying to debounce/detect the toolbar animation itself.
This commit is contained in:
Bendik Aagaard Lynghaug
2026-08-06 16:31:29 +02:00
parent 71613b5ef5
commit e630fde200
+11 -28
View File
@@ -54,22 +54,12 @@ export class RasterizedYES {
if (this._resizeHandler) {
window.removeEventListener('resize', this._resizeHandler);
}
clearTimeout(this._resizeDebounce);
}
setupCanvas() {
const pixelRatio = window.devicePixelRatio || 1;
// Sized from the containing .hero-canvas box (CSS-driven by
// .hero-yes's 100svh), not window.innerWidth/innerHeight
// directly - mobile Safari fires `resize` continuously as the
// address bar hides/shows while scrolling, and innerHeight
// tracks that dynamic viewport. Reading the container's own
// rendered size instead means a toolbar-only resize recomputes
// to the same stable numbers (a no-op redraw) instead of
// visibly rescaling the rasterized "YES" text mid-scroll.
const rect = this.rasterCanvas.parentElement.getBoundingClientRect();
const width = rect.width;
const height = rect.height;
const width = window.innerWidth;
const height = window.innerHeight;
this.rasterCanvas.style.width = width + 'px';
this.rasterCanvas.style.height = height + 'px';
@@ -89,23 +79,16 @@ export class RasterizedYES {
this.pixelRatio = pixelRatio;
if (!this._resizeHandler) {
// Debounced, and a no-op if the size didn't actually
// change: assigning canvas.width/height clears the canvas
// even when set to its current value, and mobile Safari
// fires `resize` repeatedly *during* the address-bar
// hide/show animation (not once at the end), so an
// un-debounced handler was still clearing+redrawing on
// every one of those events even after the dimensions
// themselves became stable (see setupCanvas above).
// Mobile browsers change window.innerHeight (not width) as
// the address bar hides/shows during scroll, firing a
// `resize` with no real layout change to react to.
// Genuine resizes (orientation change, desktop window
// drag) always change the width too, so gate the redraw
// on that instead of reacting to every resize event.
this._resizeHandler = () => {
clearTimeout(this._resizeDebounce);
this._resizeDebounce = setTimeout(() => {
if (this.destroyed) return;
const rect = this.rasterCanvas.parentElement.getBoundingClientRect();
if (rect.width === this.displayWidth && rect.height === this.displayHeight) return;
this.setupCanvas();
this.rasterizeText();
}, 150);
if (window.innerWidth === this.displayWidth) return;
this.setupCanvas();
this.rasterizeText();
};
window.addEventListener('resize', this._resizeHandler);
}