From 7314572d9719da1deee3eae0a4c745b47c313601 Mon Sep 17 00:00:00 2001 From: Paul Armstrong Date: Sat, 13 Feb 2021 07:24:53 -0800 Subject: [PATCH] feat(web): allow CameraImage to stretch --- web/src/components/CameraImage.jsx | 11 +++++----- .../components/__tests__/CameraImage.test.jsx | 20 ++++++++++++------- web/src/routes/Cameras.jsx | 2 +- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/web/src/components/CameraImage.jsx b/web/src/components/CameraImage.jsx index a609ac916..52f537834 100644 --- a/web/src/components/CameraImage.jsx +++ b/web/src/components/CameraImage.jsx @@ -4,7 +4,7 @@ import { useApiHost, useConfig } from '../api'; import { useCallback, useEffect, useMemo, useRef, useState } from 'preact/hooks'; import { useResizeObserver } from '../hooks'; -export default function CameraImage({ camera, onload, searchParams = '' }) { +export default function CameraImage({ camera, onload, searchParams = '', stretch = false }) { const { data: config } = useConfig(); const apiHost = useApiHost(); const [hasLoaded, setHasLoaded] = useState(false); @@ -15,11 +15,10 @@ export default function CameraImage({ camera, onload, searchParams = '' }) { const { name, width, height } = config.cameras[camera]; const aspectRatio = width / height; - const scaledHeight = useMemo(() => Math.min(Math.ceil(availableWidth / aspectRatio), height), [ - availableWidth, - aspectRatio, - height, - ]); + const scaledHeight = useMemo(() => { + const scaledHeight = Math.floor(availableWidth / aspectRatio); + return stretch ? scaledHeight : Math.min(scaledHeight, height); + }, [availableWidth, aspectRatio, height, stretch]); const scaledWidth = useMemo(() => Math.ceil(scaledHeight * aspectRatio), [scaledHeight, aspectRatio]); const img = useMemo(() => new Image(), []); diff --git a/web/src/components/__tests__/CameraImage.test.jsx b/web/src/components/__tests__/CameraImage.test.jsx index 7228a1137..3ee208438 100644 --- a/web/src/components/__tests__/CameraImage.test.jsx +++ b/web/src/components/__tests__/CameraImage.test.jsx @@ -25,12 +25,18 @@ describe('CameraImage', () => { render(); expect(screen.queryByLabelText('Loading…')).toBeInTheDocument(); - expect(screen.queryByTestId('cameraimage-canvas')).toMatchInlineSnapshot(` - - `); + const canvas = screen.queryByTestId('cameraimage-canvas'); + expect(canvas).toHaveAttribute('height', '405'); + expect(canvas).toHaveAttribute('width', '720'); + }); + + test('allows camera image to stretch to available space', async () => { + jest.spyOn(Hooks, 'useResizeObserver').mockReturnValueOnce([{ width: 1400 }]); + + render(); + expect(screen.queryByLabelText('Loading…')).toBeInTheDocument(); + const canvas = screen.queryByTestId('cameraimage-canvas'); + expect(canvas).toHaveAttribute('height', '787'); + expect(canvas).toHaveAttribute('width', '1400'); }); }); diff --git a/web/src/routes/Cameras.jsx b/web/src/routes/Cameras.jsx index 3895193db..6dc0a00cc 100644 --- a/web/src/routes/Cameras.jsx +++ b/web/src/routes/Cameras.jsx @@ -23,5 +23,5 @@ function Camera({ name }) { const href = `/cameras/${name}`; const buttons = useMemo(() => [{ name: 'Events', href: `/events?camera=${name}` }], [name]); - return } />; + return } />; }