| |
| function animateCountUp() { |
| const countElements = document.querySelectorAll('.countup'); |
| |
| const observer = new IntersectionObserver((entries) => { |
| entries.forEach(entry => { |
| if (entry.isIntersecting) { |
| const target = +entry.target.getAttribute('data-target'); |
| const duration = 2000; |
| const start = 0; |
| const increment = target / (duration / 16); |
| |
| let current = start; |
| const countUp = () => { |
| current += increment; |
| if (current < target) { |
| entry.target.textContent = Math.floor(current); |
| requestAnimationFrame(countUp); |
| } else { |
| entry.target.textContent = target + '+'; |
| entry.target.classList.add('countup-animate'); |
| } |
| }; |
| countUp(); |
| |
| observer.unobserve(entry.target); |
| } |
| }); |
| }, { threshold: 0.5 }); |
| |
| countElements.forEach(el => observer.observe(el)); |
| } |
|
|
| |
| document.addEventListener('DOMContentLoaded', () => { |
| animateCountUp(); |
| |
| |
| const featherIcons = document.querySelectorAll('[data-feather]'); |
| featherIcons.forEach(icon => { |
| icon.parentElement.addEventListener('mouseenter', () => { |
| icon.classList.add('animate-pulse'); |
| }); |
| icon.parentElement.addEventListener('mouseleave', () => { |
| icon.classList.remove('animate-pulse'); |
| }); |
| }); |
| |
| |
| document.querySelectorAll('a[href^="#"]').forEach(anchor => { |
| anchor.addEventListener('click', function (e) { |
| e.preventDefault(); |
| const target = document.querySelector(this.getAttribute('href')); |
| if (target) { |
| target.scrollIntoView({ |
| behavior: 'smooth' |
| }); |
| } |
| }); |
| }); |
| }); |