feat: build responsive Three.js river journey

This commit is contained in:
2026-09-05 17:22:12 +08:00
parent 637da07c9e
commit f6228f8507
5 changed files with 420 additions and 215 deletions

View File

@@ -1,16 +1,25 @@
'use client';
import React from 'react';
import Image from 'next/image';
import { AboutRiverScene } from './scenes/AboutRiverScene';
import styles from './RiverJourney.module.css';
const steps = [
{ number: '05', title: 'Product Engineer', description: 'Merging product strategy with engineering to ship impactful products.' },
{ number: '04', title: 'Software Engineer', description: 'Engineered scalable applications and delivered real-world solutions.' },
{ number: '03', title: 'Computer Science', description: 'Built strong foundations in algorithms and systems thinking.' },
{ number: '02', title: 'UI/UX Designer', description: 'Designed intuitive interfaces and user-centered experiences.' },
{ number: '01', title: 'Digital Artist', description: 'Explored visual design, illustration and storytelling.' },
];
export const RiverJourney: React.FC = () => {
return (
<section id="about" className={styles.journeySection}>
<section id="about" className={styles.journeySection} aria-labelledby="about-title">
<AboutRiverScene />
{/* Intro Header & Description on the Left */}
<div className={styles.introBlock}>
<span className={styles.eyebrow}>ABOUT ME</span>
<h2 className={styles.heading}>From Pixel to Product</h2>
<h2 id="about-title" className={styles.heading}>From Pixel to Product</h2>
<div className={styles.underlineBar} />
<p className={styles.description}>
I began as a digital artist, designing visual stories. Curiosity turned
@@ -20,97 +29,17 @@ export const RiverJourney: React.FC = () => {
</p>
</div>
{/* 5 Freely Positioned Milestones along the River */}
{/* Step 05: Product Engineer */}
<div className={styles.step05Graphic}>
<Image
src="/assets/step-05-product-engineer.png"
alt="Product Engineer Milestone"
width={180}
height={240}
className={styles.islandImage}
/>
</div>
<div className={styles.step05Text}>
<div className={styles.stepNumber}>05</div>
<h3 className={styles.stepTitle}>Product Engineer</h3>
<p className={styles.stepDesc}>
Merging product strategy with engineering to ship impactful products.
</p>
</div>
{/* Step 04: Software Engineer */}
<div className={styles.step04Text}>
<div className={styles.stepNumber}>04</div>
<h3 className={styles.stepTitle}>Software Engineer</h3>
<p className={styles.stepDesc}>
Engineered scalable applications and delivered real-world solutions.
</p>
</div>
<div className={styles.step04Graphic}>
<Image
src="/assets/step-04-software-engineer.png"
alt="Software Engineer Milestone"
width={250}
height={220}
className={styles.islandImage}
/>
</div>
{/* Step 03: Computer Science */}
<div className={styles.step03Text}>
<div className={styles.stepNumber}>03</div>
<h3 className={styles.stepTitle}>Computer Science</h3>
<p className={styles.stepDesc}>
Built strong foundations in algorithms and systems thinking.
</p>
</div>
<div className={styles.step03Graphic}>
<Image
src="/assets/step-02-computer-science.png"
alt="Computer Science Milestone"
width={240}
height={220}
className={styles.islandImage}
/>
</div>
{/* Step 02: UI/UX Designer */}
<div className={styles.step02Text}>
<div className={styles.stepNumber}>02</div>
<h3 className={styles.stepTitle}>UI/UX Designer</h3>
<p className={styles.stepDesc}>
Designed Intuitive interfaces and user-centered experiences.
</p>
</div>
<div className={styles.step02Graphic}>
<Image
src="/assets/step-03-ui-ux-designer.png"
alt="UI/UX Designer Milestone"
width={210}
height={200}
className={styles.islandImage}
/>
</div>
{/* Step 01: Digital Artist */}
<div className={styles.step01Text}>
<div className={styles.stepNumber}>01</div>
<h3 className={styles.stepTitle}>Digital Artist</h3>
<p className={styles.stepDesc}>
Explored visual design, illustration and storytelling.
</p>
</div>
<div className={styles.step01Graphic}>
<Image
src="/assets/step-01-digital-artist.png"
alt="Digital Artist Milestone"
width={230}
height={200}
className={styles.islandImage}
/>
</div>
<ol className={styles.stepsList} aria-label="Career journey">
{steps.map((step) => (
<li key={step.number} className={`${styles.stepCard} ${styles[`step${step.number}`]}`}>
<span className={styles.stepNumber}>{step.number}</span>
<div>
<h3 className={styles.stepTitle}>{step.title}</h3>
<p className={styles.stepDesc}>{step.description}</p>
</div>
</li>
))}
</ol>
</section>
);
};