_❯3D Computer

A retro workstation built entirely with CSS 3D transforms — no WebGL, just perspective and transform-style: preserve-3d.

CSS 3Dtransformsno-WebGLretro
Esc
1
2
3
4
5
6
7
8
9
0
-
=
Tab
q
w
e
r
t
y
u
i
o
p
[
]
Del
Caps
a
s
d
f
g
h
j
k
l
;
'
Enter
Shift
z
x
c
v
b
n
m
,
.
/
Shift
Ctrl
Alt
Space
Alt
Fn1
Fn2
Ctrl
1import { useState } from "react";
2import { Computer } from "@/components/misc/computer/computer.component";
3import { LabsDemoLayout } from "../../components/labs-experiment-frame/labs-experiment-frame.component";
4import {
5 ControlGroup,
6 ControlPanel,
7 ResetButton,
8 SliderControl,
9} from "../../components/labs-control/labs-control.component";
10import * as styles from "./computer-3d.demo.css";
11
12const DEFAULT_ROTATE = { x: 0, y: 0, z: 0 };
13const DEFAULT_SCALE = 1;
14
15export function Computer3dDemo() {
16 const [rotate, setRotate] = useState(DEFAULT_ROTATE);
17 const [scale, setScale] = useState(DEFAULT_SCALE);
18
19 const reset = () => {
20 setRotate(DEFAULT_ROTATE);
21 setScale(DEFAULT_SCALE);
22 };
23
24 return (
25 <LabsDemoLayout
26 stage={
27 <div className={styles.stageInner} style={{ transform: `scale(${scale})` }}>
28 <div
29 className={styles.wrapper3d}
30 style={{
31 transform: `rotateX(${rotate.x}deg) rotateY(${rotate.y}deg) rotateZ(${rotate.z}deg)`,
32 }}
33 >
34 <Computer />
35 </div>
36 </div>
37 }
38 controls={
39 <ControlPanel>
40 <ControlGroup title="Rotation">
41 <SliderControl
42 label="X"
43 value={rotate.x}
44 min={-180}
45 max={180}
46 onChange={(value) => setRotate((prev) => ({ ...prev, x: value }))}
47 format={(value) => `${value}°`}
48 />
49 <SliderControl
50 label="Y"
51 value={rotate.y}
52 min={-180}
53 max={180}
54 onChange={(value) => setRotate((prev) => ({ ...prev, y: value }))}
55 format={(value) => `${value}°`}
56 />
57 <SliderControl
58 label="Z"
59 value={rotate.z}
60 min={-180}
61 max={180}
62 onChange={(value) => setRotate((prev) => ({ ...prev, z: value }))}
63 format={(value) => `${value}°`}
64 />
65 </ControlGroup>
66
67 <ControlGroup title="Scale">
68 <SliderControl
69 label="Zoom"
70 value={scale}
71 min={0.1}
72 max={3}
73 step={0.1}
74 onChange={setScale}
75 format={(value) => `${value.toFixed(2)}x`}
76 />
77 </ControlGroup>
78
79 <ResetButton onReset={reset} />
80 </ControlPanel>
81 }
82 />
83 );
84}