A React 19 / Vite 7 application featuring a 3D rotating cube floating inside dynamic atmospheric environments. The cube is the controller — click it to cycle through 12 handpicked backgrounds. A glassmorphism HUD panel overlays the scene with live atmosphere telemetry and audio playback.
Deployed via GitHub Pages → TVATDCI/rotatingx
- Interactive 3D Cube — mouse-reactive rotation speed driven by
requestAnimationFrame; click anywhere to change the atmosphere - 12 Atmospheric Environments — space, nebula, galaxy, starfield, snowy mountains, sunset beach, Amazon forest, volcano, underwater, desert, moon surface, white diamond
- Dynamic CSS Variable System — every atmosphere overrides
--accent-color,--glow-color, and--bg-gradient; the entire UI reacts automatically with no extra prop drilling - Glassmorphism 2.0 HUD Panel —
backdrop-filter: blur(12px) saturate(180%)with a gradient mask border driven by--accent-color - HUD Telemetry — monospaced status bar showing the current atmosphere name and randomised GPS coordinates that regenerate on every environment change
- L-shaped Corner Accents — targeting-system bracket corners on the HUD panel, coloured by
--accent-color - Dual Audio System — SoundCloud widget (
MiniPlayer) and a local three-track player (MultiplePlayer) with play/pause and track switching - Pulse Micro-interaction — buttons animate a
box-shadowglow pulse on hover via akeyframesanimation that reads--glow-color - Mobile Scaling — buttons use
clamp()for fluid height and font-size across all screen sizes
| Layer | Technology |
|---|---|
| Framework | React 19.2 |
| Build tool | Vite 7.3 |
| Styling | Plain CSS (global) + styled-components v6 (component-scoped) |
| Prop validation | prop-types 15 |
| Deployment | gh-pages |
src/
├── main.jsx # App entry point
├── index.css # Global CSS variables, atmosphere themes, utility classes
├── App.jsx # Root component — owns atmosphere state via useAtmosphere
├── hooks/
│ └── useAtmosphere.js # Custom hook: background state + changeAtmosphere callback
└── components/
├── RotatingCube.jsx # 3D cube — rAF animation, mouse-reactive speed, click handler
├── RotatingCube.css # Cube identity styles — faces, perspective, exploded look
├── MultiplePlayer.jsx # HUD panel — local audio player, telemetry, corner accents
├── MiniPlayer.jsx # SoundCloud widget wrapper with atmosphere-aware styling
└── FancyButton.jsx # Reusable styled button with HUD pulse animation
- Custom Hook —
useAtmosphereencapsulates all atmosphere state and thechangeAtmospherecallback useState— tracks the active background stringuseCallback— memoiseschangeAtmosphereto prevent unnecessary re-rendersuseMemo— regenerates HUD coordinates only whencurrentAtmospherechangesuseRef— direct DOM access for cube transform and audio element managementuseEffect— manages therequestAnimationFrameanimation lifecycle- Prop drilling —
currentAtmospherepassed fromApp→MultiplePlayerfor HUD display - PropTypes — runtime prop validation on all components that accept props
useAtmosphere.js holds a background string in React state. App.jsx applies it as a class on the root <div> (e.g. <div className="app galaxy">). Each atmosphere class in index.css overrides three CSS variables:
.app.galaxy {
--bg-gradient: radial-gradient(circle, #1a2a6c, #b21f1f, #fdbb2d);
--accent-color: #fdbb2d;
--glow-color: rgba(253, 187, 45, 0.6);
}Every component that uses var(--accent-color) or var(--glow-color) updates instantly — the cube glow, button borders, HUD text, corner accents, and gradient border all react together.
RotatingCube.jsx runs a requestAnimationFrame loop that increments angle.x and angle.y each frame and writes the result directly to cube.style.transform. Moving the mouse over the scene adjusts the rotation speed in real time. Clicking anywhere on the scene calls changeAtmosphere.
MultiplePlayer receives currentAtmosphere as a prop from App.jsx. A useMemo block keyed on currentAtmosphere generates a new random lat/lon pair each time the atmosphere changes and formats it for display:
ATMOSPHERE: GALAXY | 34.7291°N 118.2435°W
git clone https://github.com/TVATDCI/rotatingx.git
cd rotatingx
npm install
npm run dev # development server
npm run build # production build
npm run preview # preview production build locally
npm run deploy # build + push to gh-pages| Phase | Summary |
|---|---|
| V1 — Modernisation | React 18→19, Vite 5→7, extracted useAtmosphere hook, removed dead components, introduced CSS variable theme system, first glassmorphism pass |
| V2 — HUD Transformation | Glassmorphism 2.0 with CSS mask gradient border, corner accents, HUD telemetry label, hudPulse animation, MiniPlayer atmosphere integration, removed all dead code, fixed rAF/CSS animation conflict, 4 post-implementation debug fixes |
-
prefers-reduced-motion— disablehudPulseand slow rAF speed for accessibility - Merge V2 debug fixes to
mainas a clean atomic commit - CSS containment (
contain: layout paint) on HUD panel for paint performance
- Canvas-based waveform / frequency bar visualiser inside the HUD panel
- Corner accents pulse in sync with audio beat detection
- Display current track title, artist, and elapsed time
- Keyboard shortcuts — space to play/pause, arrow keys to change tracks,
Rto randomise atmosphere - Click HUD coordinates to copy to clipboard
- Settings panel (gear icon) — adjustable blur amount, panel opacity, cube speed
- Fullscreen toggle
- ARIA live region announces atmosphere changes to screen readers
- Full keyboard tab navigation
- Lazy-load Unsplash background images with low-quality placeholder
-
will-change: transformon.rotating-cube
- User-customisable atmosphere combinations
- Persist preferences to
localStorage - Import / export theme JSON
Last updated: 2026-02-27 — V2 HUD Transformation complete