document.addEventListener('DOMContentLoaded', () => { // 1. Initialize Lenis Smooth Scroll const lenis = new Lenis({ duration: 1.2, easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), direction: 'vertical', gestureDirection: 'vertical', smooth: true, mouseMultiplier: 1, smoothTouch: false, touchMultiplier: 2, infinite: false, }); function raf(time) { lenis.raf(time); requestAnimationFrame(raf); } requestAnimationFrame(raf); // 2. Preloader Animation const tl = gsap.timeline(); tl.to('#loader-text', { y: 0, duration: 1, ease: 'power4.out', delay: 0.2 }) .to('#loader-text', { y: '-100%', duration: 1, ease: 'power4.in', delay: 0.5 }) .to('#preloader', { y: '-100%', duration: 1, ease: 'power4.inOut' }, '-=0.5') .from('.hero-title', { y: 100, opacity: 0, duration: 1.5, stagger: 0.2, ease: 'power4.out' }, '-=0.5') .to('.hero-subtitle', { opacity: 1, duration: 1, ease: 'power2.out' }, '-=1'); // 3. Custom Cursor const cursor = document.getElementById('cursor'); const cursorDot = document.getElementById('cursor-dot'); const hoverTargets = document.querySelectorAll('.hover-target'); if (window.innerWidth >= 768) { let mouseX = 0; let mouseY = 0; let cursorX = 0; let cursorY = 0; document.addEventListener('mousemove', (e) => { mouseX = e.clientX; mouseY = e.clientY; // Instant dot gsap.to(cursorDot, { x: mouseX, y: mouseY, duration: 0 }); }); // Smooth outer circle gsap.ticker.add(() => { cursorX += (mouseX - cursorX) * 0.2; cursorY += (mouseY - cursorY) * 0.2; gsap.set(cursor, { x: cursorX, y: cursorY }); }); hoverTargets.forEach(target => { target.addEventListener('mouseenter', () => { gsap.to(cursor, { scale: 2.5, backgroundColor: 'rgba(255,255,255,1)', duration: 0.3 }); gsap.to(cursorDot, { opacity: 0, duration: 0.3 }); }); target.addEventListener('mouseleave', () => { gsap.to(cursor, { scale: 1, backgroundColor: 'transparent', duration: 0.3 }); gsap.to(cursorDot, { opacity: 1, duration: 0.3 }); }); }); } // 4. Interactive Canvas Background (Particles) const canvas = document.getElementById('hero-canvas'); const ctx = canvas.getContext('2d'); let width, height; let particles = []; function resize() { width = window.innerWidth; height = window.innerHeight; canvas.width = width; canvas.height = height; } window.addEventListener('resize', resize); resize(); class Particle { constructor() { this.x = Math.random() * width; this.y = Math.random() * height; this.vx = (Math.random() - 0.5) * 0.5; this.vy = (Math.random() - 0.5) * 0.5; this.radius = Math.random() * 1.5 + 0.5; } update() { this.x += this.vx; this.y += this.vy; if (this.x < 0 || this.x > width) this.vx *= -1; if (this.y < 0 || this.y > height) this.vy *= -1; } draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2); ctx.fillStyle = 'rgba(255, 255, 255, 0.5)'; ctx.fill(); } } for (let i = 0; i < 100; i++) { particles.push(new Particle()); } let mouse = { x: null, y: null }; window.addEventListener('mousemove', (e) => { mouse.x = e.clientX; mouse.y = e.clientY; }); function animateParticles() { ctx.clearRect(0, 0, width, height); particles.forEach(p => { p.update(); p.draw(); // Connect to mouse if (mouse.x != null) { const dx = mouse.x - p.x; const dy = mouse.y - p.y; const dist = Math.sqrt(dx * dx + dy * dy); if (dist < 150) { ctx.beginPath(); ctx.moveTo(p.x, p.y); ctx.lineTo(mouse.x, mouse.y); ctx.strokeStyle = `rgba(255, 255, 255, ${1 - dist/150})`; ctx.lineWidth = 0.5; ctx.stroke(); } } }); requestAnimationFrame(animateParticles); } animateParticles(); // 5. GSAP Scroll Animations gsap.registerPlugin(ScrollTrigger); // Reveal Text const revealTexts = document.querySelectorAll('.reveal-text'); revealTexts.forEach(text => { gsap.from(text, { scrollTrigger: { trigger: text, start: 'top 80%', }, y: 50, opacity: 0, duration: 1, ease: 'power3.out' }); }); // Parallax Images const parallaxImgs = document.querySelectorAll('.parallax-img'); parallaxImgs.forEach(img => { gsap.to(img, { scrollTrigger: { trigger: img.parentElement, start: 'top bottom', end: 'bottom top', scrub: true }, y: 50, ease: 'none' }); }); // Horizontal Scroll for Gallery const gallery = document.getElementById('gallery'); let isDown = false; let startX; let scrollLeft; gallery.addEventListener('mousedown', (e) => { isDown = true; gallery.classList.add('active'); startX = e.pageX - gallery.offsetLeft; scrollLeft = gallery.scrollLeft; }); gallery.addEventListener('mouseleave', () => { isDown = false; gallery.classList.remove('active'); }); gallery.addEventListener('mouseup', () => { isDown = false; gallery.classList.remove('active'); }); gallery.addEventListener('mousemove', (e) => { if (!isDown) return; e.preventDefault(); const x = e.pageX - gallery.offsetLeft; const walk = (x - startX) * 2; // Scroll-fast gallery.scrollLeft = scrollLeft - walk; }); });