Skip to content
Open

Blog #13

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 149 additions & 0 deletions CHARACTER_REPLACEMENT_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
can# 3D Character Replacement Guide

This guide explains how to replace the default 3D character in the Work Experience section with your own avatar.

## Current Character Setup

- **Location**: Work Experience section displays a 3D human character
- **Model File**: `/public/models/animations/developer.glb`
- **Component**: `src/components/Developer.jsx`
- **Animations**: 4 animations (idle, salute, clapping, victory)
- **Animation Files**: Located in `/public/models/animations/` folder

## Option 1: ReadyPlayerMe (Recommended)

### Step 1: Create Your Avatar
1. **Direct URL**: https://readyplayer.me/avatar
2. **Alternative**: Go to https://readyplayer.me/ → Click "Try it now" → Create account
3. **Choose Creation Method**:
- **From Photo**: Upload a clear photo of yourself
- **From Scratch**: Build manually using their editor
4. **Customize**: Adjust hair, clothing, accessories, facial features
5. **Download**: Export as GLB format

### Step 2: Replace the Model
1. **Rename** your downloaded file to `developer.glb`
2. **Replace** the existing file at `/public/models/animations/developer.glb`
3. **Keep** all animation files (idle.fbx, salute.fbx, clapping.fbx, victory.fbx)

### Step 3: Test
1. Run `npm run dev`
2. Navigate to Work Experience section
3. Hover over different work experiences to test animations
4. Check that the model loads without errors

## Option 2: VRoid Studio (Most Customizable)

### Step 1: Create Avatar
1. **Download**: https://vroid.com/en/studio
2. **Create**: Anime-style avatar from scratch
3. **Export**: As VRM format
4. **Convert**: Use online converter to GLB format

### Step 2: Replace Model
- Follow same steps as Option 1, Step 2

## Option 3: Mixamo + Adobe

### Step 1: Create Character
1. **Visit**: https://www.mixamo.com/
2. **Create Account**: Adobe account required
3. **Choose Character**: Select base character or upload custom
4. **Customize**: Appearance and clothing
5. **Download**: As GLB format

### Step 2: Replace Model
- Follow same steps as Option 1, Step 2

## Alternative Options

### VRChat Integration
- **URL**: https://hub.vrcav.com/
- **Process**: Create Avatar → Select Ready Player Me
- Often has photo upload feature when main site doesn't

### Free Model Sources
- **Sketchfab**: Search for "human character GLB"
- **Mixamo**: Free characters with animations
- **OpenGameArt**: Free 3D models

## Troubleshooting

### If Animations Don't Work
1. **Check Console**: Look for errors in browser dev tools
2. **Bone Structure**: Ensure your model has similar bone names
3. **Retarget Animations**: Use Blender to retarget animations to your model

### If Model is Wrong Size
1. **Scale**: Adjust `scale={3}` in `src/sections/Experience.jsx:26`
2. **Position**: Modify `position-y={-3}` in `src/sections/Experience.jsx:26`

### If Materials Look Wrong
Update material references in `src/components/Developer.jsx`:
- `Wolf3D_Hair` - Hair material
- `Wolf3D_Skin` - Skin material
- `Wolf3D_Body` - Body material
- `Wolf3D_Outfit_Top/Bottom` - Clothing materials

### Animation Issues
The model expects these bone names for animations:
- Hips (root bone)
- Standard humanoid bone structure
- If bones don't match, animations won't work properly

## Technical Details

### Model Requirements
- **Format**: GLB/GLTF
- **Rigged**: Must have skeleton for animations
- **Bone Structure**: Humanoid bone names compatible with existing animations
- **Size**: Keep under 10MB for good performance

### Animation Files
- **idle.fbx**: Default standing pose
- **salute.fbx**: Saluting gesture
- **clapping.fbx**: Clapping hands
- **victory.fbx**: Victory pose

### Component Structure
```jsx
// src/components/Developer.jsx
const Developer = ({ animationName = 'idle', ...props }) => {
// Loads model and animations
// Switches between animations based on work experience hover
}
```

### Usage in Experience Section
```jsx
// src/sections/Experience.jsx
<Developer position-y={-3} scale={3} animationName={animationName} />
```

## File Structure
```
public/
├── models/
├── animations/
│ ├── developer.glb <- Replace this file
│ ├── idle.fbx <- Keep these
│ ├── salute.fbx <- Keep these
│ ├── clapping.fbx <- Keep these
│ └── victory.fbx <- Keep these
```

