209 Zeilen
5.7 KiB
JavaScript
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();
|
|
}); |