Skip to content
Serhii Kuznetsov
All projects

073D / WebGL2026Solo — concept, design, build, deploy

KLYK-65 — Interactive 3D Keyboard

A scroll-driven WebGL landing page whose keyboard reacts to the keys you actually press.

KLYK-65 — Interactive 3D Keyboard screenshot

The problem

Every junior portfolio has landing pages in it, so another one proves nothing. I wanted a project in a genre that is hard to fake — real-time 3D — and I wanted it to be honestly mine: most WebGL showcases are a bought model with a camera orbiting it, which says more about the marketplace than about the developer.

Decisions

  1. 01

    The model is generated in code, not downloaded

    There is no GLTF, texture, image or audio file in the repository. Every part is an extruded rounded rectangle: the caps are tapered and chamfered, the case walls are one extrusion with a hole in it. A change to the layout table reshapes the model, because the geometry is a function of that table.

  2. 02

    68 caps, about a dozen draw calls

    Caps are grouped by width into one instanced mesh each. A single mesh for all of them would have to scale the spacebar 6.25x on X and stretch its corner radius into an ellipse; seven meshes keep every corner identical and still cost far less than 68 separate objects.

  3. 03

    Legends are drawn at runtime into one atlas

    All 68 legends live in a canvas texture generated in the browser and render as a single instanced quad with a shader that offsets UVs per instance. Glyphs are white and tinted per instance, so switching colourway costs an attribute update instead of a texture rebuild — and the 3D layer ships no font file.

  4. 04

    I threw out the helper library for the lighting

    The usual environment helper pulled RGBELoader, EXRLoader and a gain-map decoder into the bundle — HDRI machinery for files this page never loads. I replaced it with four emissive panels prefiltered in the browser. The 3D chunk dropped from 964 KB to 892 KB raw and the desktop score went up four points.

  5. 05

    The choreography is pure functions

    Scroll progress maps to a camera pose, an explode amount and a canvas opacity through functions that know nothing about three.js, anchored to the sections' real offsets so a section taller than the viewport cannot drag the keyframes out of step. That is what made the timeline unit testable; the scene only damps towards whatever those functions return.

  6. 06

    Phones do not get WebGL at all

    Below 768px, or without WebGL2, the same keyboard renders as server-side SVG from the same layout table — so crawlers and no-JavaScript visitors get the whole board too, and the configurator keeps working there.

What I measured

93

Lighthouse mobile

higher than desktop — phones never load three.js

74

Lighthouse desktop

0.74 s of blocking time, nearly all of it evaluating the 3D engine

0.6 s

LCP, CLS 0

the page is readable long before the scene arrives

37

tests

30 unit on layout, timeline and geometry; 7 end-to-end

Exploded view: caps, switches, plate, PCB and case
Close-up of a pressed key
Mobile fallback: the board drawn as SVG

Built with

  • Next.js
  • TypeScript
  • three.js
  • React Three Fiber
  • Tailwind CSS