IkboljonMe
Yozuvlar

09.13.26Ingliz tilida2 daqiqa o‘qishThree.js · Design

A 3D desk made of boxes and cylinders

The workbench on my homepage has no 3D model file. It's built in code from primitives, loaded lazily, and turned by the scroll position.


A 3D desk made of boxes and cylinders

The homepage of this site opens on a desk: a laptop with code on the screen, a lamp, a breadboard, a notepad. It turns slowly as you scroll. There is no 3D model behind it — no Blender file, no GLTF download. Every object is a handful of primitives assembled in code with Three.js.

Primitives go a long way

  • The desktop is a rounded box; the legs are cylinders, splayed outward a few hundredths of a radian so the frame reads as furniture rather than scaffolding.
  • The laptop is two rounded boxes on a hinge, with a grid of tiny boxes for keys and a canvas texture for the screen.
  • The lamp arm is a tube swept along a curve, and the shade is an open cone.
  • The shadow on the floor comes from a real directional light, caught by an invisible plane.

Keeping it off the critical path

Three.js is several hundred kilobytes. The page should not wait for it, so the library is imported inside an effect after the hero has mounted, and the canvas fades in on its first rendered frame. The text is readable immediately; the desk arrives a moment later.

Scroll without re-renders

The hero measures how far you have scrolled through it and stores that as a number between 0 and 1 in a ref. The render loop reads the ref on every frame and turns the desk accordingly. React never re-renders while you scroll, so the page stays smooth.

typescript
rig.rotation.y = BASE_YAW + progress * 0.46
rig.position.y = 0.12 + progress * 0.18
renderer.render(scene, camera)

Respecting reduced motion

If your system asks for reduced motion, the desk still appears — it just renders a single still frame. No loop, no scroll-driven turn. The loop also pauses whenever the hero is off screen, so nothing burns battery in the background.