Files
Website/js/hero-videos.js
2025-08-17 14:16:58 +02:00

209 Zeilen
5.7 KiB
JavaScript

/**
* Hero Video Rotation System
* Manages rotating background videos in hero section
*/
const HeroVideoRotation = {
videos: [],
currentIndex: 0,
rotationInterval: null,
isTransitioning: false,
/**
* Initialize the video rotation system
*/
init() {
// Get all video elements
this.videos = document.querySelectorAll('.hero-video');
if (!this.videos.length) return;
// Setup event listeners
this.setupEventListeners();
// Start rotation
this.startRotation();
// Ensure first video is playing
this.playVideo(0);
},
/**
* Setup event listeners for videos
*/
setupEventListeners() {
// Indicators removed - no click handlers needed
// Pause rotation on hover (optional)
const heroSection = document.querySelector('.hero');
if (heroSection) {
heroSection.addEventListener('mouseenter', () => {
// Optional: pause rotation on hover
// this.stopRotation();
});
heroSection.addEventListener('mouseleave', () => {
// Optional: resume rotation
// this.startRotation();
});
}
// Handle video load errors gracefully
this.videos.forEach((video, index) => {
video.addEventListener('error', () => {
console.warn(`Video ${index} failed to load, skipping...`);
// If current video fails, move to next
if (index === this.currentIndex) {
this.nextVideo();
}
});
// Ensure videos are ready to play
video.addEventListener('loadeddata', () => {
console.log(`Video ${index} loaded successfully`);
});
});
},
/**
* Start automatic rotation
*/
startRotation() {
// Clear any existing interval
this.stopRotation();
// Set new interval
this.rotationInterval = setInterval(() => {
this.nextVideo();
}, CONFIG.HERO_VIDEOS.ROTATION_INTERVAL);
},
/**
* Stop automatic rotation
*/
stopRotation() {
if (this.rotationInterval) {
clearInterval(this.rotationInterval);
this.rotationInterval = null;
}
},
/**
* Switch to next video
*/
nextVideo() {
const nextIndex = (this.currentIndex + 1) % this.videos.length;
this.switchToVideo(nextIndex);
},
/**
* Switch to previous video
*/
previousVideo() {
const prevIndex = (this.currentIndex - 1 + this.videos.length) % this.videos.length;
this.switchToVideo(prevIndex);
},
/**
* Switch to specific video by index
* @param {number} index - Video index to switch to
*/
switchToVideo(index) {
if (this.isTransitioning || index === this.currentIndex) return;
this.isTransitioning = true;
const currentVideo = this.videos[this.currentIndex];
const nextVideo = this.videos[index];
// Indicators removed - no update needed
// Prepare next video
this.prepareVideo(nextVideo);
// Fade out current video
currentVideo.classList.add('fading-out');
// After half the fade duration, start fading in the next video
setTimeout(() => {
nextVideo.classList.add('active');
nextVideo.classList.remove('fading-out');
// Play next video
this.playVideo(index);
}, CONFIG.HERO_VIDEOS.FADE_DURATION / 2);
// Complete transition
setTimeout(() => {
currentVideo.classList.remove('active', 'fading-out');
this.currentIndex = index;
this.isTransitioning = false;
}, CONFIG.HERO_VIDEOS.FADE_DURATION);
},
/**
* Prepare video for playback
* @param {HTMLVideoElement} video - Video element to prepare
*/
prepareVideo(video) {
// Reset video to beginning
video.currentTime = 0;
// Ensure video is ready to play
const playPromise = video.play();
if (playPromise !== undefined) {
playPromise.catch(error => {
console.warn('Video autoplay was prevented:', error);
});
}
},
/**
* Play specific video
* @param {number} index - Index of video to play
*/
playVideo(index) {
const video = this.videos[index];
if (video) {
const playPromise = video.play();
if (playPromise !== undefined) {
playPromise.catch(error => {
console.warn(`Could not play video ${index}:`, error);
});
}
}
},
/**
* Pause all videos
*/
pauseAllVideos() {
this.videos.forEach(video => {
video.pause();
});
},
/**
* Handle page visibility change (pause when tab is not visible)
*/
handleVisibilityChange() {
if (document.hidden) {
this.stopRotation();
this.pauseAllVideos();
} else {
this.playVideo(this.currentIndex);
this.startRotation();
}
}
};
// Initialize when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
HeroVideoRotation.init();
});
// Handle page visibility API
document.addEventListener('visibilitychange', () => {
HeroVideoRotation.handleVisibilityChange();
});