|
|
|
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' |
|
}); |
|
} |
|
}); |
|
}); |
|
|
|
|
|
function animateValue(element, start, end, duration) { |
|
let startTimestamp = null; |
|
const step = (timestamp) => { |
|
if (!startTimestamp) startTimestamp = timestamp; |
|
const progress = Math.min((timestamp - startTimestamp) / duration, 1); |
|
const value = Math.floor(progress * (end - start) + start); |
|
element.textContent = value; |
|
if (progress < 1) { |
|
window.requestAnimationFrame(step); |
|
} |
|
}; |
|
window.requestAnimationFrame(step); |
|
} |
|
|
|
|
|
window.addEventListener('load', () => { |
|
const statNumbers = document.querySelectorAll('.stat-number'); |
|
statNumbers.forEach(stat => { |
|
const text = stat.textContent; |
|
if (text.includes('%')) { |
|
const value = parseInt(text); |
|
stat.textContent = '0%'; |
|
animateValue(stat, 0, value, 2000); |
|
setTimeout(() => { |
|
stat.textContent = value + '%'; |
|
}, 2000); |
|
} else if (text.includes('x')) { |
|
stat.textContent = '0x'; |
|
setTimeout(() => { |
|
stat.textContent = text; |
|
}, 1500); |
|
} else { |
|
const value = parseInt(text); |
|
animateValue(stat, 0, value, 2000); |
|
} |
|
}); |
|
}); |
|
|
|
|
|
const observerOptions = { |
|
threshold: 0.1, |
|
rootMargin: '0px 0px -100px 0px' |
|
}; |
|
|
|
const observer = new IntersectionObserver((entries) => { |
|
entries.forEach(entry => { |
|
if (entry.isIntersecting) { |
|
entry.target.classList.add('visible'); |
|
} |
|
}); |
|
}, observerOptions); |
|
|
|
|
|
document.querySelectorAll('.chart-card, .pricing-card, .testimonial-card').forEach(el => { |
|
el.style.opacity = '0'; |
|
el.style.transform = 'translateY(30px)'; |
|
observer.observe(el); |
|
}); |
|
|
|
|
|
const style = document.createElement('style'); |
|
style.textContent = ` |
|
.visible { |
|
opacity: 1 !important; |
|
transform: translateY(0) !important; |
|
transition: opacity 0.6s ease, transform 0.6s ease; |
|
} |
|
`; |
|
document.head.appendChild(style); |
|
|
|
|
|
let lastScroll = 0; |
|
const header = document.querySelector('header'); |
|
|
|
window.addEventListener('scroll', () => { |
|
const currentScroll = window.pageYOffset; |
|
|
|
if (currentScroll > 100) { |
|
header.style.boxShadow = '0 2px 10px rgba(0,0,0,0.1)'; |
|
} else { |
|
header.style.boxShadow = 'var(--shadow-sm)'; |
|
} |
|
|
|
lastScroll = currentScroll; |
|
}); |
|
|
|
|
|
document.querySelectorAll('.primary-button, .secondary-button, .pricing-button').forEach(button => { |
|
button.addEventListener('click', function(e) { |
|
|
|
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); |
|
|
|
setTimeout(() => { |
|
ripple.remove(); |
|
}, 600); |
|
}); |
|
}); |
|
|
|
|
|
const rippleStyle = document.createElement('style'); |
|
rippleStyle.textContent = ` |
|
.primary-button, .secondary-button, .pricing-button { |
|
position: relative; |
|
overflow: hidden; |
|
} |
|
|
|
.ripple { |
|
position: absolute; |
|
border-radius: 50%; |
|
background: rgba(255, 255, 255, 0.5); |
|
transform: scale(0); |
|
animation: ripple-animation 0.6s ease-out; |
|
} |
|
|
|
@keyframes ripple-animation { |
|
to { |
|
transform: scale(4); |
|
opacity: 0; |
|
} |
|
} |
|
`; |
|
document.head.appendChild(rippleStyle); |
|
|
|
|
|
document.querySelectorAll('tbody tr').forEach(row => { |
|
row.addEventListener('mouseenter', function() { |
|
this.style.transform = 'scale(1.02)'; |
|
this.style.transition = 'transform 0.3s ease'; |
|
}); |
|
|
|
row.addEventListener('mouseleave', function() { |
|
this.style.transform = 'scale(1)'; |
|
}); |
|
}); |
|
|
|
|
|
window.addEventListener('load', () => { |
|
const bars = document.querySelectorAll('.bar'); |
|
bars.forEach(bar => { |
|
const width = bar.style.width; |
|
bar.style.width = '0'; |
|
setTimeout(() => { |
|
bar.style.width = width; |
|
}, 500); |
|
}); |
|
}); |
|
|
|
|
|
const galleryItems = document.querySelectorAll('.gallery-item'); |
|
const prevBtn = document.querySelector('.demo-nav.prev'); |
|
const nextBtn = document.querySelector('.demo-nav.next'); |
|
let currentIndex = 0; |
|
|
|
function updateGallery(index) { |
|
galleryItems.forEach((item, i) => { |
|
item.classList.toggle('active', i === index); |
|
}); |
|
} |
|
|
|
if (prevBtn && nextBtn) { |
|
prevBtn.addEventListener('click', () => { |
|
currentIndex = (currentIndex - 1 + galleryItems.length) % galleryItems.length; |
|
updateGallery(currentIndex); |
|
}); |
|
|
|
nextBtn.addEventListener('click', () => { |
|
currentIndex = (currentIndex + 1) % galleryItems.length; |
|
updateGallery(currentIndex); |
|
}); |
|
} |
|
|
|
galleryItems.forEach((item, index) => { |
|
item.addEventListener('click', () => { |
|
currentIndex = index; |
|
updateGallery(currentIndex); |
|
}); |
|
}); |