## Testing Checklist
- [ ] Model loads without errors
- [ ] All 4 animations work (idle, salute, clapping, victory)
- [ ] Hover interactions trigger animations
- [ ] Model is properly scaled and positioned
- [ ] No console errors
- [ ] Performance is acceptable

## Need Help?
If you encounter issues:
1. Check browser console for errors
2. Ensure model format is GLB
3. Verify bone structure matches expected format
4. Test with a simple model first
5. Consider using Blender for model adjustments
88 changes: 88 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Development Commands

- `npm run dev` - Start development server (runs on http://localhost:5173)
- `npm run build` - Build production version
- `npm run preview` - Preview production build locally
- `npm run lint` - Run ESLint to check code quality

## Project Architecture

This is a React + Three.js portfolio website built with Vite. The site showcases an interactive 3D experience with sections for hero, about, projects, publications, work experience, and contact.

### Key Technologies
- **React 18** - UI framework
- **Three.js + React Three Fiber** - 3D graphics and animations
- **React Three Drei** - Helper utilities for Three.js
- **GSAP** - Animations and transitions
- **Tailwind CSS** - Styling framework
- **EmailJS** - Contact form functionality
- **Leva** - 3D development controls (hidden in production)

### Core Structure

**Main App Flow**: `App.jsx` renders sections in order: Navbar → Hero → About → Projects → Publications → WorkExperience → Contact → Footer

**3D Scene Architecture**:
- `Hero.jsx` contains the main 3D canvas with interactive elements
- `HeroCamera.jsx` handles camera controls and mouse interactions
- `HackerRoom.jsx` is the main 3D room model
- Floating 3D elements: `Cube.jsx`, `Rings.jsx`, tech logos (`PythonLogo.jsx`, `PyTorchLogo.jsx`, etc.)
- `calculateSizes()` in `constants/index.js` handles responsive positioning

**Data Management**:
- `src/constants/index.js` contains all static data (projects, publications, work experience, navigation)
- Responsive breakpoints handled via `react-responsive` hooks

**Component Pattern**:
- 3D components in `/components` directory
- Page sections in `/sections` directory
- Shared utilities in `/hooks` directory
- All 3D models stored in `/public/models`
- Textures and assets in `/public/textures` and `/public/assets`

### Email Configuration

The contact form and newsletter subscription use EmailJS. Environment variables needed:
- `VITE_EMAILJS_SERVICE_ID` - EmailJS service ID
- `VITE_EMAILJS_TEMPLATE_ID` - Template ID for contact form
- `VITE_EMAILJS_NEWSLETTER_TEMPLATE_ID` - Template ID for newsletter subscriptions
- `VITE_EMAILJS_PUBLIC_KEY` - EmailJS public key

**Important**: Use `VITE_` prefix for environment variables in Vite (not `REACT_APP_`)

For detailed setup instructions, see `EMAILJS_SETUP.md`

### 3D Model Loading

Models are loaded from `/public/models` using `useGLTF` hook. Key models:
- `hacker-room.glb` - Main desk/room scene
- `computer.glb` - Interactive computer for projects
- `cube.glb`, `react.glb` - Floating elements
- Animation files in `/models/animations/`

### Performance Considerations

- All 3D models are preloaded using `useGLTF.preload()`
- Responsive sizing calculated once and passed to components
- Suspense boundaries with custom loading components
- Media queries determine render complexity based on device

### Deployment

#### Vercel Deployment
1. Connect your GitHub repository to Vercel
2. Configure environment variables in Vercel project settings:
- `VITE_EMAILJS_SERVICE_ID`
- `VITE_EMAILJS_TEMPLATE_ID`
- `VITE_EMAILJS_NEWSLETTER_TEMPLATE_ID`
- `VITE_EMAILJS_PUBLIC_KEY`
3. Deploy using `npm run build`
4. Test contact form and newsletter functionality after deployment

#### Local Development with EmailJS
Create `.env.local` file with EmailJS environment variables for local testing.
Never commit this file to version control.
151 changes: 151 additions & 0 deletions EMAILJS_SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# EmailJS Setup Guide for Contact Form & Newsletter

This guide explains how to configure EmailJS for both the contact form and newsletter subscription functionality on your Vercel-deployed website.

## Required Environment Variables

Add these environment variables to your Vercel project settings:

```
VITE_EMAILJS_SERVICE_ID=your_service_id_here
VITE_EMAILJS_TEMPLATE_ID=your_contact_template_id_here
VITE_EMAILJS_NEWSLETTER_TEMPLATE_ID=your_newsletter_template_id_here
VITE_EMAILJS_PUBLIC_KEY=your_public_key_here
```

## EmailJS Account Setup

### 1. Create EmailJS Account
1. Go to [EmailJS.com](https://www.emailjs.com/)
2. Sign up for a free account
3. Verify your email address

### 2. Add Email Service
1. Go to the "Email Services" section
2. Click "Add New Service"
3. Choose your email provider (Gmail, Outlook, etc.)
4. Follow the setup instructions for your provider
5. Note the **Service ID** for your environment variables

### 3. Create Email Templates

#### Contact Form Template
1. Go to "Email Templates" section
2. Click "Create New Template"
3. Set up the template with these variables:
- `{{from_name}}` - Sender's name
- `{{from_email}}` - Sender's email
- `{{to_name}}` - Your name (Jan Magnus Heimann)
- `{{to_email}}` - Your email (jan@heimann.ai)
- `{{message}}` - Contact message content
4. Example template:

```
Subject: New Contact Form Message from {{from_name}}

From: {{from_name}} ({{from_email}})
To: {{to_name}}

Message:
{{message}}

---
This message was sent from your portfolio contact form.
```

5. Save and note the **Template ID**

#### Newsletter Subscription Template
1. Create another new template for newsletter subscriptions
2. Set up with these variables:
- `{{subscriber_email}}` - Newsletter subscriber's email
- `{{to_name}}` - Your name
- `{{to_email}}` - Your email
- `{{message}}` - Subscription notification message
3. Example template:

```
Subject: New Newsletter Subscription

Hello {{to_name}},

You have a new newsletter subscription!

Subscriber Email: {{subscriber_email}}

{{message}}

---
This notification was sent from your portfolio newsletter signup.
```

4. Save and note the **Newsletter Template ID**

### 4. Get Public Key
1. Go to "Account" section
2. Find your **Public Key**
3. Note this for your environment variables

## Vercel Deployment Setup

### 1. Add Environment Variables to Vercel
1. Go to your Vercel project dashboard
2. Navigate to Settings → Environment Variables
3. Add each of the four environment variables:
- `VITE_EMAILJS_SERVICE_ID`
- `VITE_EMAILJS_TEMPLATE_ID`
- `VITE_EMAILJS_NEWSLETTER_TEMPLATE_ID`
- `VITE_EMAILJS_PUBLIC_KEY`
4. Set them for Production, Preview, and Development environments

### 2. Redeploy Your Application
After adding environment variables, trigger a new deployment so Vercel picks up the new configuration.

## Testing

### Local Testing
1. Create a `.env.local` file in your project root
2. Add your environment variables:
```
VITE_EMAILJS_SERVICE_ID=your_service_id_here
VITE_EMAILJS_TEMPLATE_ID=your_contact_template_id_here
VITE_EMAILJS_NEWSLETTER_TEMPLATE_ID=your_newsletter_template_id_here
VITE_EMAILJS_PUBLIC_KEY=your_public_key_here
```
3. Run `npm run dev` and test both forms

### Production Testing
1. Deploy to Vercel with environment variables configured
2. Test the contact form at `yourdomain.com/#contact`
3. Test the newsletter signup at `yourdomain.com/#blog`

## Troubleshooting

### Common Issues
1. **Environment variables not found**: Make sure variables start with `VITE_` prefix for Vite
2. **EmailJS service errors**: Verify your service ID and public key are correct
3. **Template not found**: Double-check template IDs match exactly
4. **CORS errors**: EmailJS should handle CORS automatically, but verify your domain is allowlisted in EmailJS settings

### Email Delivery Issues
1. Check your EmailJS dashboard for sent email logs
2. Verify your email service connection is active
3. Check spam folders for test emails
4. Ensure your email service has proper authentication

## Features

### Contact Form (`/src/sections/Contact.jsx`)
- Full name, email, and message fields
- Form validation
- Loading states during submission
- Success/error notifications
- Automatic form reset after successful submission

### Newsletter Subscription (`/src/sections/Blog.jsx`)
- Email address field with validation
- Loading states during subscription
- Success/error notifications
- Automatic field reset after successful subscription

Both forms use the shared Alert component for consistent user feedback.
Loading