chore: added fullscreen button
032c1b6f
3 file(s) · +67 −0
| 40 | 40 | opacity: 0.8; |
|
| 41 | 41 | } |
|
| 42 | 42 | ||
| 43 | + | /* Fullscreen Button */ |
|
| 44 | + | ||
| 45 | + | .fullscreen-btn { |
|
| 46 | + | position: fixed; |
|
| 47 | + | top: 1rem; |
|
| 48 | + | left: 1rem; |
|
| 49 | + | width: 32px; |
|
| 50 | + | height: 32px; |
|
| 51 | + | background: #121113; |
|
| 52 | + | color: #ffffff; |
|
| 53 | + | border: 1px solid #333; |
|
| 54 | + | cursor: pointer; |
|
| 55 | + | display: flex; |
|
| 56 | + | align-items: center; |
|
| 57 | + | justify-content: center; |
|
| 58 | + | border-radius: 0; |
|
| 59 | + | padding: 0; |
|
| 60 | + | z-index: 10; |
|
| 61 | + | opacity: 0.7; |
|
| 62 | + | transition: opacity 0.15s, border-color 0.15s; |
|
| 63 | + | } |
|
| 64 | + | ||
| 65 | + | .fullscreen-btn:hover { |
|
| 66 | + | opacity: 1; |
|
| 67 | + | border-color: #ffffff; |
|
| 68 | + | } |
|
| 69 | + | ||
| 43 | 70 | /* Control Panel */ |
|
| 44 | 71 | ||
| 45 | 72 | .control-panel { |
| 3 | 3 | import { DEFAULT_FILTER_STATE } from "./lib/types"; |
|
| 4 | 4 | import { CameraView } from "./components/CameraView"; |
|
| 5 | 5 | import { ControlPanel } from "./components/ControlPanel"; |
|
| 6 | + | import { FullscreenButton } from "./components/FullscreenButton"; |
|
| 6 | 7 | import "./App.css"; |
|
| 7 | 8 | ||
| 8 | 9 | type Action = |
|
| 32 | 33 | return ( |
|
| 33 | 34 | <div className="app"> |
|
| 34 | 35 | <CameraView filterState={filterState} /> |
|
| 36 | + | <FullscreenButton /> |
|
| 35 | 37 | <ControlPanel |
|
| 36 | 38 | filterState={filterState} |
|
| 37 | 39 | onBasicChange={(key, value) => dispatch({ type: "SET_BASIC", key, value })} |
|
| 1 | + | import { useEffect, useState } from "react"; |
|
| 2 | + | ||
| 3 | + | export function FullscreenButton() { |
|
| 4 | + | const [isFullscreen, setIsFullscreen] = useState(false); |
|
| 5 | + | ||
| 6 | + | useEffect(() => { |
|
| 7 | + | const onChange = () => setIsFullscreen(!!document.fullscreenElement); |
|
| 8 | + | document.addEventListener("fullscreenchange", onChange); |
|
| 9 | + | return () => document.removeEventListener("fullscreenchange", onChange); |
|
| 10 | + | }, []); |
|
| 11 | + | ||
| 12 | + | const toggle = () => { |
|
| 13 | + | if (document.fullscreenElement) { |
|
| 14 | + | document.exitFullscreen(); |
|
| 15 | + | } else { |
|
| 16 | + | document.documentElement.requestFullscreen(); |
|
| 17 | + | } |
|
| 18 | + | }; |
|
| 19 | + | ||
| 20 | + | return ( |
|
| 21 | + | <button |
|
| 22 | + | className="fullscreen-btn" |
|
| 23 | + | onClick={toggle} |
|
| 24 | + | aria-label={isFullscreen ? "Exit fullscreen" : "Enter fullscreen"} |
|
| 25 | + | title={isFullscreen ? "Exit fullscreen" : "Enter fullscreen"} |
|
| 26 | + | > |
|
| 27 | + | {isFullscreen ? ( |
|
| 28 | + | <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5"> |
|
| 29 | + | <path d="M6 2v4H2M10 2v4h4M6 14v-4H2M10 14v-4h4" /> |
|
| 30 | + | </svg> |
|
| 31 | + | ) : ( |
|
| 32 | + | <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5"> |
|
| 33 | + | <path d="M2 6V2h4M14 6V2h-4M2 10v4h4M14 10v4h-4" /> |
|
| 34 | + | </svg> |
|
| 35 | + | )} |
|
| 36 | + | </button> |
|
| 37 | + | ); |
|
| 38 | + | } |