Role: UX Designer / Frontend Dev
Tech Stack: Babylon.js, WordPress (AJAX), Custom Theme (CSS + JS)
Goal: Create a seamless, immersive sci-fi themed site where page navigation feels like moving through space, not loading a new page.
📐 Concept & UX Goals
From the outset, the experience had to feel like operating a sci-fi viewscreen. Every interaction, click, scroll and transition, should feel spatial and connected. We weren’t building a site, we were building a starship UI.
Our core UX goals:
- Pages = Places: navigating to a new page would “move” the camera to a new area of the space scene
- Minimal UI: reduce visual clutter to improve immersion
- Asynchronous Loading: no full reloads, just transitions
- Scene-Integrated Navigation: content and environment exist in the same universe
🌌 Babylon.js Scene
I started by crafting a Babylon.js space environment:
- A static camera at
(0,0,0)
- Distant stars, planets, nebulae
- A configurable
offset
vector allowed us to simulate movement through the universe by shifting the rendered positions of celestial bodies
Rather than move the camera itself (which could break large-scale visual fidelity), I updated each object’s render position based on the current offset, simulating “traveling” to content.
jsCopyEditlet renderPosition = originPosition.subtract(offset);
mesh.position.copyFrom(renderPosition);
🚀 Navigating with Offset
Each WordPress page was mapped to a specific position in space. Navigating to /about
might move the scene’s offset to (5000, 0, -10000)
. I added smooth interpolation with easing so it felt like flying:
jsCopyEditoffset = BABYLON.Vector3.Lerp(offset, targetOffset, speed);
🔁 Asynchronous Content Loading
Using AJAX (wp_ajax
in PHP), I loaded pages dynamically without reloading the scene:
- All links intercepted via JavaScript
- Pages loaded via
jQuery.ajax
- The HTML content (usually
.entry-content
) was swapped into the DOM - Babylon’s update loop persisted across transitions
Each request returned HTML fragments from WordPress templates (get_template_part()
), not full pages.
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
get_template_part('template-parts/content', 'page');
}
}
🧠 UX Considerations
- Minimal layout: No bulky header or footer. Just a soft HUD-styled logo and a subtle menu tucked in the corner.
- Focus on content: Each page block hovered in the scene like a projected panel, with thin neon borders and glowing text.
- Consistent frame: Scene stayed loaded at all times, which made transitions feel native, not like switching pages.
💫 Design System
I defined reusable styles that mirrored Star Trek and Mass Effect interfaces:
- Typography:
Orbitron
,VT323
, and glowing letter shadows - Menu: A semi-transparent, floating “command stack” with expanding tree-like submenus
- Page container: 3D-transformed
<article>
blocks that could rotate slightly with scroll to simulate perspective - Animations: Fade-ins, pulse highlights on hover, glint effects on logos
🔧 Challenges
- Camera vs. Offset: Avoiding actual camera movement helped prevent precision issues at astronomical scales.
- Dynamic Element Bindings: We had to re-bind event listeners and re-init transitions after each AJAX load.
- Performance: Particle systems (like nebulae) required LOD toggling and distance culling to keep the experience smooth.
🧩 Tying It All Together
Every piece, navigation, animation, styling, and spatial layout feeds into one consistent UX metaphor:
You’re not browsing a website. You’re navigating a ship’s digital log interface.
✅ What’s Next
- Saving scene position in URL hashes or browser state
- Adding audio feedback and voice logs
- Possibly: AI-powered ambient chatter using LLM output (see /logs/building-my-first-ai-wordpress-agent-a-developers-first-experiment-with-local-llms/)