/** * 视频横幅功能脚本 * 处理视频播放、视频背景和GSAP动画 */ // 全局变量 let videoBannerInitialized = false; // 视频模态框功能 function openVideoModal(element) { const container = element.closest('.video-banner-container'); if (!container) return; const videoUrl = container.getAttribute('data-video-url'); const videoTitle = container.getAttribute('data-video-title') || '视频播放'; if (!videoUrl) return; const modal = document.getElementById('video-modal'); const modalVideo = document.getElementById('modal-video'); const modalTitle = document.getElementById('video-modal-title'); if (modal && modalVideo && modalTitle) { modalTitle.textContent = videoTitle; modalVideo.src = videoUrl; modal.style.display = 'block'; // 添加动画效果 if (typeof gsap !== 'undefined') { gsap.fromTo(modal.querySelector('.video-modal-content'), { scale: 0.8, opacity: 0 }, { scale: 1, opacity: 1, duration: 0.3, ease: "back.out(1.7)" } ); } // 阻止背景滚动 document.body.style.overflow = 'hidden'; } } function closeVideoModal() { const modal = document.getElementById('video-modal'); const modalVideo = document.getElementById('modal-video'); if (modal && modalVideo) { // 添加关闭动画 if (typeof gsap !== 'undefined') { gsap.to(modal.querySelector('.video-modal-content'), { scale: 0.8, opacity: 0, duration: 0.2, ease: "power2.in", onComplete: () => { modal.style.display = 'none'; modalVideo.src = ''; document.body.style.overflow = ''; } }); } else { modal.style.display = 'none'; modalVideo.src = ''; document.body.style.overflow = ''; } } } // 视频背景管理 class VideoBannerManager { constructor() { this.containers = []; this.init(); } init() { this.findContainers(); this.setupEventListeners(); this.initializeVideos(); this.setupAnimations(); } findContainers() { this.containers = Array.from(document.querySelectorAll('.video-banner-container')); } setupEventListeners() { // 窗口调整大小时重新初始化 window.addEventListener('resize', this.debounce(() => { this.handleResize(); }, 250)); // 模态框点击外部关闭 const modal = document.getElementById('video-modal'); if (modal) { modal.addEventListener('click', (e) => { if (e.target === modal) { closeVideoModal(); } }); } // ESC键关闭模态框 document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { closeVideoModal(); } }); } initializeVideos() { this.containers.forEach(container => { const video = container.querySelector('.video-background'); if (video) { this.setupVideo(video, container); } }); } setupVideo(video, container) { // 设置视频属性 video.muted = true; video.loop = true; video.playsInline = true; video.autoplay = true; // 监听视频事件 video.addEventListener('loadeddata', () => { this.onVideoLoaded(video, container); }); video.addEventListener('canplay', () => { this.playVideo(video); }); video.addEventListener('error', (e) => { console.error('视频加载失败:', e); this.handleVideoError(video, container); }); // 尝试播放视频 this.playVideo(video); } onVideoLoaded(video, container) { // 视频加载完成后的处理 video.style.opacity = '1'; // 添加淡入动画 if (typeof gsap !== 'undefined') { gsap.fromTo(video, { opacity: 0 }, { opacity: 1, duration: 1, ease: "power2.out" } ); } } playVideo(video) { const playPromise = video.play(); if (playPromise !== undefined) { playPromise.then(() => { // 自动播放成功 }).catch(error => { // 自动播放失败,通常是由于浏览器政策 this.handleAutoplayFailure(video); }); } } handleAutoplayFailure(video) { // 创建播放按钮 const container = video.closest('.video-banner-container'); if (container && !container.querySelector('.video-play-trigger')) { const playButton = document.createElement('div'); playButton.className = 'video-play-trigger'; playButton.innerHTML = `
`; playButton.addEventListener('click', () => { video.play(); playButton.remove(); }); container.appendChild(playButton); } } handleVideoError(video, container) { // 视频加载错误处理 const errorDiv = document.createElement('div'); errorDiv.className = 'video-error-message'; errorDiv.textContent = '视频加载失败'; container.appendChild(errorDiv); } handleResize() { // 处理窗口大小变化 this.containers.forEach(container => { const video = container.querySelector('.video-background'); if (video) { this.adjustVideoSize(video, container); } }); } adjustVideoSize(video, container) { // 调整视频尺寸以适应容器 const containerRect = container.getBoundingClientRect(); const videoRect = video.getBoundingClientRect(); const containerRatio = containerRect.width / containerRect.height; const videoRatio = video.videoWidth / video.videoHeight; if (containerRatio > videoRatio) { video.style.width = '100%'; video.style.height = 'auto'; } else { video.style.width = 'auto'; video.style.height = '100%'; } } setupAnimations() { if (typeof gsap === 'undefined') return; // 等待GSAP兼容性就绪 if (!document.body.classList.contains('gsap-ready')) { document.addEventListener('gsapCompatibilityReady', () => { this.setupAnimations(); }); return; } this.containers.forEach(container => { this.animateContainer(container); }); } animateContainer(container) { const content = container.querySelector('.video-banner-content'); const title = container.querySelector('.video-banner-title'); const subtitle = container.querySelector('.video-banner-subtitle'); const description = container.querySelector('.video-banner-description'); const playButton = container.querySelector('.video-banner-play-button'); // 创建时间线动画 const tl = gsap.timeline({ delay: 0.5 }); if (subtitle) { tl.fromTo(subtitle, { y: 30, opacity: 0 }, { y: 0, opacity: 1, duration: 0.8, ease: "power2.out" } ); } if (title) { tl.fromTo(title, { y: 50, opacity: 0 }, { y: 0, opacity: 1, duration: 1, ease: "power2.out" }, "-=0.6" ); } if (description) { tl.fromTo(description, { y: 30, opacity: 0 }, { y: 0, opacity: 1, duration: 0.8, ease: "power2.out" }, "-=0.4" ); } if (playButton) { tl.fromTo(playButton, { scale: 0, opacity: 0 }, { scale: 1, opacity: 1, duration: 0.6, ease: "back.out(1.7)" }, "-=0.2" ); } } // 工具函数:防抖 debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } } // 初始化 document.addEventListener('DOMContentLoaded', function() { if (!videoBannerInitialized) { new VideoBannerManager(); videoBannerInitialized = true; } }); // 如果页面已经加载完成 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function() { if (!videoBannerInitialized) { new VideoBannerManager(); videoBannerInitialized = true; } }); } else { if (!videoBannerInitialized) { new VideoBannerManager(); videoBannerInitialized = true; } }