Back to work

This portfolio

A personal site built around a WebGL portrait and oversized type. Here’s how the moving parts fit together.

This portfolio on desktop and mobile
ProjectFrontend development / 2026

Building this site

I used the free Toms Framer template as the visual and interaction reference, then rebuilt it in Next.js 16 with a static export. The layout, red portrait and oversized name follow that reference; this is an implementation study, not an original art direction.

The hero uses three.js and a custom WebGL ripple shader. Two ping-pong render targets hold the current and previous wave heights; pointer movement adds energy and clicks produce rings. The name stays selectable DOM text, with difference blending over the photograph. A static image stays visible while WebGL loads or if it fails.

The difficult part was keeping the shader’s image crop and colour treatment aligned with the static portrait, while fitting Vietnamese accents into the large name without clipping them. Resizing, touch input and lost WebGL contexts each needed a fallback that kept the page usable.

Motion handles the intro, scroll-linked headings, word reveals, hover states and tool flips. A custom lerp smooth scroll follows wheel and keyboard input; touch devices use native scrolling. Effects stay enabled under reduced motion, a deliberate choice for this site.

I kept placeholder work out of the published pages and used screenshots of the actual site below. This case study makes no claim about client work, traffic or business results.

Back to work