Download index.html from WebashalarForML/anycoder-77f43fa2: direct link, hf CLI and curl.
- Browser
- Download file 28.9 kB
-
https://huggingface.co/spaces/WebashalarForML/anycoder-77f43fa2/resolve/main/index.html
- Command line
-
hf download hf://spaces/WebashalarForML/anycoder-77f43fa2/index.html
-
curl -L -o index.html https://huggingface.co/spaces/WebashalarForML/anycoder-77f43fa2/resolve/main/index.html
28.9 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>A.I. Engineer Portfolio | Cinematic Experience</title> | |
| <!-- External Libraries --> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script> | |
| <script src="https://unpkg.com/lucide@latest"></script> | |
| <!-- Google Fonts --> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@100;300;400;700&family=Space+Grotesk:wght@300;500;700&display=swap" rel="stylesheet"> | |
| <!-- Tailwind Config for Custom Colors/Fonts --> | |
| <script> | |
| tailwind.config = { | |
| theme: { | |
| extend: { | |
| colors: { | |
| void: '#050505', | |
| obsidian: '#0a0a0a', | |
| charcoal: '#1c1c1c', | |
| platinum: '#e5e5e5', | |
| accent: '#ff3333', // Subtle accent for rare elements | |
| }, | |
| fontFamily: { | |
| mono: ['"JetBrains Mono"', 'monospace'], | |
| sans: ['"Space Grotesk"', 'sans-serif'], | |
| }, | |
| backgroundImage: { | |
| 'grid-pattern': "linear-gradient(to right, #1f1f1f 1px, transparent 1px), linear-gradient(to bottom, #1f1f1f 1px, transparent 1px)", | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| <style> | |
| /* Base Reset & Typography */ | |
| body { | |
| background-color: #050505; | |
| color: #e5e5e5; | |
| overflow-x: hidden; | |
| cursor: none; /* Custom cursor */ | |
| } | |
| ::selection { | |
| background: #333; | |
| color: #fff; | |
| } | |
| /* Custom Scrollbar */ | |
| ::-webkit-scrollbar { | |
| width: 8px; | |
| } | |
| ::-webkit-scrollbar-track { | |
| background: #0a0a0a; | |
| } | |
| ::-webkit-scrollbar-thumb { | |
| background: #333; | |
| border-radius: 4px; | |
| } | |
| ::-webkit-scrollbar-thumb:hover { | |
| background: #555; | |
| } | |
| /* Custom Cursor */ | |
| #cursor { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 20px; | |
| height: 20px; | |
| border: 1px solid rgba(255, 255, 255, 0.5); | |
| border-radius: 50%; | |
| pointer-events: none; | |
| z-index: 9999; | |
| transform: translate(-50%, -50%); | |
| transition: width 0.3s, height 0.3s, background-color 0.3s; | |
| mix-blend-mode: difference; | |
| } | |
| #cursor.hovered { | |
| width: 50px; | |
| height: 50px; | |
| background-color: rgba(255, 255, 255, 0.1); | |
| border-color: transparent; | |
| } | |
| /* Utilities */ | |
| .glass-panel { | |
| background: rgba(10, 10, 10, 0.6); | |
| backdrop-filter: blur(12px); | |
| -webkit-backdrop-filter: blur(12px); | |
| border: 1px solid rgba(255, 255, 255, 0.05); | |
| } | |
| .text-outline { | |
| -webkit-text-stroke: 1px rgba(255, 255, 255, 0.2); | |
| color: transparent; | |
| transition: all 0.5s ease; | |
| } | |
| .text-outline:hover { | |
| color: #fff; | |
| -webkit-text-stroke: 1px #fff; | |
| } | |
| /* Noise Texture Overlay */ | |
| .noise-overlay { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| pointer-events: none; | |
| z-index: 50; | |
| opacity: 0.05; | |
| background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E"); | |
| } | |
| /* Loading Screen */ | |
| #loader { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: #000; | |
| z-index: 10000; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| flex-direction: column; | |
| } | |
| .loader-bar { | |
| width: 0%; | |
| height: 2px; | |
| background: #fff; | |
| margin-top: 20px; | |
| transition: width 0.1s; | |
| } | |
| /* 3D Canvas Container */ | |
| #canvas-container { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| z-index: -1; | |
| opacity: 0; /* Fade in via JS */ | |
| transition: opacity 1.5s ease; | |
| } | |
| </style> | |
| </head> | |
| <body class="font-sans antialiased"> | |
| <!-- Loading Screen --> | |
| <div id="loader"> | |
| <div class="font-mono text-xs tracking-[0.5em] text-gray-400">INITIALIZING SYSTEM</div> | |
| <div class="loader-bar" id="loader-bar"></div> | |
| </div> | |
| <!-- Noise Overlay --> | |
| <div class="noise-overlay"></div> | |
| <!-- Custom Cursor --> | |
| <div id="cursor"></div> | |
| <!-- 3D Background --> | |
| <div id="canvas-container"></div> | |
| <!-- Navigation --> | |
| <nav class="fixed top-0 left-0 w-full p-6 flex justify-between items-center z-40 mix-blend-difference"> | |
| <div class="font-mono text-sm font-bold tracking-widest hover-trigger">AI.ENGINEER</div> | |
| <div class="hidden md:flex gap-8 font-mono text-xs tracking-wider"> | |
| <a href="#work" class="hover:text-white transition-colors hover-trigger">WORK</a> | |
| <a href="#research" class="hover:text-white transition-colors hover-trigger">RESEARCH</a> | |
| <a href="#about" class="hover:text-white transition-colors hover-trigger">ABOUT</a> | |
| </div> | |
| <button class="border border-white/20 px-4 py-2 rounded-full font-mono text-xs hover:bg-white hover:text-black transition-all hover-trigger"> | |
| CONTACT | |
| </button> | |
| </nav> | |
| <!-- Main Content --> | |
| <main class="relative z-10"> | |
| <!-- Hero Section --> | |
| <section class="h-screen w-full flex flex-col justify-center items-center relative px-4"> | |
| <div class="absolute inset-0 bg-gradient-to-b from-transparent via-transparent to-[#050505] pointer-events-none"></div> | |
| <div class="text-center z-10"> | |
| <p class="font-mono text-xs md:text-sm text-gray-400 mb-4 tracking-[0.3em] hero-anim opacity-0 translate-y-10"> | |
| ARTIFICIAL INTELLIGENCE & RESEARCH | |
| </p> | |
| <h1 class="text-5xl md:text-8xl lg:text-9xl font-bold tracking-tighter leading-none mb-6 hero-anim opacity-0 translate-y-10"> | |
| <span class="block bg-clip-text text-transparent bg-gradient-to-r from-white to-gray-600">PRECISION</span> | |
| <span class="block text-outline">ENGINEERING</span> | |
| </h1> | |
| <p class="max-w-xl mx-auto font-light text-gray-400 text-sm md:text-base leading-relaxed hero-anim opacity-0 translate-y-10"> | |
| Architecting the future through neural networks and high-performance algorithms. | |
| </p> | |
| </div> | |
| <div class="absolute bottom-10 left-1/2 -translate-x-1/2 flex flex-col items-center gap-2 hero-anim opacity-0"> | |
| <span class="font-mono text-[10px] tracking-widest text-gray-500">SCROLL TO EXPLORE</span> | |
| <div class="w-[1px] h-12 bg-gradient-to-b from-white to-transparent"></div> | |
| </div> | |
| </section> | |
| <!-- KPI Slider Section --> | |
| <section id="kpi-section" class="py-32 px-6 md:px-20 relative"> | |
| <div class="absolute top-0 left-0 w-full h-[1px] bg-white/10"></div> | |
| <div class="flex flex-col md:flex-row justify-between items-end mb-20 border-b border-white/10 pb-8"> | |
| <h2 class="text-4xl md:text-6xl font-bold">SYSTEM METRICS</h2> | |
| <div class="font-mono text-xs text-gray-500 mt-4 md:mt-0"> | |
| REAL-TIME DATA STREAM | |
| </div> | |
| </div> | |
| <!-- KPI Cards Container --> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-6"> | |
| <!-- Card 1 --> | |
| <div class="kpi-card group p-8 border border-white/5 bg-[#0a0a0a] relative overflow-hidden hover-trigger"> | |
| <div class="absolute top-0 right-0 p-4 opacity-50 group-hover:opacity-100 transition-opacity"> | |
| <i data-lucide="cpu" class="w-6 h-6"></i> | |
| </div> | |
| <div class="font-mono text-xs text-gray-500 mb-2">MODEL ACCURACY</div> | |
| <div class="text-5xl md:text-6xl font-bold font-mono mb-4 counter" data-target="99.8">0</div> | |
| <div class="w-full h-[1px] bg-white/10 mb-4 relative overflow-hidden"> | |
| <div class="absolute top-0 left-0 h-full w-1/2 bg-white group-hover:w-full transition-all duration-1000 ease-out"></div> | |
| </div> | |
| <p class="text-sm text-gray-400">Optimized for edge deployment and low-latency inference.</p> | |
| </div> | |
| <!-- Card 2 --> | |
| <div class="kpi-card group p-8 border border-white/5 bg-[#0a0a0a] relative overflow-hidden hover-trigger"> | |
| <div class="absolute top-0 right-0 p-4 opacity-50 group-hover:opacity-100 transition-opacity"> | |
| <i data-lucide="database" class="w-6 h-6"></i> | |
| </div> | |
| <div class="font-mono text-xs text-gray-500 mb-2">DATA PROCESSED</div> | |
| <div class="text-5xl md:text-6xl font-bold font-mono mb-4 counter" data-target="850">0</div> | |
| <div class="w-full h-[1px] bg-white/10 mb-4 relative overflow-hidden"> | |
| <div class="absolute top-0 left-0 h-full w-0 group-hover:w-full transition-all duration-1000 ease-out delay-200"></div> | |
| </div> | |
| <p class="text-sm text-gray-400">Petabytes of structured and unstructured data analyzed.</p> | |
| </div> | |
| <!-- Card 3 --> | |
| <div class="kpi-card group p-8 border border-white/5 bg-[#0a0a0a] relative overflow-hidden hover-trigger"> | |
| <div class="absolute top-0 right-0 p-4 opacity-50 group-hover:opacity-100 transition-opacity"> | |
| <i data-lucide="zap" class="w-6 h-6"></i> | |
| </div> | |
| <div class="font-mono text-xs text-gray-500 mb-2">INFERENCE TIME</div> | |
| <div class="text-5xl md:text-6xl font-bold font-mono mb-4 counter" data-target="12">0</div> | |
| <div class="text-xs text-gray-500 font-mono mb-4">ms</div> | |
| <div class="w-full h-[1px] bg-white/10 mb-4 relative overflow-hidden"> | |
| <div class="absolute top-0 left-0 h-full w-1/3 bg-white group-hover:w-full transition-all duration-1000 ease-out delay-400"></div> | |
| </div> | |
| <p class="text-sm text-gray-400">Achieving sub-15ms response times on consumer hardware.</p> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Wireframe / Grid Section --> | |
| <section id="work" class="py-32 relative overflow-hidden"> | |
| <div class="container mx-auto px-6"> | |
| <div class="flex flex-col md:flex-row justify-between items-start mb-16"> | |
| <h2 class="text-4xl md:text-6xl font-bold">PROJECTS</h2> | |
| <div class="font-mono text-xs text-gray-500 mt-4 md:mt-0">ARCHIVE: 2023 - 2024</div> | |
| </div> | |
| <!-- Vertical Crop Grid Trigger --> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-12 items-center"> | |
| <!-- Left: Text Description --> | |
| <div class="order-2 md:order-1 space-y-8"> | |
| <div class="project-trigger group cursor-pointer"> | |
| <div class="flex items-center gap-4 mb-2"> | |
| <span class="font-mono text-xs text-accent">01</span> | |
| <span class="font-mono text-xs text-gray-500">NEURAL INTERFACE</span> | |
| </div> | |
| <h3 class="text-3xl md:text-5xl font-bold group-hover:text-white transition-colors">Brain-Computer Interface</h3> | |
| <p class="text-gray-400 mt-4 leading-relaxed"> | |
| Decoding motor cortex signals in real-time to control robotic prosthetics with millimeter precision. | |
| </p> | |
| </div> | |
| <div class="w-full h-[1px] bg-white/10"></div> | |
| <div class="project-trigger group cursor-pointer"> | |
| <div class="flex items-center gap-4 mb-2"> | |
| <span class="font-mono text-xs text-accent">02</span> | |
| <span class="font-mono text-xs text-gray-500">GENERATIVE MODEL</span> | |
| </div> | |
| <h3 class="text-3xl md:text-5xl font-bold group-hover:text-white transition-colors">Synthetic Data Fabric</h3> | |
| <p class="text-gray-400 mt-4 leading-relaxed"> | |
| Creating infinite, privacy-compliant datasets for training LLMs and Computer Vision models. | |
| </p> | |
| </div> | |
| </div> | |
| <!-- Right: Visual Reveal --> | |
| <div class="order-1 md:order-2 relative h-[600px] w-full border border-white/10 bg-charcoal overflow-hidden group hover-trigger"> | |
| <!-- Abstract geometric representation --> | |
| <div class="absolute inset-0 bg-grid-pattern opacity-20"></div> | |
| <div class="absolute inset-0 flex items-center justify-center"> | |
| <div class="w-64 h-64 border border-white/20 rounded-full animate-[spin_10s_linear_infinite]"></div> | |
| <div class="absolute w-48 h-48 border border-white/10 rotate-45"></div> | |
| <div class="absolute w-32 h-32 bg-white/5 blur-xl rounded-full"></div> | |
| </div> | |
| <div class="absolute bottom-0 left-0 p-8 bg-gradient-to-t from-black to-transparent w-full"> | |
| <span class="font-mono text-xs">FIG 1.1: ARCHITECTURE</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Accordion Slider / Showcase --> | |
| <section id="research" class="py-32 bg-[#0a0a0a] relative"> | |
| <div class="container mx-auto px-6"> | |
| <h2 class="text-4xl md:text-6xl font-bold mb-20 text-center">RESEARCH PAPERS</h2> | |
| <div class="max-w-4xl mx-auto space-y-4"> | |
| <!-- Paper 1 --> | |
| <div class="research-item group border-b border-white/10 pb-4 cursor-pointer hover:bg-white/5 transition-colors"> | |
| <div class="flex justify-between items-center py-6"> | |
| <h3 class="text-2xl font-bold">Attention Is All You Need (Redux)</h3> | |
| <i data-lucide="chevron-down" class="w-6 h-6 transform transition-transform duration-300"></i> | |
| </div> | |
| <div class="max-h-0 overflow-hidden transition-all duration-500 ease-in-out"> | |
| <div class="pb-8 grid grid-cols-1 md:grid-cols-3 gap-6"> | |
| <div class="md:col-span-2 text-gray-400 text-sm leading-relaxed"> | |
| <p class="mb-4">An exploration into self-attention mechanisms in transformer architectures, optimized for sparse computation.</p> | |
| <ul class="list-disc list-inside text-gray-500 font-mono text-xs space-y-1"> | |
| <li>ArXiv: 2023.10.24</li> | |
| <li>Latex Source Available</li> | |
| <li>Code: GitHub.com/AI-Eng/Transformer</li> | |
| </ul> | |
| </div> | |
| <div class="bg-white/5 p-4 border border-white/10"> | |
| <div class="text-xs font-mono text-gray-500 mb-2">CITATION SCORE</div> | |
| <div class="text-3xl font-bold">142</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Paper 2 --> | |
| <div class="research-item group border-b border-white/10 pb-4 cursor-pointer hover:bg-white/5 transition-colors"> | |
| <div class="flex justify-between items-center py-6"> | |
| <h3 class="text-2xl font-bold">Quantum-Classical Hybrid Heuristics</h3> | |
| <i data-lucide="chevron-down" class="w-6 h-6 transform transition-transform duration-300"></i> | |
| </div> | |
| <div class="max-h-0 overflow-hidden transition-all duration-500 ease-in-out"> | |
| <div class="pb-8 grid grid-cols-1 md:grid-cols-3 gap-6"> | |
| <div class="md:col-span-2 text-gray-400 text-sm leading-relaxed"> | |
| <p class="mb-4">Leveraging variational quantum eigensolvers (VQE) to optimize reinforcement learning policies.</p> | |
| </div> | |
| <div class="bg-white/5 p-4 border border-white/10"> | |
| <div class="text-xs font-mono text-gray-500 mb-2">CITATION SCORE</div> | |
| <div class="text-3xl font-bold">89</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Footer --> | |
| <footer class="py-20 border-t border-white/10 bg-void relative overflow-hidden"> | |
| <div class="container mx-auto px-6 flex flex-col md:flex-row justify-between items-center relative z-10"> | |
| <div class="mb-8 md:mb-0 text-center md:text-left"> | |
| <h2 class="text-2xl font-bold">READY TO COLLABORATE?</h2> | |
| <p class="text-gray-500 font-mono text-sm mt-2">Open for select research partnerships.</p> | |
| </div> | |
| <div class="flex gap-6"> | |
| <a href="#" class="hover:text-white transition-colors hover-trigger"><i data-lucide="github" class="w-6 h-6"></i></a> | |
| <a href="#" class="hover:text-white transition-colors hover-trigger"><i data-lucide="twitter" class="w-6 h-6"></i></a> | |
| <a href="#" class="hover:text-white transition-colors hover-trigger"><i data-lucide="linkedin" class="w-6 h-6"></i></a> | |
| </div> | |
| </div> | |
| <div class="absolute bottom-4 right-6 font-mono text-[10px] text-gray-700"> | |
| Built with anycoder | |
| </div> | |
| </footer> | |
| </main> | |
| <script> | |
| // Initialize Icons | |
| lucide.createIcons(); | |
| // --- 1. PRELOADER LOGIC --- | |
| const loader = document.getElementById('loader'); | |
| const loaderBar = document.getElementById('loader-bar'); | |
| const canvasContainer = document.getElementById('canvas-container'); | |
| let progress = 0; | |
| const interval = setInterval(() => { | |
| progress += Math.random() * 10; | |
| if (progress >= 100) { | |
| progress = 100; | |
| clearInterval(interval); | |
| // Finish loading | |
| gsap.to(loaderBar, { width: '100%', duration: 0.2, onComplete: () => { | |
| gsap.to(loader, { | |
| yPercent: -100, | |
| duration: 1, | |
| ease: "power4.inOut", | |
| onComplete: () => { | |
| canvasContainer.style.opacity = 1; | |
| initAnimations(); // Start main animations after loader | |
| } | |
| }); | |
| }}); | |
| } | |
| loaderBar.style.width = `${progress}%`; | |
| }, 100); | |
| // --- 2. THREE.JS BACKGROUND (Data Tunnel Effect) --- | |
| // Combining concepts from multiple pens for a unique look | |
| const scene = new THREE.Scene(); | |
| // Fog for depth fading | |
| scene.fog = new THREE.FogExp2(0x050505, 0.002); | |
| const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); | |
| camera.position.z = 100; | |
| const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true }); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| renderer.setPixelRatio(window.devicePixelRatio); | |
| canvasContainer.appendChild(renderer.domElement); | |
| // Create Particles (The "Data Tunnel") | |
| const geometry = new THREE.BufferGeometry(); | |
| const count = 3000; | |
| const positions = new Float32Array(count * 3); | |
| const colors = new Float32Array(count * 3); | |
| const sizes = new Float32Array(count); | |
| const color1 = new THREE.Color(0xffffff); // White | |
| const color2 = new THREE.Color(0x333333); // Grey | |
| for(let i = 0; i < count; i++) { | |
| // Tunnel shape logic | |
| const angle = Math.random() * Math.PI * 2; | |
| const radius = 20 + Math.random() * 80; // Tunnel width | |
| const z = (Math.random() - 0.5) * 400; // Length | |
| positions[i * 3] = Math.cos(angle) * radius; | |
| positions[i * 3 + 1] = Math.sin(angle) * radius; | |
| positions[i * 3 + 2] = z; | |
| // Mix colors | |
| const mixedColor = Math.random() > 0.5 ? color1 : color2; | |
| colors[i * 3] = mixedColor.r; | |
| colors[i * 3 + 1] = mixedColor.g; | |
| colors[i * 3 + 2] = mixedColor.b; | |
| sizes[i] = Math.random() * 2; | |
| } | |
| geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); | |
| geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3)); | |
| geometry.setAttribute('size', new THREE.BufferAttribute(sizes, 1)); | |
| // Custom Shader Material for particles | |
| const material = new THREE.PointsMaterial({ | |
| size: 0.5, | |
| vertexColors: true, | |
| transparent: true, | |
| opacity: 0.8, | |
| blending: THREE.AdditiveBlending | |
| }); | |
| const particles = new THREE.Points(geometry, material); | |
| scene.add(particles); | |
| // Add a secondary geometric grid (The "Wireframe" feel) | |
| const gridHelper = new THREE.GridHelper(200, 50, 0x333333, 0x111111); | |
| gridHelper.position.y = -50; | |
| scene.add(gridHelper); | |
| // Animation Loop | |
| let mouseX = 0; | |
| let mouseY = 0; | |
| let targetX = 0; | |
| let targetY = 0; | |
| document.addEventListener('mousemove', (event) => { | |
| mouseX = event.clientX - window.innerWidth / 2; | |
| mouseY = event.clientY - window.innerHeight / 2; | |
| }); | |
| const clock = new THREE.Clock(); | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| const elapsedTime = clock.getElapsedTime(); | |
| targetX = mouseX * 0.001; | |
| targetY = mouseY * 0.001; | |
| // Rotate particles based on mouse | |
| particles.rotation.y += 0.002; | |
| particles.rotation.x += (targetY - particles.rotation.x) * 0.05; | |
| particles.rotation.y += (targetX - particles.rotation.y) * 0.05; | |
| // Move particles towards camera to simulate tunnel | |
| const positions = particles.geometry.attributes.position.array; | |
| for(let i = 0; i < count; i++) { | |
| // Move Z | |
| positions[i * 3 + 2] += 0.5; // Speed | |
| // Reset if too close | |
| if(positions[i * 3 + 2] > 150) { | |
| positions[i * 3 + 2] = -250; | |
| } | |
| } | |
| particles.geometry.attributes.position.needsUpdate = true; | |
| // Subtle grid movement | |
| gridHelper.rotation.y = -mouseX * 0.0002; | |
| renderer.render(scene, camera); | |
| } | |
| animate(); | |
| // Handle Resize | |
| window.addEventListener('resize', () => { | |
| camera.aspect = window.innerWidth / window.innerHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| }); | |
| // --- 3. GSAP SCROLL ANIMATIONS --- | |
| gsap.registerPlugin(ScrollTrigger); | |
| function initAnimations() { | |
| // Hero Animations | |
| const heroTl = gsap.timeline(); | |
| heroTl.to('.hero-anim', { | |
| y: 0, | |
| opacity: 1, | |
| duration: 1, | |
| stagger: 0.2, | |
| ease: "power3.out" | |
| }); | |
| // KPI Counter Animation | |
| gsap.utils.toArray('.counter').forEach(counter => { | |
| const target = parseFloat(counter.getAttribute('data-target')); | |
| gsap.to(counter, { | |
| innerText: target, | |
| duration: 2, | |
| snap: { innerText: 0.1 }, | |
| scrollTrigger: { | |
| trigger: counter, | |
| start: "top 85%", | |
| toggleActions: "play none none reverse" | |
| } | |
| }); | |
| }); | |
| // Card Stagger Reveal | |
| gsap.from('.kpi-card', { | |
| y: 50, | |
| opacity: 0, | |
| duration: 1, | |
| stagger: 0.2, | |
| scrollTrigger: { | |
| trigger: '#kpi-section', | |
| start: "top 70%" | |
| } | |
| }); | |
| // Project Wireframe Reveal | |
| gsap.from('.project-trigger', { | |
| x: -50, | |
| opacity: 0, | |
| duration: 1, | |
| stagger: 0.2, | |
| scrollTrigger: { | |
| trigger: '#work', | |
| start: "top 70%" | |
| } | |
| }); | |
| // Research Accordion Logic (Manual JS for accordion effect) | |
| const researchItems = document.querySelectorAll('.research-item'); | |
| researchItems.forEach(item => { | |
| const header = item.querySelector('div.flex'); | |
| const content = item.querySelector('.max-h-0'); | |
| const icon = item.querySelector('i'); | |
| header.addEventListener('click', () => { | |
| const isOpen = content.style.maxHeight; | |
| // Close all others | |
| researchItems.forEach(otherItem => { | |
| otherItem.querySelector('.max-h-0').style.maxHeight = null; | |
| otherItem.querySelector('i').style.transform = 'rotate(0deg)'; | |
| }); | |
| // Toggle current | |
| if (!isOpen) { | |
| content.style.maxHeight = content.scrollHeight + "px"; | |
| icon.style.transform = 'rotate(180deg)'; | |
| } | |
| }); | |
| }); | |
| } | |
| // --- 4. CUSTOM CURSOR LOGIC --- | |
| const cursor = document.getElementById('cursor'); | |
| const triggers = document.querySelectorAll('.hover-trigger'); | |
| document.addEventListener('mousemove', (e) => { | |
| cursor.style.left = e.clientX + 'px'; | |
| cursor.style.top = e.clientY + 'px'; | |
| }); | |
| triggers.forEach(trigger => { | |
| trigger.addEventListener('mouseenter', () => { | |
| cursor.classList.add('hovered'); | |
| }); | |
| trigger.addEventListener('mouseleave', () => { | |
| cursor.classList.remove('hovered'); | |
| }); | |
| }); | |
| </script> | |
| </body> | |
| </html> |