document.addEventListener('DOMContentLoaded', () => {
// 1. Scroll Animations
const observerOptions = {
root: null,
rootMargin: '0px',
threshold: 0.15
};
const scrollObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('is-visible');
observer.unobserve(entry.target); // Only animate once
}
});
}, observerOptions);
document.querySelectorAll('.animate-on-scroll').forEach(el => {
scrollObserver.observe(el);
});
// 2. Video Performance Optimization (Play only in viewport)
const videoObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
if (entry.isIntersecting) {
video.play().catch(e => console.log('Autoplay prevented:', e));
} else {
video.pause();
}
});
}, { threshold: 0.1 }); // Trigger when 10% visible
document.querySelectorAll('video').forEach(video => {
videoObserver.observe(video);
});
// 3. Section 3: Digital Employees Showcase Tabs
const tabBtns = document.querySelectorAll('.tab-btn');
const tabContents = document.querySelectorAll('.tab-content');
const showcaseVideo = document.getElementById('showcase-video');
tabBtns.forEach(btn => {
btn.addEventListener('click', () => {
// Remove active from all
tabBtns.forEach(b => b.classList.remove('active'));
tabContents.forEach(c => {
c.classList.remove('active');
c.classList.remove('animating'); // Reset animation state
});
// Add active to clicked
btn.classList.add('active');
const targetId = btn.getAttribute('data-target');
const targetContent = document.getElementById(targetId);
if (targetContent) {
targetContent.classList.add('active');
// Trigger staggered slide-in by forcing a reflow
void targetContent.offsetWidth;
targetContent.classList.add('animating');
}
// Swap video instantly (assuming videos are named client1.mp4, client2.mp4, or similar mapping)
const videoSrc = btn.getAttribute('data-video');
if (videoSrc && showcaseVideo) {
// Only swap if source is different to prevent flickering
if (showcaseVideo.src !== new URL(videoSrc, window.location.href).href) {
showcaseVideo.src = videoSrc;
showcaseVideo.play().catch(e => {});
}
}
});
});
// 4. Section 5: Testimonials Slider
const slides = document.querySelectorAll('.testimonial-slide');
const navContainer = document.querySelector('.slider-nav');
const track = document.querySelector('.testimonial-track');
let currentSlideIndex = 0;
// Generate dots dynamically based on number of slides
if (slides.length > 0 && navContainer) {
slides.forEach((_, idx) => {
const dot = document.createElement('button');
dot.classList.add('slider-dot');
if (idx === 0) dot.classList.add('active');
dot.addEventListener('click', () => goToSlide(idx));
navContainer.appendChild(dot);
});
const dots = document.querySelectorAll('.slider-dot');
function goToSlide(index) {
if (index < 0 || index >= slides.length) return;
currentSlideIndex = index;
// Move track
const translateX = - (index * 20); // 20% width per slide since track is 500%
track.style.transform = `translateX(${translateX}%)`;
// Update dots
dots.forEach(d => d.classList.remove('active'));
dots[index].classList.add('active');
}
// Optional: Auto-play slider
// setInterval(() => {
// let next = (currentSlideIndex + 1) % slides.length;
// goToSlide(next);
// }, 5000);
}
});