public 3d-motion repository
Portfolio-Landing-Page-2-React-Frontend
// arnobt78/Portfolio-Landing-Page-2-React-Frontend
A modern, immersive portfolio template built with React and Vite. Features a 3D astronaut hero, parallax scrolling, interactive globe, animated testimonials, and a contact form powered by EmailJS—all without a backend. Ideal for developers, designers, or anyone looking to showcase their work with a standout single-page site.
Portfolio Landing Page 2 - React, Vite, JavaScript, Three.js, TailwindCSS Frontend Project
A modern, immersive portfolio template built with React and Vite. Features a 3D astronaut hero, parallax scrolling, interactive globe, animated testimonials, and a contact form powered by EmailJS—all without a backend. Ideal for developers, designers, or anyone looking to showcase their work with a standout single-page site.
- Live Demo: https://portfolio-ui-2-3d.vercel.app/
Table of Contents
- Overview
- Features & Functionalities
- Technology Stack
- Project Structure
- Getting Started
- Environment Variables
- Project Walkthrough
- Components Guide
- Reusing Components
- API & Backend
- Keywords
- Conclusion
- License
Overview
This is a single-page portfolio built with React, Vite, and Tailwind CSS. It showcases a developer's projects, experience, testimonials, and contact form with a modern, immersive design featuring 3D graphics (Three.js), parallax scrolling, animated text, and interactive elements. The project is fully frontend—no backend server required—and uses EmailJS for contact form submissions.
Features & Functionalities
| Feature | Description |
|---|---|
| 3D Hero | Animated astronaut model (GLB) with mouse-follow camera and floating effect |
| Parallax Background | Multi-layer scroll-based parallax (sky, mountains, planets) |
| FlipWords | Cycling headline words with blur/scale animation (e.g., "Secure" → "Modern" → "Scalable") |
| Interactive Globe | COBE-based 3D globe with drag-to-rotate and city markers |
| Orbiting Tech Stack | Frameworks displayed in circular orbits (clockwise + counter-clockwise) |
| Draggable Cards | About section cards (SOLID, Design Patterns, etc.) with drag constraints |
| Project Preview | Hover over projects to see floating image that follows cursor |
| Project Modal | "Read More" opens full project details (image, description, tags) |
| Timeline | Scroll-linked work experience timeline with animated progress line |
| Testimonial Marquee | Dual-row infinite scroll of client reviews (pause on hover) |
| Contact Form | EmailJS integration—sends emails without backend |
| Particles Background | Canvas particles with mouse magnetism in Contact section |
| Responsive Navbar | Fixed header with mobile hamburger menu and smooth animations |
Technology Stack
| Technology | Purpose |
|---|---|
| React 19 | UI library |
| Vite 6 | Build tool, dev server, HMR |
| Tailwind CSS 4 | Utility-first styling, theme variables |
| Three.js | 3D rendering |
| React Three Fiber | React renderer for Three.js |
| @react-three/drei | Helpers (Float, Html, useProgress, useGLTF) |
| Motion | Animations (successor to Framer Motion) |
| COBE | Lightweight 3D globe (canvas-based) |
| EmailJS | Client-side email sending (no backend) |
| Maath | Math utilities (easing for 3D) |
| react-responsive | Media queries for responsive logic |
| tailwind-merge | Merge Tailwind classes without conflicts |
Project Structure
portfolio-ui-2/
├── public/
│ ├── assets/ # SVGs, logos, social icons
│ ├── models/ # 3D GLB files (astronaut)
│ ├── vite.svg # Favicon
│ └── (sky.jpg, mountain-*.png, planets.png) # Parallax images
├── src/
│ ├── components/ # Reusable UI components
│ │ ├── Alert.jsx
│ │ ├── Astronaut.jsx
│ │ ├── Card.jsx
│ │ ├── CopyEmailButton.jsx
│ │ ├── FlipWords.jsx
│ │ ├── Frameworks.jsx
│ │ ├── globe.jsx
│ │ ├── HeroText.jsx
│ │ ├── Loader.jsx
│ │ ├── Marquee.jsx
│ │ ├── OrbitingCircles.jsx
│ │ ├── parallaxBackground.jsx
│ │ ├── Particles.jsx
│ │ ├── Project.jsx
│ │ └── ProjectDetails.jsx
│ │ └── Timeline.jsx
│ ├── sections/ # Page sections
│ │ ├── About.jsx
│ │ ├── Contact.jsx
│ │ ├── Experiences.jsx
│ │ ├── Footer.jsx
│ │ ├── Hero.jsx
│ │ ├── Navbar.jsx
│ │ ├── Projects.jsx
│ │ └── Testimonial.jsx
│ ├── constants/
│ │ └── index.js # Projects, socials, experiences, reviews
│ ├── App.jsx
│ ├── main.jsx
│ └── index.css
├── index.html
├── vite.config.js
├── tailwind.config.js
├── package.json
└── README.md
Getting Started
Prerequisites
- Node.js 18+ (recommended: 20+)
- npm or yarn
Installation
# Clone the repository
git clone <your-repo-url>
cd portfolio-ui-2
# Install dependencies
npm install
# Start development server
npm run dev
The app runs at http://localhost:5173 (or the next available port).
Build for Production
npm run build
Output is in the dist/ folder. Preview with:
npm run preview
Lint
npm run lint
Environment Variables
The Contact form uses EmailJS to send emails. For production, store credentials in environment variables.
Step 1: Create EmailJS Account
- Sign up at https://www.emailjs.com/
- Create an Email Service (e.g., Gmail)
- Create an Email Template with variables:
{{from_name}},{{from_email}},{{message}}, etc. - Note your Service ID, Template ID, and Public Key
Step 2: Create .env File
Create .env in the project root:
VITE_EMAILJS_SERVICE_ID=your_service_id
VITE_EMAILJS_TEMPLATE_ID=your_template_id
VITE_EMAILJS_PUBLIC_KEY=your_public_key
Note: Vite only exposes variables prefixed with
VITE_to the client.
Step 3: Use in Code
In src/sections/Contact.jsx, replace hardcoded values:
await emailjs.send(
import.meta.env.VITE_EMAILJS_SERVICE_ID,
import.meta.env.VITE_EMAILJS_TEMPLATE_ID,
{
from_name: formData.name,
to_name: "John Doe",
from_email: formData.email,
to_email: "johndoe@email.com",
message: formData.message,
},
import.meta.env.VITE_EMAILJS_PUBLIC_KEY,
);
.env.example (Optional)
Create .env.example for documentation (do not commit secrets):
VITE_EMAILJS_SERVICE_ID=
VITE_EMAILJS_TEMPLATE_ID=
VITE_EMAILJS_PUBLIC_KEY=
Project Walkthrough
1. Entry Point
main.jsx mounts the app with React 18+ createRoot and StrictMode:
createRoot(document.getElementById("root")).render(
<StrictMode>
<App />
</StrictMode>,
);
2. App Layout
App.jsx composes all sections in order. Navigation uses anchor links (#home, #about, #work, #contact) for smooth scrolling.
3. Hero Section
- HeroText: Staggered Motion animations + FlipWords for cycling adjectives
- ParallaxBackground:
useScroll+useTransformfor layer movement - Canvas: Three.js scene with Astronaut (Float), Rig (camera follows mouse), Loader (progress)
4. About Section
- Grid 1: Intro + profile image
- Grid 2: "CODE IS CRAFT" with draggable Card components (text + tech logos)
- Grid 3: Time zone + Globe
- Grid 4: CTA + CopyEmailButton
- Grid 5: Tech stack + Frameworks (OrbitingCircles)
5. Projects Section
handleMouseMoveupdatesx,ymotion values- Spring values drive floating preview image position
- Each Project row calls
setPreview(image)on hover - "Read More" opens ProjectDetails modal
6. Experiences Section
- Timeline receives
experiencesfrom constants useScroll+useTransformanimate gradient line height with scroll
7. Testimonial Section
- Reviews split into
firstRowandsecondRow - Two Marquee components: one normal, one
reverse pauseOnHoverpauses animation for readability
8. Contact Section
- Particles canvas background
- Form state:
formData,isLoading,showAlert handleSubmitcalls EmailJS; Alert shows success/error
Components Guide
FlipWords
Cycles through words with blur/scale exit animation.
Props: words (array), duration (ms), className
<FlipWords
words={["Secure", "Modern", "Scalable"]}
duration={3000}
className="font-black text-8xl"
/>
Marquee
Infinite horizontal or vertical scroll.
Props: reverse, pauseOnHover, vertical, repeat, className
<Marquee pauseOnHover reverse className="[--duration:20s]">
{items.map((item) => (
<Card key={item.id} {...item} />
))}
</Marquee>
OrbitingCircles
Places children in orbit around center.
Props: reverse, duration, radius, path, iconSize, speed
<OrbitingCircles iconSize={40} radius={160} duration={20}>
{icons.map((icon, i) => (

))}
</OrbitingCircles>
Card (Draggable)
Text or image card with drag constraints.
Props: style, text, image, containerRef
const containerRef = useRef();
<Card
style={{ rotate: "45deg", top: "50%", left: "50%" }}
text="SOLID"
containerRef={containerRef}
/>;
Globe
Interactive 3D globe (COBE).
Props: className, config (optional overrides)
<Globe className="w-full max-w-[400px]" />
Particles
Canvas particle background with mouse magnetism.
Props: quantity, ease, color, refresh, className
<Particles quantity={100} ease={80} color="#ffffff" refresh />
Alert
Toast notification for success/error.
Props: type ("success" | "danger"), text
<Alert type="success" text="Message sent!" />
Timeline
Scroll-linked work experience timeline.
Props: data (array of { title, job, date, contents })
<Timeline data={experiences} />
Reusing Components
In Another React Project
-
Copy the component file (e.g.,
FlipWords.jsx,Marquee.jsx) -
Install dependencies if needed:
npm install motion tailwind-merge -
Copy related CSS from
index.css(e.g.,@keyframes marquee,--animate-orbit) -
Import and use:
import { FlipWords } from "./components/FlipWords"; <FlipWords words={["Fast", "Reliable"]} />;
Standalone Usage Example
// Marquee in a marketing site
<Marquee repeat={6} pauseOnHover>
{partners.map(p =>

)}
</Marquee>
// OrbitingCircles for skills
<OrbitingCircles iconSize={32} radius={120} reverse speed={1.5}>
{skills.map(s => <SkillBadge key={s} name={s} />)}
</OrbitingCircles>
API & Backend
This project has no backend. It is a static SPA.
| Service | Usage |
|---|---|
| EmailJS | Client-side email sending via their API. No server required. |
| Robohash | Used for testimonial avatars (https://robohash.org/{name}) |
EmailJS Flow
- User submits form →
emailjs.send()called - EmailJS API receives request with template variables
- Email sent to configured inbox
- Success/error handled in
try/catch
Keywords
portfolio, React, Vite, Tailwind CSS, Three.js, 3D, WebGL, parallax, animation, Motion, EmailJS, frontend, SPA, responsive, globe, marquee, timeline, contact form, open source, educational, developer portfolio
Conclusion
This portfolio demonstrates modern frontend techniques: 3D with Three.js, scroll-based animations, reusable components, and no-backend contact forms. The structure is modular—sections and components can be reused or replaced. Customize content via src/constants/index.js and styling via src/index.css and Tailwind theme variables.
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] 5 topics link to curated motion topic pages.