| |
| lucide.createIcons(); |
|
|
| |
| gsap.registerPlugin(ScrollTrigger); |
|
|
| |
| const navbar = document.getElementById('navbar'); |
| window.addEventListener('scroll', () => { |
| if (window.scrollY > 50) { |
| navbar.classList.add('nav-glass'); |
| } else { |
| navbar.classList.remove('nav-glass'); |
| } |
| }); |
|
|
| |
| const menuBtn = document.getElementById('menuBtn'); |
| const closeMenu = document.getElementById('closeMenu'); |
| const mobileMenu = document.getElementById('mobileMenu'); |
| const mobileLinks = document.querySelectorAll('.mobile-link'); |
|
|
| function toggleMenu(show) { |
| if (show) { |
| mobileMenu.classList.remove('opacity-0', 'pointer-events-none'); |
| document.body.style.overflow = 'hidden'; |
| } else { |
| mobileMenu.classList.add('opacity-0', 'pointer-events-none'); |
| document.body.style.overflow = ''; |
| } |
| } |
|
|
| menuBtn.addEventListener('click', () => toggleMenu(true)); |
| closeMenu.addEventListener('click', () => toggleMenu(false)); |
| mobileLinks.forEach(link => link.addEventListener('click', () => toggleMenu(false))); |
|
|
| |
| const morphCard = document.getElementById('morphCard'); |
| const morphImg = document.getElementById('morphImg'); |
| const morphOverlays = document.getElementById('morphOverlays'); |
| const morphGlow = document.getElementById('morphGlow'); |
|
|
| const heroTl = gsap.timeline({ delay: 1 }); |
|
|
| heroTl |
| .to(morphCard, { |
| rotateY: -8, |
| rotateX: 6, |
| scale: 0.96, |
| borderRadius: '32px', |
| duration: 1.8, |
| ease: 'power3.out' |
| }) |
| .to(morphImg, { |
| scale: 1.2, |
| duration: 2.2, |
| ease: 'power2.out' |
| }, '<') |
| .to(morphOverlays, { |
| opacity: 1, |
| duration: 1, |
| ease: 'power2.out' |
| }, '-=1.8') |
| .to(morphGlow, { |
| opacity: 1, |
| duration: 2, |
| ease: 'power2.out' |
| }, '<'); |
|
|
| |
| gsap.to(morphCard, { |
| y: -8, |
| rotateY: -4, |
| rotateX: 3, |
| duration: 4, |
| repeat: -1, |
| yoyo: true, |
| ease: 'sine.inOut', |
| delay: 3 |
| }); |
|
|
| |
| const steps = document.querySelectorAll('.process-step'); |
| steps.forEach((step, index) => { |
| ScrollTrigger.create({ |
| trigger: step, |
| start: 'top 70%', |
| end: 'bottom 30%', |
| onEnter: () => updateSteps(index), |
| onEnterBack: () => updateSteps(index) |
| }); |
| }); |
|
|
| function updateSteps(activeIndex) { |
| steps.forEach((s, i) => { |
| if (i <= activeIndex) { |
| s.classList.remove('opacity-30'); |
| s.classList.add('opacity-100'); |
| } else { |
| s.classList.add('opacity-30'); |
| s.classList.remove('opacity-100'); |
| } |
| }); |
| } |
|
|
| |
| gsap.to('#scrollMorphImg', { |
| scale: 1.25, |
| ease: 'none', |
| scrollTrigger: { |
| trigger: '#scrollMorphContainer', |
| start: 'top 80%', |
| end: 'bottom 20%', |
| scrub: true |
| } |
| }); |
|
|
| gsap.to('#scrollMorphChrome', { |
| opacity: 1, |
| ease: 'none', |
| scrollTrigger: { |
| trigger: '#scrollMorphContainer', |
| start: 'top 60%', |
| end: 'center center', |
| scrub: true |
| } |
| }); |
|
|
| gsap.to('#scrollProgress', { |
| width: '100%', |
| ease: 'none', |
| scrollTrigger: { |
| trigger: '#scrollMorphContainer', |
| start: 'top 60%', |
| end: 'bottom 20%', |
| scrub: true |
| } |
| }); |
|
|
| |
| const baSlider = document.getElementById('baSlider'); |
| const baHandle = document.getElementById('baHandle'); |
| const baBeforeLayer = document.getElementById('baBeforeLayer'); |
| let isDragging = false; |
|
|
| function updateBA(x) { |
| const rect = baSlider.getBoundingClientRect(); |
| let percentage = ((x - rect.left) / rect.width) * 100; |
| percentage = Math.max(0, Math.min(100, percentage)); |
| baHandle.style.left = percentage + '%'; |
| baBeforeLayer.style.clipPath = `inset(0 ${100 - percentage}% 0 0)`; |
| } |
|
|
| baHandle.addEventListener('mousedown', () => isDragging = true); |
| window.addEventListener('mouseup', () => isDragging = false); |
| window.addEventListener('mousemove', (e) => { |
| if (!isDragging) return; |
| updateBA(e.clientX); |
| }); |
|
|
| baHandle.addEventListener('touchstart', () => isDragging = true, { passive: true }); |
| window.addEventListener('touchend', () => isDragging = false); |
| window.addEventListener('touchmove', (e) => { |
| if (!isDragging) return; |
| updateBA(e.touches[0].clientX); |
| }, { passive: true }); |
|
|
| baSlider.addEventListener('click', (e) => { |
| if (e.target.closest('#baHandle')) return; |
| updateBA(e.clientX); |
| }); |
|
|
| |
| const revealSections = document.querySelectorAll('section'); |
| revealSections.forEach((section) => { |
| const targets = section.querySelectorAll('h1, h2, h3, p, .group, .process-step, .ba-slider'); |
| gsap.from(targets, { |
| y: 30, |
| opacity: 0, |
| duration: 0.8, |
| stagger: 0.08, |
| ease: 'power2.out', |
| scrollTrigger: { |
| trigger: section, |
| start: 'top 85%', |
| toggleActions: 'play none none reverse' |
| } |
| }); |
| }); |