feat(web): allow CameraImage to stretch

This commit is contained in:
Paul Armstrong 2021-02-13 07:24:53 -08:00 committed by Blake Blackshear
parent 52a29ed00a
commit 7314572d97
3 changed files with 19 additions and 14 deletions

View File

@ -4,7 +4,7 @@ import { useApiHost, useConfig } from '../api';
import { useCallback, useEffect, useMemo, useRef, useState } from 'preact/hooks'; import { useCallback, useEffect, useMemo, useRef, useState } from 'preact/hooks';
import { useResizeObserver } from '../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 { data: config } = useConfig();
const apiHost = useApiHost(); const apiHost = useApiHost();
const [hasLoaded, setHasLoaded] = useState(false); const [hasLoaded, setHasLoaded] = useState(false);
@ -15,11 +15,10 @@ export default function CameraImage({ camera, onload, searchParams = '' }) {
const { name, width, height } = config.cameras[camera]; const { name, width, height } = config.cameras[camera];
const aspectRatio = width / height; const aspectRatio = width / height;
const scaledHeight = useMemo(() => Math.min(Math.ceil(availableWidth / aspectRatio), height), [ const scaledHeight = useMemo(() => {
availableWidth, const scaledHeight = Math.floor(availableWidth / aspectRatio);
aspectRatio, return stretch ? scaledHeight : Math.min(scaledHeight, height);
height, }, [availableWidth, aspectRatio, height, stretch]);
]);
const scaledWidth = useMemo(() => Math.ceil(scaledHeight * aspectRatio), [scaledHeight, aspectRatio]); const scaledWidth = useMemo(() => Math.ceil(scaledHeight * aspectRatio), [scaledHeight, aspectRatio]);
const img = useMemo(() => new Image(), []); const img = useMemo(() => new Image(), []);

View File

@ -25,12 +25,18 @@ describe('CameraImage', () => {
render(<CameraImage camera="front" />); render(<CameraImage camera="front" />);
expect(screen.queryByLabelText('Loading…')).toBeInTheDocument(); expect(screen.queryByLabelText('Loading…')).toBeInTheDocument();
expect(screen.queryByTestId('cameraimage-canvas')).toMatchInlineSnapshot(` const canvas = screen.queryByTestId('cameraimage-canvas');
<canvas expect(canvas).toHaveAttribute('height', '405');
data-testid="cameraimage-canvas" expect(canvas).toHaveAttribute('width', '720');
height="405" });
width="720"
/> test('allows camera image to stretch to available space', async () => {
`); jest.spyOn(Hooks, 'useResizeObserver').mockReturnValueOnce([{ width: 1400 }]);
render(<CameraImage camera="front" stretch />);
expect(screen.queryByLabelText('Loading…')).toBeInTheDocument();
const canvas = screen.queryByTestId('cameraimage-canvas');
expect(canvas).toHaveAttribute('height', '787');
expect(canvas).toHaveAttribute('width', '1400');
}); });
}); });

View File

@ -23,5 +23,5 @@ function Camera({ name }) {
const href = `/cameras/${name}`; const href = `/cameras/${name}`;
const buttons = useMemo(() => [{ name: 'Events', href: `/events?camera=${name}` }], [name]); const buttons = useMemo(() => [{ name: 'Events', href: `/events?camera=${name}` }], [name]);
return <Card buttons={buttons} href={href} header={name} media={<CameraImage camera={name} />} />; return <Card buttons={buttons} href={href} header={name} media={<CameraImage camera={name} stretch />} />;
} }