diff --git a/packages/webamp/js/components/Vis.tsx b/packages/webamp/js/components/Vis.tsx index 438773b1..70154296 100644 --- a/packages/webamp/js/components/Vis.tsx +++ b/packages/webamp/js/components/Vis.tsx @@ -54,10 +54,10 @@ export default function Vis({ analyser }: Props) { const audioStatus = useTypedSelector(Selectors.getMediaStatus); const getWindowShade = useTypedSelector(Selectors.getWindowShade); const getWindowOpen = useTypedSelector(Selectors.getWindowOpen); - const isMWOpen = getWindowOpen("main"); + const isMWOpen = getWindowOpen("main") ?? false; const doubled = useTypedSelector(Selectors.getDoubled); const toggleVisualizerStyle = useActionCreator(Actions.toggleVisualizerStyle); - const windowShade = getWindowShade("main"); + const windowShade = getWindowShade("main") ?? false; const smallVis = windowShade && isMWOpen; const renderHeight = smallVis ? 5 : 16; @@ -81,16 +81,17 @@ export default function Vis({ analyser }: Props) { //? painter administration const painter = useMemo(() => { if (!canvas) return null; + const modeValue: "bars" | "oscilloscope" | "none" = + mode === VISUALIZERS.BAR + ? "bars" + : mode === VISUALIZERS.OSCILLOSCOPE + ? "oscilloscope" + : "none"; const cfg = { canvas, analyser, colors, - mode: - mode === VISUALIZERS.BAR - ? "bars" - : mode === VISUALIZERS.OSCILLOSCOPE - ? "oscilloscope" - : "none", + mode: modeValue, renderHeight, smallVis, pixelDensity, @@ -99,7 +100,7 @@ export default function Vis({ analyser }: Props) { peaks: true, oscStyle: "lines", bandwidth: "wide", - coloring: "normal", + coloring: "line", }; return createVisualizerEngine(cfg); }, [ @@ -107,12 +108,6 @@ export default function Vis({ analyser }: Props) { canvas, mode, colors, - renderHeight, - smallVis, - pixelDensity, - doubled, - isMWOpen, - smallVis, ]); // reacts to changes in doublesize mode @@ -133,6 +128,18 @@ export default function Vis({ analyser }: Props) { // eslint-disable-next-line react-hooks/exhaustive-deps }, [doubled, canvas, painter]); + // updates painter configuration when layout changes (windowShade, main window open/closed) + // without recreating the painter, preserving visualizer state + useEffect(() => { + if (painter) { + painter.updateConfig({ + doubled, + isMWOpen, + smallVis, + }); + } + }, [doubled, isMWOpen, smallVis, painter]); + useEffect(() => { if (canvas == null || painter == null) { return; diff --git a/packages/webamp/js/components/VisualizerEngine.ts b/packages/webamp/js/components/VisualizerEngine.ts index f79061be..fc3101c8 100644 --- a/packages/webamp/js/components/VisualizerEngine.ts +++ b/packages/webamp/js/components/VisualizerEngine.ts @@ -48,8 +48,8 @@ export function createVisualizerEngine(cfg: VEConfig) { const INITIAL_KICK_OFF = 3.0; - const doubleSized = !!cfg.doubled; - const isMWOpen = !!cfg.isMWOpen; + let doubleSized = !!cfg.doubled; + let isMWOpen = !!cfg.isMWOpen; const visMode = cfg.mode === "oscilloscope" ? 1 : cfg.mode === "bars" ? 0 : -1; const visOscStyle = @@ -61,7 +61,7 @@ export function createVisualizerEngine(cfg: VEConfig) { ? 2 : 0; const saColorMode = coloring === "normal" ? 0 : coloring === "fire" ? 1 : 2; - const windowShaded = smallVis; + let windowShaded = smallVis; const peaks = !!cfg.peaks; const wideBars = cfg.bandwidth === "wide" ? 1 : 0; @@ -783,5 +783,21 @@ export function createVisualizerEngine(cfg: VEConfig) { ctx.putImageData(myImageData, 0, 0); } - return { prepare, paintFrame }; + function updateConfig(newCfg: Partial) { + // Update mutable configuration values that can change without recreating the painter + if (newCfg.doubled !== undefined) { + doubleSized = !!newCfg.doubled; + prepare(); // recalculate buffer size + } + if (newCfg.isMWOpen !== undefined) { + isMWOpen = !!newCfg.isMWOpen; + prepare(); // recalculate buffer size + } + if (newCfg.smallVis !== undefined) { + windowShaded = !!newCfg.smallVis; + prepare(); // recalculate buffer size + } + } + + return { prepare, paintFrame, updateConfig }; }