refactor(web): render CameraImage to a canvas

This commit is contained in:
Paul Armstrong 2021-01-31 16:43:12 -08:00 committed by Blake Blackshear
parent d285ff7e54
commit 880178d62e

View File

@ -7,8 +7,9 @@ export default function CameraImage({ camera, onload, searchParams = '' }) {
const { data: config } = useConfig(); const { data: config } = useConfig();
const apiHost = useApiHost(); const apiHost = useApiHost();
const [availableWidth, setAvailableWidth] = useState(0); const [availableWidth, setAvailableWidth] = useState(0);
const [loadedSrc, setLoadedSrc] = useState(null); const [hasLoaded, setHasLoaded] = useState(false);
const containerRef = useRef(null); const containerRef = useRef(null);
const canvasRef = useRef(null);
const { name, width, height } = config.cameras[camera]; const { name, width, height } = config.cameras[camera];
const aspectRatio = width / height; const aspectRatio = width / height;
@ -35,15 +36,17 @@ export default function CameraImage({ camera, onload, searchParams = '' }) {
aspectRatio, aspectRatio,
height, height,
]); ]);
const scaledWidth = useMemo(() => Math.ceil(scaledHeight * aspectRatio), [scaledHeight, aspectRatio]);
const img = useMemo(() => new Image(), [camera]); const img = useMemo(() => new Image(), [camera]);
img.onload = useCallback( img.onload = useCallback(
(event) => { (event) => {
const src = event.srcElement.currentSrc; setHasLoaded(true);
setLoadedSrc(src); const ctx = canvasRef.current.getContext('2d');
ctx.drawImage(img, 0, 0, scaledWidth, scaledHeight);
onload && onload(event); onload && onload(event);
}, },
[searchParams, onload] [setHasLoaded, onload, canvasRef.current]
); );
useEffect(() => { useEffect(() => {
@ -54,12 +57,13 @@ export default function CameraImage({ camera, onload, searchParams = '' }) {
}, [apiHost, name, img, searchParams, scaledHeight]); }, [apiHost, name, img, searchParams, scaledHeight]);
return ( return (
<div ref={containerRef}> <div className="relative" ref={containerRef}>
{loadedSrc ? ( <canvas height={scaledHeight} ref={canvasRef} width={scaledWidth} />
<img width={scaledHeight * aspectRatio} height={scaledHeight} src={loadedSrc} alt={name} /> {!hasLoaded ? (
) : ( <div className="absolute inset-0 flex justify-center" style={`height: ${scaledHeight}px`}>
<ActivityIndicator /> <ActivityIndicator />
)} </div>
) : null}
</div> </div>
); );
} }