From be4e2141332e4cc2e385e18e09b083b760a3faf2 Mon Sep 17 00:00:00 2001 From: Frank Stellmacher <171614930+Psychotoxical@users.noreply.github.com> Date: Thu, 30 Apr 2026 20:19:10 +0200 Subject: [PATCH] fix(equalizer): bail out when canvas has no laid-out dimensions (#384) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drawCurve read offsetWidth/offsetHeight unconditionally. When the canvas sits inside a collapsed
(SettingsSubSection) on first paint, both are 0, innerW becomes negative, the points-loop never runs, and points[0][0] throws. Linux WebKitGTK happens to lay out the details expanded on first render; macOS WebKit does not, so the same code path unmounted the entire React tree because there is no ErrorBoundary above Settings. Bail early when innerW or innerH is non-positive — the ResizeObserver already triggers a redraw once the canvas gets real dimensions. Closes #382. --- src/components/Equalizer.tsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/components/Equalizer.tsx b/src/components/Equalizer.tsx index aedc22b2..a8629f10 100644 --- a/src/components/Equalizer.tsx +++ b/src/components/Equalizer.tsx @@ -38,10 +38,6 @@ function drawCurve(canvas: HTMLCanvasElement, gains: number[], accentColor: stri const dpr = window.devicePixelRatio || 1; const W = canvas.offsetWidth; const H = canvas.offsetHeight; - canvas.width = W * dpr; - canvas.height = H * dpr; - const ctx = canvas.getContext('2d')!; - ctx.scale(dpr, dpr); const fMin = 20, fMax = 20000; const dbMin = -13, dbMax = 13; @@ -49,6 +45,16 @@ function drawCurve(canvas: HTMLCanvasElement, gains: number[], accentColor: stri const innerW = W - padL - padR; const innerH = H - padT - padB; + // Canvas hidden or not laid out yet (e.g. inside a collapsed
on macOS WebKit). + // Bail before allocating an invalid back-buffer; ResizeObserver redraws when the canvas + // gets real dimensions. + if (innerW <= 0 || innerH <= 0) return; + + canvas.width = W * dpr; + canvas.height = H * dpr; + const ctx = canvas.getContext('2d')!; + ctx.scale(dpr, dpr); + const freqToX = (f: number) => padL + (Math.log10(f / fMin) / Math.log10(fMax / fMin)) * innerW; const dbToY = (db: number) =>