// ============================================ // FUTURISTIC CHRISTMAS - LEAFBOX TECHNOLOGIES // JavaScript Interactions & Animations // ============================================ // ========== CONFIGURATION ========== const CONFIG = { snow: { count: 100, maxSize: 4, minSize: 1, speed: 0.5 }, tree: { particleCount: 150, glowIntensity: 20 }, sound: { enabled: false, volume: 0.3 } }; // ========== PARTICLE SNOW ANIMATION ========== class SnowCanvas { constructor(canvasId) { this.canvas = document.getElementById(canvasId); this.ctx = this.canvas.getContext('2d'); this.particles = []; this.init(); this.animate(); } init() { this.resize(); window.addEventListener('resize', () => this.resize()); this.createParticles(); } resize() { this.canvas.width = window.innerWidth; this.canvas.height = window.innerHeight; } createParticles() { this.particles = []; const particleCount = window.innerWidth < 768 ? 50 : CONFIG.snow.count; for (let i = 0; i < particleCount; i++) { this.particles.push({ x: Math.random() * this.canvas.width, y: Math.random() * this.canvas.height, size: Math.random() * (CONFIG.snow.maxSize - CONFIG.snow.minSize) + CONFIG.snow.minSize, speedY: Math.random() * CONFIG.snow.speed + 0.5, speedX: Math.random() * 0.5 - 0.25, opacity: Math.random() * 0.5 + 0.3, color: this.getSnowColor() }); } } getSnowColor() { const colors = ['#00E5FF', '#00FF99', '#FFFFFF']; return colors[Math.floor(Math.random() * colors.length)]; } animate() { this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); this.particles.forEach(particle => { // Draw particle this.ctx.beginPath(); this.ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2); this.ctx.fillStyle = particle.color; this.ctx.globalAlpha = particle.opacity; this.ctx.fill(); // Add glow effect const gradient = this.ctx.createRadialGradient( particle.x, particle.y, 0, particle.x, particle.y, particle.size * 2 ); gradient.addColorStop(0, particle.color); gradient.addColorStop(1, 'transparent'); this.ctx.fillStyle = gradient; this.ctx.globalAlpha = particle.opacity * 0.5; this.ctx.fill(); // Update position particle.y += particle.speedY; particle.x += particle.speedX; // Reset particle when it goes off screen if (particle.y > this.canvas.height) { particle.y = -10; particle.x = Math.random() * this.canvas.width; } if (particle.x > this.canvas.width || particle.x < 0) { particle.x = Math.random() * this.canvas.width; } }); this.ctx.globalAlpha = 1; requestAnimationFrame(() => this.animate()); } } // ========== DIGITAL CHRISTMAS TREE ========== class DigitalTree { constructor(canvasId) { this.canvas = document.getElementById(canvasId); this.ctx = this.canvas.getContext('2d'); this.particles = []; this.lines = []; this.animationProgress = 0; this.init(); } init() { // Set canvas size const size = window.innerWidth < 768 ? 300 : 400; this.canvas.width = size; this.canvas.height = size; this.createTreeStructure(); this.animate(); } createTreeStructure() { const centerX = this.canvas.width / 2; const baseY = this.canvas.height - 50; const topY = 30; const maxWidth = this.canvas.width * 0.6; // Create tree outline with particles for (let i = 0; i < CONFIG.tree.particleCount; i++) { const progress = i / CONFIG.tree.particleCount; const y = baseY - (baseY - topY) * progress; const width = maxWidth * (1 - progress); const x = centerX + (Math.random() - 0.5) * width; this.particles.push({ x: x, y: y, targetX: x, targetY: y, currentX: centerX, currentY: baseY, size: Math.random() * 3 + 1, color: this.getTreeColor(), delay: Math.random() * 50, glowSize: Math.random() * 10 + 5 }); } // Create connecting lines for (let i = 0; i < this.particles.length - 1; i++) { if (Math.random() > 0.7) { this.lines.push({ start: this.particles[i], end: this.particles[i + 1] }); } } // Add star at top this.star = { x: centerX, y: topY - 20, size: 15, points: 5, rotation: 0 }; // Add trunk this.trunk = { x: centerX, y: baseY, width: 20, height: 40 }; } getTreeColor() { const colors = ['#00FF99', '#00E5FF', '#FFD700']; return colors[Math.floor(Math.random() * colors.length)]; } drawStar(x, y, size, rotation) { this.ctx.save(); this.ctx.translate(x, y); this.ctx.rotate(rotation); this.ctx.beginPath(); for (let i = 0; i < 5; i++) { const angle = (Math.PI * 2 * i) / 5 - Math.PI / 2; const x = Math.cos(angle) * size; const y = Math.sin(angle) * size; if (i === 0) { this.ctx.moveTo(x, y); } else { this.ctx.lineTo(x, y); } const innerAngle = angle + Math.PI / 5; const innerX = Math.cos(innerAngle) * (size * 0.4); const innerY = Math.sin(innerAngle) * (size * 0.4); this.ctx.lineTo(innerX, innerY); } this.ctx.closePath(); this.ctx.fillStyle = '#FFD700'; this.ctx.fill(); // Add glow this.ctx.shadowBlur = 20; this.ctx.shadowColor = '#FFD700'; this.ctx.fill(); this.ctx.restore(); } animate() { this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); // Update animation progress if (this.animationProgress < 1) { this.animationProgress += 0.01; } // Draw connecting lines this.lines.forEach(line => { const startProgress = Math.min(1, this.animationProgress * 2); const endProgress = Math.min(1, (this.animationProgress - 0.3) * 2); if (startProgress > line.start.delay / 100) { this.ctx.beginPath(); this.ctx.moveTo(line.start.currentX, line.start.currentY); this.ctx.lineTo(line.end.currentX, line.end.currentY); this.ctx.strokeStyle = 'rgba(0, 255, 153, 0.3)'; this.ctx.lineWidth = 1; this.ctx.stroke(); } }); // Draw and update particles this.particles.forEach(particle => { if (this.animationProgress > particle.delay / 100) { // Animate to target position const progress = Math.min(1, (this.animationProgress - particle.delay / 100) * 2); particle.currentX = particle.currentX + (particle.targetX - particle.currentX) * progress * 0.1; particle.currentY = particle.currentY + (particle.targetY - particle.currentY) * progress * 0.1; // Draw particle glow const gradient = this.ctx.createRadialGradient( particle.currentX, particle.currentY, 0, particle.currentX, particle.currentY, particle.glowSize ); gradient.addColorStop(0, particle.color); gradient.addColorStop(1, 'transparent'); this.ctx.fillStyle = gradient; this.ctx.globalAlpha = 0.6; this.ctx.fillRect( particle.currentX - particle.glowSize, particle.currentY - particle.glowSize, particle.glowSize * 2, particle.glowSize * 2 ); // Draw particle this.ctx.globalAlpha = 1; this.ctx.beginPath(); this.ctx.arc(particle.currentX, particle.currentY, particle.size, 0, Math.PI * 2); this.ctx.fillStyle = particle.color; this.ctx.fill(); } }); // Draw trunk this.ctx.fillStyle = '#374151'; this.ctx.fillRect( this.trunk.x - this.trunk.width / 2, this.trunk.y, this.trunk.width, this.trunk.height ); // Draw star if (this.animationProgress > 0.8) { this.star.rotation += 0.02; this.drawStar(this.star.x, this.star.y, this.star.size, this.star.rotation); } requestAnimationFrame(() => this.animate()); } } // ========== COUNTDOWN TIMER ========== class CountdownTimer { constructor() { this.targetDate = new Date('2026-01-01T00:00:00').getTime(); this.elements = { days: document.getElementById('days'), hours: document.getElementById('hours'), minutes: document.getElementById('minutes'), seconds: document.getElementById('seconds') }; this.update(); setInterval(() => this.update(), 1000); } update() { const now = new Date().getTime(); const distance = this.targetDate - now; if (distance < 0) { this.displayTime(0, 0, 0, 0); return; } const days = Math.floor(distance / (1000 * 60 * 60 * 24)); const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); const seconds = Math.floor((distance % (1000 * 60)) / 1000); this.displayTime(days, hours, minutes, seconds); } displayTime(days, hours, minutes, seconds) { this.elements.days.textContent = String(days).padStart(2, '0'); this.elements.hours.textContent = String(hours).padStart(2, '0'); this.elements.minutes.textContent = String(minutes).padStart(2, '0'); this.elements.seconds.textContent = String(seconds).padStart(2, '0'); } } // ========== THEME TOGGLE ========== class ThemeToggle { constructor() { this.button = document.getElementById('themeToggle'); this.currentTheme = localStorage.getItem('theme') || 'dark'; this.init(); } init() { this.applyTheme(this.currentTheme); this.button.addEventListener('click', () => this.toggle()); } toggle() { this.currentTheme = this.currentTheme === 'dark' ? 'light' : 'dark'; this.applyTheme(this.currentTheme); localStorage.setItem('theme', this.currentTheme); } applyTheme(theme) { if (theme === 'light') { document.body.classList.add('light-theme'); } else { document.body.classList.remove('light-theme'); } } } // ========== SOUND TOGGLE ========== class SoundToggle { constructor() { this.button = document.getElementById('soundToggle'); this.audio = null; this.isPlaying = false; this.init(); } init() { this.button.addEventListener('click', () => this.toggle()); // Create audio context (simple chime sound using Web Audio API) this.createAudioContext(); } createAudioContext() { try { this.audioContext = new (window.AudioContext || window.webkitAudioContext)(); } catch (e) { console.log('Web Audio API not supported'); } } playChime() { if (!this.audioContext) return; const now = this.audioContext.currentTime; const oscillator = this.audioContext.createOscillator(); const gainNode = this.audioContext.createGain(); oscillator.connect(gainNode); gainNode.connect(this.audioContext.destination); // Christmas bell-like sound oscillator.frequency.setValueAtTime(800, now); oscillator.frequency.exponentialRampToValueAtTime(400, now + 0.1); gainNode.gain.setValueAtTime(0.3, now); gainNode.gain.exponentialRampToValueAtTime(0.01, now + 0.5); oscillator.start(now); oscillator.stop(now + 0.5); } toggle() { this.isPlaying = !this.isPlaying; if (this.isPlaying) { this.button.classList.remove('muted'); this.playChime(); // Play chime periodically this.interval = setInterval(() => this.playChime(), 5000); } else { this.button.classList.add('muted'); if (this.interval) { clearInterval(this.interval); } } } } // ========== EASTER EGG ========== class EasterEgg { constructor() { this.modal = document.getElementById('easterEggModal'); this.closeBtn = document.getElementById('modalClose'); this.trigger = document.getElementById('easterEgg'); this.privacyLink = document.getElementById('privacyLink'); this.clickCount = 0; this.init(); } init() { // Easter egg on cybersecurity card this.trigger.addEventListener('click', (e) => { this.clickCount++; if (this.clickCount === 3) { this.show(); this.clickCount = 0; } }); // Easter egg on privacy link this.privacyLink.addEventListener('click', (e) => { e.preventDefault(); this.show(); }); this.closeBtn.addEventListener('click', () => this.hide()); this.modal.addEventListener('click', (e) => { if (e.target === this.modal) { this.hide(); } }); // Keyboard shortcut: Ctrl+Shift+X document.addEventListener('keydown', (e) => { if (e.ctrlKey && e.shiftKey && e.key === 'X') { this.show(); } }); } show() { this.modal.classList.add('active'); document.body.style.overflow = 'hidden'; } hide() { this.modal.classList.remove('active'); document.body.style.overflow = ''; } } // ========== SMOOTH SCROLL ========== function initSmoothScroll() { document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { const href = this.getAttribute('href'); if (href === '#' || href === '#!') return; e.preventDefault(); const target = document.querySelector(href); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); }); } // ========== SCROLL ANIMATIONS ========== class ScrollAnimations { constructor() { this.elements = document.querySelectorAll('.timeline-item, .service-card'); this.init(); } init() { this.observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.style.opacity = '1'; entry.target.style.transform = 'translateY(0)'; } }); }, { threshold: 0.1 }); this.elements.forEach(el => { this.observer.observe(el); }); } } // ========== INTERACTIVE PARTICLES ON HOVER ========== class InteractiveParticles { constructor() { this.init(); } init() { const serviceCards = document.querySelectorAll('.service-card'); serviceCards.forEach(card => { card.addEventListener('mouseenter', (e) => { this.createParticleBurst(e.currentTarget); }); }); } createParticleBurst(element) { const rect = element.getBoundingClientRect(); const particles = 10; for (let i = 0; i < particles; i++) { const particle = document.createElement('div'); particle.style.position = 'fixed'; particle.style.left = rect.left + rect.width / 2 + 'px'; particle.style.top = rect.top + rect.height / 2 + 'px'; particle.style.width = '4px'; particle.style.height = '4px'; particle.style.borderRadius = '50%'; particle.style.background = 'var(--leaf-green)'; particle.style.pointerEvents = 'none'; particle.style.zIndex = '9999'; particle.style.boxShadow = '0 0 10px var(--leaf-green)'; document.body.appendChild(particle); const angle = (Math.PI * 2 * i) / particles; const velocity = 100; const vx = Math.cos(angle) * velocity; const vy = Math.sin(angle) * velocity; let x = 0, y = 0; const animate = () => { x += vx * 0.01; y += vy * 0.01; particle.style.transform = `translate(${x}px, ${y}px)`; particle.style.opacity = Math.max(0, 1 - Math.sqrt(x * x + y * y) / 100); if (Math.sqrt(x * x + y * y) < 100) { requestAnimationFrame(animate); } else { particle.remove(); } }; animate(); } } } // ========== CONTACT BUTTON INTERACTION ========== function initContactButton() { const contactButton = document.getElementById('contactButton'); contactButton.addEventListener('click', () => { // Create a glowing pulse effect const pulse = document.createElement('div'); pulse.style.position = 'fixed'; pulse.style.left = '50%'; pulse.style.top = '50%'; pulse.style.transform = 'translate(-50%, -50%)'; pulse.style.width = '0px'; pulse.style.height = '0px'; pulse.style.borderRadius = '50%'; pulse.style.border = '2px solid var(--leaf-green)'; pulse.style.pointerEvents = 'none'; pulse.style.zIndex = '9999'; document.body.appendChild(pulse); let size = 0; const animate = () => { size += 20; pulse.style.width = size + 'px'; pulse.style.height = size + 'px'; pulse.style.opacity = Math.max(0, 1 - size / 500); if (size < 500) { requestAnimationFrame(animate); } else { pulse.remove(); } }; animate(); // Show alert setTimeout(() => { alert('🎄 Thank you for your interest! Our team will contact you soon.\n\nEmail: hello@leafbox.tech\nPhone: +1 (555) 123-4567'); }, 300); }); } // ========== CURSOR TRAIL EFFECT ========== class CursorTrail { constructor() { this.trail = []; this.maxTrail = 20; this.init(); } init() { if (window.innerWidth < 768) return; // Disable on mobile document.addEventListener('mousemove', (e) => { this.trail.push({ x: e.clientX, y: e.clientY, timestamp: Date.now() }); if (this.trail.length > this.maxTrail) { this.trail.shift(); } this.render(); }); } render() { // Remove old trail elements document.querySelectorAll('.cursor-trail').forEach(el => { if (Date.now() - parseInt(el.dataset.timestamp) > 500) { el.remove(); } }); // Create new trail element if (this.trail.length > 0) { const last = this.trail[this.trail.length - 1]; const trail = document.createElement('div'); trail.className = 'cursor-trail'; trail.style.position = 'fixed'; trail.style.left = last.x + 'px'; trail.style.top = last.y + 'px'; trail.style.width = '6px'; trail.style.height = '6px'; trail.style.borderRadius = '50%'; trail.style.background = 'var(--ice-blue)'; trail.style.pointerEvents = 'none'; trail.style.zIndex = '9998'; trail.style.boxShadow = '0 0 10px var(--ice-blue)'; trail.style.opacity = '0.6'; trail.style.transform = 'translate(-50%, -50%)'; trail.style.transition = 'opacity 0.5s ease-out'; trail.dataset.timestamp = last.timestamp; document.body.appendChild(trail); setTimeout(() => { trail.style.opacity = '0'; }, 10); } } } // ========== INITIALIZE ALL ========== document.addEventListener('DOMContentLoaded', () => { console.log('🎄 LeafBox Technologies - Merry Christmas! 🎄'); console.log('Where technology meets the magic of Christmas ✨'); // Initialize all components const snowCanvas = new SnowCanvas('snowCanvas'); const digitalTree = new DigitalTree('treeCanvas'); const countdown = new CountdownTimer(); const themeToggle = new ThemeToggle(); const soundToggle = new SoundToggle(); const easterEgg = new EasterEgg(); const scrollAnimations = new ScrollAnimations(); const interactiveParticles = new InteractiveParticles(); const cursorTrail = new CursorTrail(); initSmoothScroll(); initContactButton(); // Log easter egg hint console.log('💡 Hint: Try clicking the Cybersecurity card 3 times... 🎁'); console.log('💡 Or use the keyboard shortcut: Ctrl+Shift+X'); }); // ========== PERFORMANCE OPTIMIZATION ========== // Reduce animations on low-end devices if (navigator.hardwareConcurrency < 4) { CONFIG.snow.count = 50; CONFIG.tree.particleCount = 100; } // Pause animations when tab is not visible document.addEventListener('visibilitychange', () => { if (document.hidden) { // Pause non-essential animations console.log('Tab hidden - pausing animations'); } else { console.log('Tab visible - resuming animations'); } });