Spaces:
Running
Running
| // Main JavaScript file for Blue Horizon Explorer | |
| // Initialize when DOM is loaded | |
| document.addEventListener('DOMContentLoaded', function() { | |
| console.log('Blue Horizon Explorer loaded successfully!'); | |
| // Initialize animations on scroll | |
| initScrollAnimations(); | |
| // Initialize interactive elements | |
| initInteractiveElements(); | |
| }); | |
| // Function to initialize scroll animations | |
| function initScrollAnimations() { | |
| const observerOptions = { | |
| root: null, | |
| rootMargin: '0px', | |
| threshold: 0.1 | |
| }; | |
| const observer = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| entry.target.classList.add('fade-in'); | |
| } | |
| }); | |
| }, observerOptions); | |
| // Observe elements with data-animate attribute | |
| document.querySelectorAll('[data-animate]').forEach(el => { | |
| observer.observe(el); | |
| }); | |
| } | |
| // Function to initialize interactive elements | |
| function initInteractiveElements() { | |
| // Add click effects to buttons | |
| document.querySelectorAll('.btn-effect').forEach(button => { | |
| button.addEventListener('click', function(e) { | |
| // Create ripple effect | |
| const ripple = document.createElement('span'); | |
| const rect = this.getBoundingClientRect(); | |
| const size = Math.max(rect.width, rect.height); | |
| const x = e.clientX - rect.left - size / 2; | |
| const y = e.clientY - rect.top - size / 2; | |
| ripple.style.width = ripple.style.height = size + 'px'; | |
| ripple.style.left = x + 'px'; | |
| ripple.style.top = y + 'px'; | |
| ripple.classList.add('ripple'); | |
| this.appendChild(ripple); | |
| // Remove ripple after animation | |
| setTimeout(() => { | |
| ripple.remove(); | |
| }, 600); | |
| }); | |
| }); | |
| // Theme toggle functionality (for future dark mode implementation) | |
| const themeToggle = document.getElementById('themeToggle'); | |
| if (themeToggle) { | |
| themeToggle.addEventListener('click', function() { | |
| document.body.classList.toggle('dark-mode'); | |
| const icon = this.querySelector('i'); | |
| if (document.body.classList.contains('dark-mode')) { | |
| icon.setAttribute('data-feather', 'sun'); | |
| localStorage.setItem('theme', 'dark'); | |
| } else { | |
| icon.setAttribute('data-feather', 'moon'); | |
| localStorage.setItem('theme', 'light'); | |
| } | |
| feather.replace(); | |
| }); | |
| } | |
| // Load saved theme from localStorage | |
| const savedTheme = localStorage.getItem('theme'); | |
| if (savedTheme === 'dark') { | |
| document.body.classList.add('dark-mode'); | |
| if (themeToggle) { | |
| const icon = themeToggle.querySelector('i'); | |
| icon.setAttribute('data-feather', 'sun'); | |
| feather.replace(); | |
| } | |
| } | |
| } | |
| // Utility function to format numbers | |
| function formatNumber(num) { | |
| if (num >= 1000000) { | |
| return (num / 1000000).toFixed(1) + 'M'; | |
| } | |
| if (num >= 1000) { | |
| return (num / 1000).toFixed(1) + 'K'; | |
| } | |
| return num.toString(); | |
| } | |
| // API call example for future expansion | |
| async function fetchBlueContent() { | |
| try { | |
| const response = await fetch('https://api.unsplash.com/search/photos?query=blue&per_page=5', { | |
| headers: { | |
| 'Authorization': 'Client-ID YOUR_ACCESS_KEY' // Replace with actual key | |
| } | |
| }); | |
| const data = await response.json(); | |
| return data; | |
| } catch (error) { | |
| console.error('Error fetching blue content:', error); | |
| return null; | |
| } | |
| } | |
| // Export functions for use in components if needed | |
| window.BlueHorizonUtils = { | |
| formatNumber, | |
| fetchBlueContent | |
| }; |