Skip to content

Rebuild portfolio as interactive 3D corridor experience#67

Open
Mas-Hanafi wants to merge 2 commits into
JCodesMore:masterfrom
Mas-Hanafi:claude/angry-lamport-af3960
Open

Rebuild portfolio as interactive 3D corridor experience#67
Mas-Hanafi wants to merge 2 commits into
JCodesMore:masterfrom
Mas-Hanafi:claude/angry-lamport-af3960

Conversation

@Mas-Hanafi

Copy link
Copy Markdown

Summary

Replaces the placeholder Next.js scaffold with a full 3D portfolio for Imam Hanafi (Tourism Marketing Communication Specialist), inspired architecturally by itomdev.com but rebuilt from scratch to avoid the reference site's copyrighted art assets:

  • An infinite scroll-driven corridor (React Three Fiber + Three.js) with 4 doors leading to Gallery (career), Studio (AI tools), About (skills), and Contact rooms.
  • Visual style is a procedurally-generated toon + inverted-hull outline "sketch" look — no external textures, so there's no copyright exposure from the reference site's hand-drawn assets.
  • All content (name, career history, AI tools, competencies, events) is real, transcribed verbatim from the site owner's CV — not placeholder/lorem text.
  • Built via a 16-task TDD implementation plan (included at docs/superpowers/plans/2026-07-04-itom-3d-portfolio-clone.md) with spec-compliance + code-quality review at every step.

What changed

  • src/lib/corridor-math.ts — pure, fully-unit-tested scroll/door/camera math
  • src/components/canvas/materials/sketchMaterial.ts — procedural toon+outline material factories
  • src/context/SceneContext.tsx — room navigation state
  • src/hooks/useInfiniteCamera.ts, useRoomCamera.ts, useSketchMaterial.ts — R3F camera/material hooks, all with proper GPU resource disposal on unmount
  • src/components/canvas/{Door,Corridor,Experience}.tsx + rooms/{Gallery,Studio,About,Contact}Room.tsx — the 3D scene
  • src/components/dom/HUD.tsx — 2D nav overlay (accessible: aria-current, aria-label)
  • src/data/content.ts / src/types/content.ts — real CV content + types
  • src/app/page.tsx, layout.tsx — wired up, metadata derived from the same content source as the UI

Two bugs found and fixed during manual browser verification (Task 16)

Both were invisible to automated tests since no single component test exercised the full Canvas+camera composition:

  1. Camera faced the wrong direction on initial mount — Three.js's default camera orientation looks down local -Z, but all corridor content was placed at +Z. Fixed by rotating the initial camera 180° on Y.
  2. Camera never repositioned when entering a room after scrolling — the corridor's camera-driving hook unmounts when you leave for a room, leaving the camera stranded wherever it last scrolled to (up to z=118) while room content sits near z≈0. Fixed with a new useRoomCamera hook that snaps the camera to a room-viewing pose whenever a room becomes active. Also found and fixed two backface-culled planes (Gallery cards, Contact paper) that were only exposed once the camera fix made them visible.

Explicitly out of scope (documented in the plan, not silent gaps)

  • GSAP camera-zoom transition between corridor/rooms (currently an instant swap)
  • Door labels as visible 3D text (font decision deferred)
  • Audio, loading screen, mobile touch controls
  • Real contact form / drei <Text> content in rooms

Test plan

  • npm test — 29/29 tests pass
  • npm run typecheck — clean
  • npm run lint — 0 errors (1 pre-existing intentional warning: unused label prop on Door, reserved for future 3D text)
  • npm run build — production build succeeds
  • Manual browser verification: corridor renders with 4 doors, scroll moves the camera, all 4 rooms render correctly via HUD nav (both from initial position and deep-scrolled), exit returns to a visible corridor

Note: package-lock.json is not included in this PR's diff (regenerate with npm install — the lockfile diff was too large to push through the available channel in this environment). New dependencies added: three, @react-three/fiber, @react-three/drei, gsap (runtime); vitest, jsdom, @vitejs/plugin-react, @react-three/test-renderer, @testing-library/react (dev).

🤖 Generated with Claude Code

Replaces the placeholder scaffold with a React Three Fiber portfolio for
Imam Hanafi (Tourism Marketing Communication Specialist): an infinite
corridor with 4 doors leading to Gallery/Studio/About/Contact rooms,
styled with a procedurally-generated toon+outline "sketch" look (no
external art assets, avoiding the copyright issue of the reference
site's hand-drawn textures). Content is real, transcribed from the
site owner's CV.

Note: package-lock.json is not included in this commit (regenerate
with `npm install` from package.json — the lockfile diff was too large
to push via this channel). All other changed files across the 16-task
implementation plan (see docs/superpowers/plans/) are included.
…t font

Renders visible text (previously blank placeholders) using drei's Text
component: door labels on corridor sign plates, career role/org on
Gallery cards, AI tool names on Studio monitors, the profile name in
About, and email/WhatsApp on the Contact paper. Font is Caveat
(handwriting style, matching the sketch aesthetic), loaded directly
from Google Fonts' CDN rather than vendored as a binary in the repo.

Also fixes a real test regression: drei's Text does an async font
fetch that has no server to resolve against inside
@react-three/test-renderer's headless environment, which was aborting
reconciliation for entire component subtrees (not just the Text node),
zeroing out unrelated Mesh/Group count assertions in 5 previously-green
tests. Fixed with a global vitest setup file that mocks drei's Text
with a synchronous pass-through stand-in during tests only.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant