diff --git a/examples/web/react/app.tsx b/examples/web/react/app.tsx index 94a03925f7b1e0bfc19b2bdbb9dc4842db02bb3b..c844a19d7f0e327113bab2e447814c83526458c7 100644 --- a/examples/web/react/app.tsx +++ b/examples/web/react/app.tsx @@ -69,11 +69,14 @@ export const App: FC<AppProps> = ({ emulator, backgrounds = ["264653"] }) => { emulator.reset(); }; const onFullscreenClick = () => { - setFullscreen((!fullscreen); + setFullscreen(!fullscreen); }; const onThemeClick = () => { setBackgroundIndex((backgroundIndex + 1) % backgrounds.length); }; + const onMinimize = () => { + setFullscreen(!fullscreen); + }; const onDrawHandler = (handler: DrawHandler) => { setInterval(() => { handler(emulator.getImageBuffer(), PixelFormat.RGB); @@ -93,7 +96,11 @@ export const App: FC<AppProps> = ({ emulator, backgrounds = ["264653"] }) => { <PanelSplit left={ <div> - <Display fullscreen={fullscreen} onDrawHandler={onDrawHandler} /> + <Display + fullscreen={fullscreen} + onDrawHandler={onDrawHandler} + onMinimize={onMinimize} + /> </div> } > diff --git a/examples/web/react/components/display/display.css b/examples/web/react/components/display/display.css index fa6401a2e2b0029048e744d9b95c96292b49afe8..3ab5ca248c90e1eb5f92a0e0cacc2dd3dd89979a 100644 --- a/examples/web/react/components/display/display.css +++ b/examples/web/react/components/display/display.css @@ -15,7 +15,7 @@ z-index: 6; } -.display > .display-close { +.display > .display-minimize { bottom: 22px; display: none; position: absolute; @@ -28,12 +28,12 @@ -webkit-user-select: none; } -.display > .display-close > img { +.display > .display-minimize > img { height: 32px; width: 32px; } -.display.fullscreen > .display-close { +.display.fullscreen > .display-minimize { display: block; } @@ -41,8 +41,8 @@ background-color: #1b1a17; border: 2px solid #50cb93; font-size: 0px; - max-width: 320px; padding: 8px 8px 8px 8px; + box-sizing: content-box; } .display.fullscreen > .display-frame { diff --git a/examples/web/react/components/display/display.tsx b/examples/web/react/components/display/display.tsx index 102a09e577ba9e82ad91d82f1895df863114a507..38a921987f50ca25a97bce0f91d3a6c6052d29e6 100644 --- a/examples/web/react/components/display/display.tsx +++ b/examples/web/react/components/display/display.tsx @@ -1,4 +1,4 @@ -import React, { FC, useRef, useEffect } from "react"; +import React, { FC, useState, useRef, useEffect } from "react"; import { PixelFormat } from "../../app"; import "./display.css"; @@ -22,9 +22,10 @@ type DisplayOptions = { type DisplayProps = { options?: DisplayOptions; size?: string; - fullscreen?: boolean, + fullscreen?: boolean; style?: string[]; onDrawHandler?: (caller: DrawHandler) => void; + onMinimize?: () => void; }; type CanvasContents = { @@ -40,7 +41,8 @@ export const Display: FC<DisplayProps> = ({ size = "small", fullscreen = false, style = [], - onDrawHandler + onDrawHandler, + onMinimize }) => { options = { ...options, @@ -51,8 +53,11 @@ export const Display: FC<DisplayProps> = ({ } let canvasContents: CanvasContents | null = null; - const classes = () => ["display", fullscreen ? "fullscreen" : null, size, ...style].join(" "); + const classes = () => + ["display", fullscreen ? "fullscreen" : null, size, ...style].join(" "); + const [width, setWidth] = useState<number | undefined>(undefined); + const [height, setHeight] = useState<number | undefined>(undefined); const canvasRef = useRef<HTMLCanvasElement>(null); useEffect(() => { @@ -63,6 +68,16 @@ export const Display: FC<DisplayProps> = ({ canvasRef.current ); } + if (fullscreen) { + const [fullWidth, fullHeight] = crop( + options.width / options.height + ); + setWidth(fullWidth); + setHeight(fullHeight); + } else { + setWidth(undefined); + setHeight(undefined); + } }); if (onDrawHandler) { @@ -74,14 +89,21 @@ export const Display: FC<DisplayProps> = ({ return ( <div id="display" className={classes()}> - <span id="display-close" className="magnify-button display-close"> + <span + id="display-minimize" + className="magnify-button display-minimize" + onClick={onMinimize} + > <img className="large" src={require("./minimise.svg")} alt="minimise" /> </span> - <div className="display-frame"> + <div + className="display-frame" + style={{ width: width ?? options.width, height: height }} + > <canvas ref={canvasRef} id="display-canvas" @@ -114,6 +136,7 @@ const initCanvas = ( const videoBuffer = new DataView(imageData.data.buffer); const canvasCtx = canvas.getContext("2d")!; + canvasCtx.setTransform(1, 0, 0, 1, 0, 0); canvasCtx.scale( canvas.width / canvasBuffer.width, canvas.height / canvasBuffer.height @@ -148,4 +171,18 @@ const updateCanvas = ( canvasContents.canvasCtx.drawImage(canvasContents.canvasBuffer, 0, 0); }; +const crop = (ratio: number): [number, number] => { + // calculates the window ratio as this is fundamental to + // determine the proper way to crop the fullscreen + const windowRatio = window.innerWidth / window.innerHeight; + + // in case the window is wider (more horizontal than the base ratio) + // this means that we must crop horizontally + if (windowRatio > ratio) { + return [window.innerWidth * (ratio / windowRatio), window.innerHeight]; + } else { + return [window.innerWidth, window.innerHeight * (windowRatio / ratio)]; + } +}; + export default Display;