Spaces:
Running
Running
| // Initialize GSAP plugins | |
| gsap.registerPlugin(ScrollTrigger, SplitText); | |
| // Custom Cursor | |
| const cursorDot = document.querySelector('.cursor-dot'); | |
| const cursorRing = document.querySelector('.cursor-ring'); | |
| document.addEventListener('mousemove', (e) => { | |
| gsap.to(cursorDot, { | |
| x: e.clientX - 4, | |
| y: e.clientY - 4, | |
| duration: 0.1 | |
| }); | |
| gsap.to(cursorRing, { | |
| x: e.clientX - 12, | |
| y: e.clientY - 12, | |
| duration: 0.2 | |
| }); | |
| }); | |
| // Particles System | |
| function createParticles() { | |
| const container = document.getElementById('particles-container'); | |
| const particleCount = 50; | |
| for (let i = 0; i < particleCount; i++) { | |
| const particle = document.createElement('div'); | |
| particle.className = 'particle'; | |
| gsap.set(particle, { | |
| x: Math.random() * window.innerWidth, | |
| y: Math.random() * window.innerHeight, | |
| opacity: 0 | |
| }); | |
| container.appendChild(particle); | |
| gsap.timeline({ repeat: -1 }) | |
| .to(particle, { | |
| opacity: Math.random() * 0.5 + 0.2, | |
| duration: 0.5, | |
| delay: Math.random() * 2 | |
| }) | |
| .to(particle, { | |
| y: -100, | |
| x: `+=${Math.random() * 100 - 50}`, | |
| duration: Math.random() * 10 + 10, | |
| ease: "none" | |
| }, "-=0.5") | |
| .to(particle, { | |
| opacity: 0, | |
| duration: 0.5 | |
| }) | |
| .set(particle, { | |
| y: window.innerHeight + 50, | |
| x: Math.random() * window.innerWidth | |
| }); | |
| } | |
| } | |
| // Typewriter Effect | |
| function initTypewriter() { | |
| const text = "Protecting Data and Critical Infrastructure in the Post-Quantum Era"; | |
| const element = document.getElementById('typewriter-text'); | |
| let i = 0; | |
| function typeChar() { | |
| if (i < text.length) { | |
| element.textContent += text.charAt(i); | |
| i++; | |
| setTimeout(typeChar, 60); | |
| } | |
| } | |
| typeChar(); | |
| } | |
| // Pyramid Scroll Animation | |
| function initPyramidAnimation() { | |
| const tl = gsap.timeline({ | |
| scrollTrigger: { | |
| trigger: "#story-pyramid", | |
| start: "top top", | |
| end: "bottom bottom", | |
| scrub: 1, | |
| pin: true, | |
| pinSpacing: true | |
| } | |
| }); | |
| // Animate pyramid layers | |
| gsap.set("#layer1, #layer2, #layer3", { opacity: 0, scale: 0.8, y: 100 }); | |
| tl.to("#layer1", { | |
| opacity: 1, | |
| scale: 1, | |
| y: 0, | |
| duration: 1, | |
| ease: "power3.out" | |
| }) | |
| .to("#layer2", { | |
| opacity: 1, | |
| scale: 1, | |
| y: 0, | |
| duration: 1, | |
| ease: "power3.out" | |
| }, "-=0.5") | |
| .to("#layer3", { | |
| opacity: 1, | |
| scale: 1, | |
| y: 0, | |
| duration: 1, | |
| ease: "power3.out" | |
| }, "-=0.5"); | |
| // Narrative steps opacity | |
| const steps = document.querySelectorAll('.narrative-step'); | |
| steps.forEach((step, index) => { | |
| ScrollTrigger.create({ | |
| trigger: index === 0 ? "#layer1" : index === 1 ? "#layer2" : "#layer3", | |
| start: "top center", | |
| end: "bottom center", | |
| onEnter: () => { | |
| steps.forEach(s => s.classList.add('opacity-50')); | |
| step.classList.remove('opacity-50'); | |
| step.classList.add('scale-105'); | |
| }, | |
| onLeaveBack: () => { | |
| if (index > 0) { | |
| steps[index - 1].classList.remove('opacity-50'); | |
| step.classList.add('opacity-50'); | |
| } | |
| } | |
| }); | |
| }); | |
| } | |
| // Parallax Elements | |
| function initParallax() { | |
| gsap.utils.toArray('.parallax-element').forEach(el => { | |
| gsap.to(el, { | |
| y: -100, | |
| ease: "none", | |
| scrollTrigger: { | |
| trigger: el, | |
| start: "top bottom", | |
| end: "bottom top", | |
| scrub: true | |
| } | |
| }); | |
| }); | |
| } | |
| // Enhanced Card Animations | |
| function initCardAnimations() { | |
| gsap.utils.toArray('.card-gradient').forEach(card => { | |
| card.addEventListener('mouseenter', () => { | |
| gsap.to(card, { | |
| rotateY: 5, | |
| duration: 0.3, | |
| ease: "power2.out" | |
| }); | |
| }); | |
| card.addEventListener('mouseleave', () => { | |
| gsap.to(card, { | |
| rotateY: 0, | |
| duration: 0.3, | |
| ease: "power2.out" | |
| }); | |
| }); | |
| }); | |
| } | |
| // Initialize AOS | |
| function initAOS() { | |
| AOS.init({ | |
| duration: 1000, | |
| once: true, | |
| offset: 100 | |
| }); | |
| } | |
| // Initialize Vanta.js | |
| function initVanta() { | |
| VANTA.GLOBE({ | |
| el: "#vanta-bg", | |
| mouseControls: true, | |
| touchControls: true, | |
| gyroControls: false, | |
| minHeight: 200.00, | |
| minWidth: 200.00, | |
| scale: 1.00, | |
| scaleMobile: 1.00, | |
| color: 0xe65103, | |
| color2: 0x1e293b, | |
| backgroundColor: 0x0f172a, | |
| size: 1.00, | |
| lineColor: 0xe65103 | |
| }); | |
| } | |
| // Initialize Feather Icons | |
| function initFeather() { | |
| feather.replace(); | |
| } | |
| // Master Init Function | |
| document.addEventListener('DOMContentLoaded', () => { | |
| initTypewriter(); | |
| initVanta(); | |
| initAOS(); | |
| initFeather(); | |
| createParticles(); | |
| initPyramidAnimation(); | |
| initParallax(); | |
| initCardAnimations(); | |
| // Stagger fade-in animations | |
| gsap.utils.toArray('.fade-in-up').forEach((el, index) => { | |
| gsap.to(el, { | |
| opacity: 1, | |
| y: 0, | |
| duration: 0.8, | |
| delay: index * 0.2, | |
| ease: "power3.out" | |
| }); | |
| }); | |
| // Add glow effect to all buttons on hover | |
| document.querySelectorAll('a, button').forEach(el => { | |
| el.addEventListener('mouseenter', () => { | |
| gsap.to(el, { | |
| scale: 1.02, | |
| duration: 0.2, | |
| ease: "power2.out" | |
| }); | |
| }); | |
| el.addEventListener('mouseleave', () => { | |
| gsap.to(el, { | |
| scale: 1, | |
| duration: 0.2, | |
| ease: "power2.out" | |
| }); | |
| }); | |
| }); | |
| }); | |
| // Refresh ScrollTrigger on resize | |
| window.addEventListener('resize', () => { | |
| ScrollTrigger.refresh(); | |
| }); |