File size: 3,975 Bytes
14a31b5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
// Counter animation
const counters = document.querySelectorAll('.counter');
const speed = 200;
const animateCounter = (counter) => {
const target = +counter.getAttribute('data-target');
const count = +counter.innerText;
const increment = target / speed;
if (count < target) {
counter.innerText = Math.ceil(count + increment);
setTimeout(() => animateCounter(counter), 1);
} else {
counter.innerText = target;
}
};
// Intersection Observer for counter animation
const observerOptions = {
threshold: 0.5
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
animateCounter(entry.target);
observer.unobserve(entry.target);
}
});
}, observerOptions);
counters.forEach(counter => {
observer.observe(counter);
});
// Particles.js configuration
if (document.getElementById('particles-js')) {
particlesJS('particles-js', {
particles: {
number: { value: 80, density: { enable: true, value_area: 800 } },
color: { value: ['#06b6d4', '#8b5cf6', '#ec4899'] },
shape: { type: 'circle' },
opacity: { value: 0.5, random: true },
size: { value: 3, random: true },
line_linked: {
enable: true,
distance: 150,
color: '#06b6d4',
opacity: 0.2,
width: 1
},
move: {
enable: true,
speed: 2,
direction: 'none',
random: true,
straight: false,
out_mode: 'out',
bounce: false
}
},
interactivity: {
detect_on: 'canvas',
events: {
onhover: { enable: true, mode: 'grab' },
onclick: { enable: true, mode: 'push' },
resize: true
},
modes: {
grab: { distance: 200, line_linked: { opacity: 0.5 } },
push: { particles_nb: 4 }
}
},
retina_detect: true
});
}
// Smooth scroll for anchor links
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',
block: 'start'
});
}
});
});
// Add hover effect to cards
document.querySelectorAll('.group').forEach(card => {
card.addEventListener('mouseenter', function() {
this.style.transform = 'translateY(-5px)';
});
card.addEventListener('mouseleave', function() {
this.style.transform = 'translateY(0)';
});
});
// Form submission handler (placeholder)
document.querySelector('input[type="email"]')?.closest('div')?.querySelector('button')?.addEventListener('click', function(e) {
e.preventDefault();
const email = document.querySelector('input[type="email"]').value;
if (email) {
this.innerHTML = '<span class="relative z-10">β Check your email!</span>';
this.style.background = 'linear-gradient(to right, #10b981, #059669)';
}
});
// Mobile menu toggle (if needed)
const mobileMenuToggle = document.querySelector('[data-mobile-menu-toggle]');
const mobileMenu = document.querySelector('[data-mobile-menu]');
if (mobileMenuToggle && mobileMenu) {
mobileMenuToggle.addEventListener('click', () => {
mobileMenu.classList.toggle('hidden');
});
}
// Add scroll-based animations
window.addEventListener('scroll', () => {
const scrolled = window.pageYOffset;
const parallax = document.querySelector('#particles-js');
if (parallax) {
parallax.style.transform = `translateY(${scrolled * 0.5}px)`;
}
}); |