lattmamb/deepvision_builderOS
1
1// Main JavaScript functionality for Unity Fleet website2 3document.addEventListener('DOMContentLoaded', function() {4 // Initialize animations and interactions5 initScrollAnimations();6 initAccordion();7 initParallaxEffect();8 initHeroAnimation();9 10 // Mobile navigation toggle11 const navLinks = document.querySelector('.nav-links');12 const mobileNavToggle = document.createElement('div');13 mobileNavToggle.className = 'mobile-nav-toggle';14 mobileNavToggle.innerHTML = '<i class="fas fa-bars"></i>';15 document.querySelector('nav').appendChild(mobileNavToggle);16 17 mobileNavToggle.addEventListener('click', function() {18 navLinks.classList.toggle('active');19 this.innerHTML = navLinks.classList.contains('active') 20 ? '<i class="fas fa-times"></i>' 21 : '<i class="fas fa-bars"></i>';22 });23});24 25// Scroll animations for elements26function initScrollAnimations() {27 const animatedElements = document.querySelectorAll('.section-header, .feature-item, .subscription-card, .impact-metric, .token-diagram, .rural-content, .timeline-item');28 29 const observer = new IntersectionObserver((entries) => {30 entries.forEach(entry => {31 if (entry.isIntersecting) {32 entry.target.classList.add('animate');33 observer.unobserve(entry.target);34 }35 });36 }, {37 threshold: 0.138 });39 40 animatedElements.forEach(element => {41 element.classList.add('pre-animation');42 observer.observe(element);43 });44 45 // Add CSS for animations46 const style = document.createElement('style');47 style.textContent = `48 .pre-animation {49 opacity: 0;50 transform: translateY(30px);51 transition: opacity 0.6s ease, transform 0.6s ease;52 }53 54 .animate {55 opacity: 1;56 transform: translateY(0);57 }58 59 .subscription-card.pre-animation {60 transform: translateY(50px);61 transition-delay: calc(var(--animation-order, 0) * 0.1s);62 }63 64 .feature-item.pre-animation {65 transform: translateX(-30px);66 transition-delay: calc(var(--animation-order, 0) * 0.1s);67 }68 69 .timeline-item.pre-animation {70 transform: translateX(-30px);71 transition-delay: calc(var(--animation-order, 0) * 0.15s);72 }73 `;74 document.head.appendChild(style);75 76 // Set animation order for staggered animations77 document.querySelectorAll('.subscription-card').forEach((card, index) => {78 card.style.setProperty('--animation-order', index);79 });80 81 document.querySelectorAll('.feature-item').forEach((item, index) => {82 item.style.setProperty('--animation-order', index);83 });84 85 document.querySelectorAll('.timeline-item').forEach((item, index) => {86 item.style.setProperty('--animation-order', index);87 });88}89 90// Accordion functionality for grant proposal section91function initAccordion() {92 const accordionItems = document.querySelectorAll('.accordion-item');93 94 accordionItems.forEach(item => {95 const header = item.querySelector('.accordion-header');96 const content = item.querySelector('.accordion-content');97 98 header.addEventListener('click', () => {99 // Close all other accordion items100 accordionItems.forEach(otherItem => {101 if (otherItem !== item && otherItem.classList.contains('active')) {102 otherItem.classList.remove('active');103 otherItem.querySelector('.accordion-content').style.maxHeight = '0px';104 }105 });106 107 // Toggle current item108 item.classList.toggle('active');109 110 if (item.classList.contains('active')) {111 content.style.display = 'block';112 content.style.maxHeight = content.scrollHeight + 'px';113 } else {114 content.style.maxHeight = '0px';115 setTimeout(() => {116 content.style.display = 'none';117 }, 300);118 }119 });120 });121 122 // Open first accordion item by default123 if (accordionItems.length > 0) {124 accordionItems[0].classList.add('active');125 const firstContent = accordionItems[0].querySelector('.accordion-content');126 firstContent.style.display = 'block';127 firstContent.style.maxHeight = firstContent.scrollHeight + 'px';128 }129 130 // Add CSS for accordion animations131 const style = document.createElement('style');132 style.textContent = `133 .accordion-content {134 max-height: 0;135 overflow: hidden;136 transition: max-height 0.3s ease;137 }138 `;139 document.head.appendChild(style);140}141 142// Parallax effect for sections143function initParallaxEffect() {144 window.addEventListener('scroll', () => {145 const scrollPosition = window.pageYOffset;146 147 // Parallax for hero section148 const heroImage = document.querySelector('.hero-image');149 if (heroImage) {150 heroImage.style.transform = `translateY(${scrollPosition * 0.4}px)`;151 }152 153 // Subtle parallax for section backgrounds154 document.querySelectorAll('.section-gradient').forEach(section => {155 const sectionTop = section.offsetTop;156 const sectionHeight = section.offsetHeight;157 const sectionMiddle = sectionTop + sectionHeight / 2;158 const distanceFromMiddle = scrollPosition - sectionMiddle;159 const parallaxValue = distanceFromMiddle * 0.05;160 161 section.style.backgroundPosition = `center ${50 + parallaxValue}%`;162 });163 });164}165 166// Hero section animations167function initHeroAnimation() {168 const heroContent = document.querySelector('.hero-content');169 const heroElements = heroContent.querySelectorAll('h1, h2, p, .cta-buttons');170 171 // Add CSS for hero animations172 const style = document.createElement('style');173 style.textContent = `174 @keyframes fadeInUp {175 from {176 opacity: 0;177 transform: translateY(30px);178 }179 to {180 opacity: 1;181 transform: translateY(0);182 }183 }184 185 .hero-animate {186 animation: fadeInUp 0.8s forwards;187 opacity: 0;188 }189 `;190 document.head.appendChild(style);191 192 // Apply staggered animations to hero elements193 heroElements.forEach((element, index) => {194 element.classList.add('hero-animate');195 element.style.animationDelay = `${0.3 + (index * 0.2)}s`;196 });197 198 // Add hover effect to CTA buttons199 document.querySelectorAll('.cta-buttons .btn').forEach(button => {200 button.addEventListener('mouseenter', function() {201 this.style.transform = 'translateY(-5px)';202 this.style.boxShadow = '0 15px 30px rgba(0, 224, 255, 0.3)';203 });204 205 button.addEventListener('mouseleave', function() {206 this.style.transform = '';207 this.style.boxShadow = '';208 });209 });210}211 212// Add smooth scrolling for navigation links213document.querySelectorAll('a[href^="#"]').forEach(anchor => {214 anchor.addEventListener('click', function(e) {215 e.preventDefault();216 217 const targetId = this.getAttribute('href');218 const targetElement = document.querySelector(targetId);219 220 if (targetElement) {221 // Close mobile navigation if open222 document.querySelector('.nav-links').classList.remove('active');223 document.querySelector('.mobile-nav-toggle').innerHTML = '<i class="fas fa-bars"></i>';224 225 // Scroll to target226 window.scrollTo({227 top: targetElement.offsetTop - 80, // Offset for fixed header228 behavior: 'smooth'229 });230 }231 });232});233 234// Add fixed navigation on scroll235window.addEventListener('scroll', function() {236 const nav = document.querySelector('nav');237 if (window.scrollY > 100) {238 nav.classList.add('nav-scrolled');239 } else {240 nav.classList.remove('nav-scrolled');241 }242});243 244// Add CSS for fixed navigation245const navStyle = document.createElement('style');246navStyle.textContent = `247 .nav-scrolled {248 position: fixed;249 background: rgba(11, 11, 15, 0.9);250 backdrop-filter: blur(10px);251 box-shadow: 0 5px 20px rgba(0, 0, 0, 0.3);252 animation: slideDown 0.3s forwards;253 }254 255 @keyframes slideDown {256 from {257 transform: translateY(-100%);258 }259 to {260 transform: translateY(0);261 }262 }263 264 @media (max-width: 768px) {265 .mobile-nav-toggle {266 display: block;267 font-size: 1.5rem;268 cursor: pointer;269 color: var(--accent-color-1);270 }271 272 .nav-links {273 position: absolute;274 top: 100%;275 left: 0;276 width: 100%;277 background: rgba(11, 11, 15, 0.95);278 flex-direction: column;279 padding: 1rem 0;280 clip-path: polygon(0 0, 100% 0, 100% 0, 0 0);281 transition: clip-path 0.4s ease;282 }283 284 .nav-links.active {285 clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);286 }287 288 .nav-links a {289 padding: 1rem 2rem;290 }291 }292`;293document.head.appendChild(navStyle);294 295// Add token orbit animation296const orbitStyle = document.createElement('style');297orbitStyle.textContent = `298 .orbit-item {299 transition: transform 0.3s ease, background 0.3s ease;300 }301 302 .orbit-item:hover {303 transform: scale(1.2) !important;304 background: var(--accent-color-1);305 color: var(--bg-color);306 }307`;308document.head.appendChild(orbitStyle);309 310// Add hover effects to image cards311document.querySelectorAll('.image-card').forEach(card => {312 card.addEventListener('mouseenter', function() {313 this.querySelector('img').style.transform = 'scale(1.05)';314 this.querySelector('.image-overlay').style.opacity = '1';315 });316 317 card.addEventListener('mouseleave', function() {318 this.querySelector('img').style.transform = 'scale(1)';319 this.querySelector('.image-overlay').style.opacity = '0.8';320 });321});322 323// Add CSS for image card hover effects324const imageCardStyle = document.createElement('style');325imageCardStyle.textContent = `326 .image-card img {327 transition: transform 0.5s ease;328 }329 330 .image-overlay {331 opacity: 0.8;332 transition: opacity 0.3s ease;333 }334`;335document.head.appendChild(imageCardStyle);336 