public 3d-motion repository
Portfolio-Landing-Page-14--React-Frontend
// arnobt78/Portfolio-Landing-Page-14--React-Frontend
A single-page portfolio showcase built with React, Vite, and TypeScript. It features a 3D character on the landing section, scroll-driven animations with GSAP, a tech-stack 3D scene with physics (Rapier), and responsive layout. The project is frontend-only (no backend or API) and uses custom CSS for styling
Portfolio Landing Page 14 - React, Vite, TypeScript, Three.js, GSAP, ScrollTrigger, Rapier, Post-processing Frontend Project
A single-page portfolio showcase built with React, Vite, and TypeScript. It features a 3D character on the landing section, scroll-driven animations with GSAP, a tech-stack 3D scene with physics (Rapier), and responsive layout. The project is frontend-only (no backend or API) and uses custom CSS for styling. It is intended for learning, instruction, and reuse as a portfolio template.
- Live Demo: https://portfolio-ui-14.vercel.app/
Table of Contents
- Project Overview
- Technology Stack
- Project Structure
- Getting Started
- Environment Variables
- Scripts
- Architecture & Data Flow
- Components
- Routes & Pages
- Features & Functionalities
- Reusing Components in Other Projects
- Keywords
- License
- Happy Coding
Project Overview
Portfolio Landing Page 14 is a client-side only application. It has no API endpoints, no server routes, and no backend. The app is a single HTML page that mounts a React root; all navigation is in-page (anchor links and scroll). It demonstrates:
- 3D rendering with Three.js and React Three Fiber (character on desktop, tech-stack scene).
- Scroll-based animations with GSAP and ScrollTrigger.
- Loading experience with a progress state and post-load animations.
- Responsive behavior (e.g. 3D character and TechStack only on desktop).
- Custom cursor, hover effects, and section-based layout (Landing, About, What I Do, Career, Work, Tech Stack, Contact).
Technology Stack
| Category | Technology |
|---|---|
| Framework | React 18 (with hooks) |
| Build | Vite 5 |
| Language | TypeScript 5 |
| 3D | Three.js, React Three Fiber, Drei, Rapier (physics), Post-processing |
| Animation | GSAP 3, ScrollTrigger, @gsap/react |
| UI / Icons | react-icons, react-fast-marquee |
| Styling | Custom CSS (no Tailwind in this repo) |
| Analytics | @vercel/analytics (optional) |
Project Structure
portfolio-ui-14/
├── index.html # Entry HTML; root div and script to main.tsx
├── package.json
├── vite.config.ts # Vite config; chunk size limit for 3D bundles
├── tsconfig.json
├── tsconfig.app.json
├── tsconfig.node.json
├── eslint.config.js
├── public/
│ └── models/ # 3D assets (e.g. character.glb), HDR, etc.
├── src/
│ ├── main.tsx # React root mount
│ ├── App.tsx # Root component; LoadingProvider + lazy MainContainer & Character
│ ├── App.css
│ ├── index.css # Global CSS variables, base styles, Geist font
│ ├── vite-env.d.ts
│ ├── context/
│ │ └── LoadingProvider.tsx # Loading state (percent, setIsLoading); wraps app
│ ├── data/
│ │ └── boneData.ts # Bone names for character animations (typing, eyebrow)
│ ├── components/
│ │ ├── MainContainer.tsx # Layout: Cursor, Navbar, SocialIcons, sections, lazy TechStack
│ │ ├── Landing.tsx
│ │ ├── About.tsx
│ │ ├── WhatIDo.tsx
│ │ ├── Career.tsx
│ │ ├── Work.tsx # Horizontal scroll section (GSAP pin + scrub)
│ │ ├── Contact.tsx
│ │ ├── TechStack.tsx # 3D canvas with physics spheres (Rapier)
│ │ ├── Loading.tsx # Loader UI; exports setProgress for character load
│ │ ├── Navbar.tsx # Header + smooth scroll; exports smoother for initialFX
│ │ ├── Cursor.tsx # Custom cursor
│ │ ├── SocialIcons.tsx
│ │ ├── HoverLinks.tsx # Reusable hover link text effect
│ │ ├── WorkImage.tsx # Work item image (optional video on hover)
│ │ ├── Character/ # 3D character
│ │ │ ├── index.tsx # Wraps Scene
│ │ │ ├── Scene.tsx # Three.js scene, camera, renderer, character load, animations
│ │ │ └── utils/ # character loading, lighting, animations, mouse, resize, decrypt
│ │ ├── utils/
│ │ │ ├── splitText.ts # GSAP split-text on .para / .title
│ │ │ ├── initialFX.ts # Post-load landing animations; uses smoother
│ │ │ └── GsapScroll.ts # ScrollTrigger timelines for character + career
│ │ └── styles/ # Component-specific CSS files
│ └── utils/
│ └── splitTextFree.ts # Split text into chars/words/lines for GSAP
Getting Started
Prerequisites
- Node.js (e.g. 18+)
- npm (or yarn/pnpm)
Install and run
# Clone the repository (or use your own fork)
git clone <repository-url>
cd portfolio-ui-14
# Install dependencies
npm install
# Start development server (with host so you can open from other devices)
npm run dev
Then open the URL shown in the terminal (e.g. http://localhost:5173).
Build and preview
# Production build
npm run build
# Preview production build locally
npm run preview
Lint
npm run lint
Environment Variables
This project does not use any environment variables in the source code. There are no import.meta.env or process.env references for app configuration.
- You do not need a
.envfile to run or build the project. - For deployment (e.g. Vercel), you can leave environment variables empty unless you add your own (e.g. analytics IDs, feature flags).
- If you later add env vars (e.g.
VITE_ANALYTICS_ID), create a.envor.env.localand prefix them withVITE_so Vite exposes them to the client. Never commit secrets to the repo.
Scripts
| Command | Description |
|---|---|
npm run dev | Start Vite dev server (vite --host) |
npm run build | TypeScript build + Vite production build (tsc -b && vite build) |
npm run preview | Serve the dist folder locally |
npm run lint | Run ESLint on the project |
Architecture & Data Flow
- Entry:
index.htmlloads/src/main.tsx.main.tsxrenders<App />inside React’screateRoot. - App:
App.tsxwraps the tree inLoadingProviderand lazy-loadsMainContainerandCharacter. No router; one page. - Loading:
LoadingProviderholdsisLoadingand loading percent. It shows<Loading percent={loading} />until loading is done. The 3D character load usessetProgressfromLoading.tsxto drive the percentage; when ready,initialFXruns andsetIsLoading(false)hides the loader. - Layout:
MainContainerrenders Cursor, Navbar, SocialIcons, and a scroll wrapper containing Landing, About, WhatIDo, Career, Work, TechStack (desktop only, lazy), and Contact. On desktop it also renders the Character as a sibling (inside the same parent as the scroll content). - 3D: Character is built in
Character/Scene.tsxwith a raw Three.js scene (no R3F in Scene). TechStack is a separate React Three Fiber<Canvas>with Rapier physics. Both use GSAP for scroll-linked or time-based animations where needed.
Components
Core layout
- MainContainer – Wraps the whole page: cursor, navbar, social icons, smooth-scroll div, and all sections. Responsive: character and TechStack only when
isDesktopView(e.g. width > 1024). - Navbar – Header with logo, email link, and nav links (About, Work, Contact). Uses
data-hreffor in-page smooth scroll. Exportssmoother(no-op) for compatibility withinitialFX. - Cursor – Custom cursor that follows the mouse and reacts to
data-cursor="icons"anddata-cursor="disable".
Sections
- Landing – Hero with “John Doe”, “A Creative Designer / Developer” and placeholder for children (e.g. character on mobile).
- About – Section with title “About Me” and paragraph.
- WhatIDo – “What I Do” title and content boxes; touch devices get click-to-expand behavior.
- Career – Timeline-style list of roles and descriptions.
- Work – Horizontal scrolling gallery of work items (GSAP ScrollTrigger pin + scrub).
- TechStack – R3F canvas with physics-enabled spheres and tech logos; desktop only.
- Contact – Email, phone, social links, and “Designed and Developed by John Doe”.
UI and utilities
- Loading – Progress-based loader; exports
setProgressso the character loader can update the same progress. - HoverLinks – Text link with hover “clone” effect; used in Navbar and SocialIcons.
- SocialIcons – Side social links + resume button.
- WorkImage – Image (and optional video on hover) for work items.
Character (3D)
- Character/index.tsx – Thin wrapper around
Scene. - Character/Scene.tsx – Creates Three.js scene, WebGLRenderer, camera; loads character via
setCharacter, applies lighting and animations; handles resize and mouse/touch for head movement. UsessetProgressanduseLoadingto tie into the global loading state.
Routes & Pages
There are no routes in this project. It is a single-page application:
- The only “page” is the index. All content is in one scroll (Landing → About → What I Do → Career → Work → Tech Stack → Contact).
- Navigation is done with anchor links (
#about,#work,#contact) andscrollIntoView({ behavior: 'smooth' })in the Navbar.
Features & Functionalities
| Feature | How it works |
|---|---|
| Loading screen | LoadingProvider shows <Loading> until percent reaches 100 and post-load animation runs; character loader calls setProgress(callback) to update the same percent. |
| 3D character | Loaded in Character/Scene (GLB), with lighting, intro animation, and head tracking (mouse/touch). Desktop only. |
| Tech stack 3D | R3F + Rapier physics; spheres with tech logos; N8AO post-processing. Lazy-loaded, desktop only. |
| Scroll animations | GSAP ScrollTrigger on character position/rotation, career timeline, work horizontal scroll; splitText/splitTextFree for text reveal on .para and .title. |
| Landing animations | After load, initialFX runs: split text on landing, GSAP timelines, and “Designer / Developer” loop. |
| Custom cursor | Cursor component; requestAnimationFrame + GSAP for smooth follow; data-cursor for state. |
| Responsive | Sections reflow; character and TechStack hidden on small screens; WhatIDo uses touch-friendly click. |
How It’s Working (Summary)
- Boot: Vite serves
index.html→ loadsmain.tsx→ React mountsApp. - Loading:
LoadingProvidershows the loader;setProgressis passed to the character loader so the same 0–100 value updates the UI. When the model is ready,progress.loaded()resolves and intro animations run; thensetIsLoading(false)hides the loader. - Sections: All sections live in one scroll. Navbar links use
data-href="#about"(etc.) and smooth-scroll to the corresponding section. No router. - 3D: Character uses a single Three.js scene/renderer in
Scene.tsx; TechStack uses a separate R3F<Canvas>with physics. Both are optional on small screens. - Animations: GSAP + ScrollTrigger drive scroll-linked timelines (e.g. character move, work horizontal scroll);
splitText/splitTextFreesplit text for reveal animations;initialFXruns once after load for landing text effects.
Reusing Components in Other Projects
Using a single component
- Copy the component file and its
styles/*.css(if any). - Install the same dependencies the component uses (e.g.
gsap,react-icons,three,@react-three/fiber). - Replace any project-specific imports (e.g.
useLoading,setProgress) with your own context or props.
Example: reuse HoverLinks
// In your project
import HoverLinks from "./HoverLinks";
<a href="#about">
<HoverLinks text="ABOUT" />
</a>;
You also need the styles from components/styles/style.css (or the part that affects .hover-link / .hover-in).
Using the Loading pattern
- Copy
LoadingProvider,Loading, and the usage ofsetProgress. - Where you load heavy assets (e.g. 3D), call
setProgress(updateCallback)and invoke the callback with a number 0–100, then call the “loaded” promise when done so the loader can finish and run post-load logic.
Example: wrap your app with LoadingProvider
import { LoadingProvider } from "./context/LoadingProvider";
function App() {
return (
<LoadingProvider>
<main>{/* your content */}</main>
</LoadingProvider>
);
}
Example: drive progress from an async loader
const progress = setProgress((percent) => setLoading(percent));
// Later, when asset is ready:
progress.loaded().then(() => {
// Run post-load animations, then:
setIsLoading(false);
});
Using the Character + GSAP scroll
- Copy the
Characterfolder (Scene + utils),data/boneData.ts, and the parts ofGsapScrollthat you need. - Ensure your HTML has the same section class names (e.g.
.landing-section,.about-section) or adjustGsapScrolland Scene to your DOM. - Provide the same GLB and HDR paths (or change them in
character.tsandlighting.ts).
Using TechStack in another app
- Copy
TechStack.tsxand its dependencies (R3F, Drei, Rapier, Post-processing, Three). - Place your own images in
public/images/and update theimageUrlsarray inTechStack.tsx.
Keywords
Portfolio, landing page, React, Vite, TypeScript, Three.js, React Three Fiber, GSAP, ScrollTrigger, 3D character, physics, Rapier, custom cursor, loading screen, single-page application, frontend only, no backend, responsive, Vercel, demo, template, open source.
License
This project is licensed under the MIT License. Feel free to use, modify, and distribute the code as per the terms of the license.
Happy Coding! 🎉
This is an open-source project - feel free to use, enhance, and extend this project further!
If you have any questions or want to share your work, reach out via GitHub or my portfolio at https://www.arnobmahmud.com.
Enjoy building and learning! 🚀
Thank you! 😊
[INFO] 4 topics link to curated motion topic pages.