Portfolio JavaScript Architecture

This directory contains the modular JavaScript architecture for the portfolio website, following the Single Responsibility Principle (SRP) and modern ES6 module patterns.

πŸ“ Directory Structure

assets/js/
β”œβ”€β”€ main.js                 # Main entry point
β”œβ”€β”€ README.md              # This documentation
β”œβ”€β”€ core/
β”‚   └── PortfolioApp.js    # Main application orchestrator
β”œβ”€β”€ utils/
β”‚   β”œβ”€β”€ ThemeManager.js    # Theme switching & persistence
β”‚   └── PerformanceMonitor.js # Performance monitoring
β”œβ”€β”€ effects/
β”‚   β”œβ”€β”€ ParticleSystem.js  # Background particle animations
β”‚   └── TypingAnimation.js # Typewriter text effects
β”œβ”€β”€ navigation/
β”‚   β”œβ”€β”€ NavigationEffects.js # Navbar scroll effects
β”‚   β”œβ”€β”€ MobileNavigation.js  # Mobile menu functionality
β”‚   └── SmoothScrolling.js   # Smooth anchor link scrolling
β”œβ”€β”€ interactive/
β”‚   β”œβ”€β”€ InteractiveElements.js # Card tilt & button ripple effects
β”‚   └── CursorEffects.js      # Custom cursor effects
└── animations/
    └── ScrollAnimations.js   # Scroll-triggered animations

πŸ—οΈ Architecture Overview

Single Responsibility Principle (SRP)

Each class has a single, well-defined responsibility:

Event-Driven Communication

Components communicate through custom events rather than direct references:

ES6 Modules

πŸš€ Usage

Main Entry Point

// main.js
import { PortfolioApp } from './core/PortfolioApp.js';

document.addEventListener('DOMContentLoaded', () => {
    window.portfolioApp = new PortfolioApp();
});

Component Access

// Access any component through the main app
const themeManager = window.portfolioApp.getComponent('themeManager');
const particleSystem = window.portfolioApp.getComponent('particleSystem');

Adding New Components

  1. Create a new class file in the appropriate directory
  2. Export the class using ES6 export syntax
  3. Import and initialize in PortfolioApp.js
  4. Add to the components Map

πŸ”§ Development

Adding a New Feature

  1. Create the component class in the appropriate directory
  2. Follow the naming convention: PascalCase.js
  3. Export the class: export class ComponentName
  4. Add to PortfolioApp: Import and initialize in the main app
  5. Document the component: Add to this README

Component Template

/**
 * Component Name
 * Brief description of responsibility
 */
export class ComponentName {
    constructor() {
        this.init();
    }

    init() {
        // Initialize component
    }

    // Component methods
}

πŸ“Š Benefits

Maintainability

Testability

Scalability

Performance

πŸ› οΈ Build Process

The modular structure supports modern build tools:

πŸ” Debugging

Component Debugging

// Access component for debugging
console.log(window.portfolioApp.getComponent('themeManager'));

// Check if component exists
if (window.portfolioApp.getComponent('particleSystem')) {
    console.log('Particle system is active');
}

Event Debugging

// Listen to custom events
document.addEventListener('themeChanged', (event) => {
    console.log('Theme changed to:', event.detail.theme);
});

document.addEventListener('performanceWarning', (event) => {
    console.log('Performance warning:', event.detail);
});

πŸ“ Best Practices

  1. Single Responsibility: Each class should have one clear purpose
  2. Event-Driven: Use custom events for component communication
  3. Error Handling: Always handle potential errors gracefully
  4. Documentation: Document each component’s purpose and usage
  5. Naming: Use clear, descriptive names for classes and methods
  6. Testing: Write tests for each component independently

πŸ”„ Migration from Monolithic

This modular structure replaces the previous monolithic main.js file. Benefits: