import React, { useCallback, useState } from "react"; import { Renderer, RendererError } from "./Renderer"; import { ShaderError } from "./Shader"; function Visualizer({ audioContext, audioNode, }: { audioContext: AudioContext; audioNode: AudioNode; }) { const [renderError, setRenderError] = useState(null); const canvas = useCallback( (canvas: HTMLCanvasElement | null) => { // If we're rendering an error message, we won't be // setting a canvas. // // Also, nonintuitively, renderError will be null here on // subsequent iterations, so we can't rely on it to // identify errors. if (canvas === null) { return; } const renderer = new Renderer(audioContext, audioNode, canvas); try { renderer.initializeScene(); } catch (error) { // Log so we don't lose the stack trace console.log(error); if (error instanceof ShaderError) { setRenderError( Failed to compile shader; This is a bug, feel free to contact me with this error message:
                                
                                    {error.message}
                                
                            
); } else if (error instanceof RendererError) { setRenderError( This browser does not support WebGL 2, sadly. This demo uses WebGL and specifically instanced drawing, so unfortunately this means it can't run on your browser/device. ); } else if (error instanceof Error) { setRenderError( Something went very wrong; apologies, either your browser is not behaving or there's a serious bug. You can contact me with this error message:
                                
                                    {error.message}
                                
                            
); } else { setRenderError( Something went very wrong; apologies, either your browser is not behaving or there's a serious bug. ); } } }, [audioContext, audioNode] ); if (renderError === null) { return ; } else { return renderError; } } export default Visualizer;