chore: added fullscreen button 032c1b6f
Steve · 2026-05-03 13:26 3 file(s) · +67 −0
src/App.css +27 −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 {
src/App.tsx +2 −0
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 })}
src/components/FullscreenButton.tsx (added) +38 −0
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 +
}