468 lines
15 KiB
JavaScript
468 lines
15 KiB
JavaScript
/**
|
||
* 聊天模式性能优化
|
||
* 在聊天模式下禁用轮播和动画以节省资源
|
||
*/
|
||
|
||
(function() {
|
||
'use strict';
|
||
|
||
let animationsPaused = false;
|
||
let carouselInterval = null;
|
||
let originalAnimations = new Map();
|
||
|
||
/**
|
||
* 暂停所有CSS动画
|
||
*/
|
||
function pauseCSSAnimations() {
|
||
// 获取所有有动画的元素
|
||
const animatedElements = document.querySelectorAll('*');
|
||
|
||
animatedElements.forEach(element => {
|
||
const computedStyle = window.getComputedStyle(element);
|
||
const animationName = computedStyle.animationName;
|
||
const animationDuration = computedStyle.animationDuration;
|
||
|
||
if (animationName && animationName !== 'none') {
|
||
// 保存原始动画设置
|
||
originalAnimations.set(element, {
|
||
animationName: animationName,
|
||
animationDuration: animationDuration,
|
||
animationPlayState: computedStyle.animationPlayState
|
||
});
|
||
|
||
// 暂停动画
|
||
element.style.animationPlayState = 'paused';
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 恢复所有CSS动画
|
||
*/
|
||
function resumeCSSAnimations() {
|
||
originalAnimations.forEach((styles, element) => {
|
||
element.style.animationPlayState = styles.animationPlayState || 'running';
|
||
});
|
||
originalAnimations.clear();
|
||
}
|
||
|
||
/**
|
||
* 停止轮播
|
||
*/
|
||
function stopCarousel() {
|
||
// 停止ticker轮播
|
||
const tickerCarousel = document.getElementById('tickerCarousel');
|
||
if (tickerCarousel) {
|
||
tickerCarousel.style.animationPlayState = 'paused';
|
||
console.log('已暂停ticker轮播');
|
||
}
|
||
|
||
// 停止所有自定义轮播动画
|
||
const carouselElements = document.querySelectorAll('.ticker-carousel, .news-carousel');
|
||
carouselElements.forEach(el => {
|
||
el.style.animationPlayState = 'paused';
|
||
});
|
||
|
||
// 查找并停止所有轮播相关的定时器
|
||
if (window.tickerInterval) {
|
||
clearInterval(window.tickerInterval);
|
||
window.tickerInterval = null;
|
||
}
|
||
|
||
// 停止新闻轮播定时器
|
||
if (window.newsRotationInterval) {
|
||
clearInterval(window.newsRotationInterval);
|
||
window.newsRotationInterval = null;
|
||
console.log('已停止新闻轮播定时器');
|
||
}
|
||
|
||
// 保存所有活动的定时器ID以便恢复
|
||
window.pausedIntervals = [];
|
||
|
||
// 暴力停止所有定时器(作为后备方案)
|
||
const highestId = window.setTimeout(function() {
|
||
for (let i = highestId; i >= 0; i--) {
|
||
window.clearInterval(i);
|
||
}
|
||
}, 0);
|
||
|
||
// 停止Bootstrap轮播
|
||
const carousels = document.querySelectorAll('.carousel');
|
||
carousels.forEach(carousel => {
|
||
if (typeof $ !== 'undefined' && $(carousel).carousel) {
|
||
$(carousel).carousel('pause');
|
||
}
|
||
});
|
||
|
||
// 停止Swiper轮播
|
||
if (window.Swiper) {
|
||
const swipers = document.querySelectorAll('.swiper-container');
|
||
swipers.forEach(swiperEl => {
|
||
if (swiperEl.swiper) {
|
||
swiperEl.swiper.autoplay.stop();
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 恢复轮播
|
||
*/
|
||
function startCarousel() {
|
||
// 恢复Bootstrap轮播
|
||
const carousels = document.querySelectorAll('.carousel');
|
||
carousels.forEach(carousel => {
|
||
if ($(carousel).carousel) {
|
||
$(carousel).carousel('cycle');
|
||
}
|
||
});
|
||
|
||
// 恢复Swiper轮播
|
||
if (window.Swiper) {
|
||
const swipers = document.querySelectorAll('.swiper-container');
|
||
swipers.forEach(swiperEl => {
|
||
if (swiperEl.swiper) {
|
||
swiperEl.swiper.autoplay.start();
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 禁用背景视频
|
||
*/
|
||
function pauseBackgroundVideos() {
|
||
const videos = document.querySelectorAll('video');
|
||
videos.forEach(video => {
|
||
if (!video.paused) {
|
||
video.pause();
|
||
video.dataset.wasPaused = 'false';
|
||
} else {
|
||
video.dataset.wasPaused = 'true';
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 恢复背景视频
|
||
*/
|
||
function resumeBackgroundVideos() {
|
||
const videos = document.querySelectorAll('video');
|
||
videos.forEach(video => {
|
||
if (video.dataset.wasPaused === 'false') {
|
||
video.play();
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 进入聊天模式时的优化
|
||
*/
|
||
function optimizeForChatMode() {
|
||
if (animationsPaused) return;
|
||
|
||
console.log('进入聊天模式,暂停动画和轮播');
|
||
|
||
// 添加聊天模式激活类
|
||
document.body.classList.add('chat-mode-active');
|
||
|
||
// 冻结背景渐变但保持可见
|
||
const animatedGradient = document.querySelector('.animated-gradient');
|
||
if (animatedGradient) {
|
||
// 获取当前背景并冻结
|
||
const currentStyle = window.getComputedStyle(animatedGradient);
|
||
const currentBackground = currentStyle.backgroundImage || currentStyle.background;
|
||
|
||
// 保存原始样式
|
||
animatedGradient.dataset.originalBackground = animatedGradient.style.background;
|
||
animatedGradient.dataset.originalTransition = animatedGradient.style.transition;
|
||
|
||
// 设置固定背景
|
||
animatedGradient.style.background = currentBackground;
|
||
animatedGradient.style.transition = 'none';
|
||
|
||
// 停止requestAnimationFrame动画
|
||
// 设置标志位阻止动画继续
|
||
window.pauseBackgroundAnimation = true;
|
||
|
||
console.log('已冻结背景渐变动画,保持当前颜色');
|
||
}
|
||
|
||
// 暂停CSS动画但不包括背景和功能性元素
|
||
const animatedElements = document.querySelectorAll('[style*="animation"]');
|
||
animatedElements.forEach(el => {
|
||
// 不处理背景渐变、加载动画和工具按钮
|
||
if (!el.classList.contains('animated-gradient') &&
|
||
!el.classList.contains('loading-spinner') &&
|
||
el.id !== 'chatModeLoadingSpinner' &&
|
||
el.id !== 'loadingSpinner' &&
|
||
!el.closest('#toolsMenuBtn')) {
|
||
el.style.animationPlayState = 'paused';
|
||
}
|
||
});
|
||
|
||
// 停止轮播
|
||
stopCarousel();
|
||
|
||
// 暂停背景视频
|
||
pauseBackgroundVideos();
|
||
|
||
// 只隐藏3D动画元素
|
||
const tickerElements = document.querySelectorAll(
|
||
'.ticker-pulse-ring, .ticker-carousel, .news-carousel, .ticker-flip-card'
|
||
);
|
||
tickerElements.forEach(el => {
|
||
el.style.display = 'none';
|
||
});
|
||
|
||
// 隐藏整个ticker区域
|
||
const tickerSection = document.querySelector('.ticker-section');
|
||
if (tickerSection) {
|
||
tickerSection.style.display = 'none';
|
||
console.log('已隐藏3D ticker区域');
|
||
}
|
||
|
||
animationsPaused = true;
|
||
}
|
||
|
||
/**
|
||
* 退出聊天模式时恢复
|
||
*/
|
||
function restoreFromChatMode() {
|
||
if (!animationsPaused) return;
|
||
|
||
console.log('退出聊天模式,恢复动画和轮播');
|
||
|
||
// 移除聊天模式激活类
|
||
document.body.classList.remove('chat-mode-active');
|
||
|
||
// 恢复背景渐变动画
|
||
const animatedGradient = document.querySelector('.animated-gradient');
|
||
if (animatedGradient) {
|
||
// 恢复原始样式
|
||
animatedGradient.style.background = animatedGradient.dataset.originalBackground || '';
|
||
animatedGradient.style.transition = animatedGradient.dataset.originalTransition || '';
|
||
delete animatedGradient.dataset.originalBackground;
|
||
delete animatedGradient.dataset.originalTransition;
|
||
|
||
// 恢复背景动画
|
||
window.pauseBackgroundAnimation = false;
|
||
|
||
// 重新启动背景动画(如果有initBackground函数)
|
||
if (window.initBackground && typeof window.initBackground === 'function') {
|
||
window.initBackground();
|
||
}
|
||
|
||
console.log('已恢复背景渐变动画');
|
||
}
|
||
|
||
// 恢复CSS动画
|
||
const animatedElements = document.querySelectorAll('[style*="animation"]');
|
||
animatedElements.forEach(el => {
|
||
if (el.id !== 'chatModeLoadingSpinner' && el.id !== 'loadingSpinner') {
|
||
el.style.animationPlayState = '';
|
||
}
|
||
});
|
||
|
||
// 恢复轮播
|
||
startCarousel();
|
||
|
||
// 恢复背景视频
|
||
resumeBackgroundVideos();
|
||
|
||
// 恢复3D动画元素
|
||
const tickerElements = document.querySelectorAll(
|
||
'.ticker-pulse-ring, .ticker-carousel, .news-carousel, .ticker-flip-card'
|
||
);
|
||
tickerElements.forEach(el => {
|
||
el.style.display = '';
|
||
});
|
||
|
||
// 恢复ticker区域
|
||
const tickerSection = document.querySelector('.ticker-section');
|
||
if (tickerSection) {
|
||
tickerSection.style.display = '';
|
||
console.log('已恢复3D ticker区域');
|
||
}
|
||
|
||
// 重新启动新闻轮播
|
||
if (window.initTicker3D && typeof window.initTicker3D === 'function') {
|
||
window.initTicker3D();
|
||
}
|
||
|
||
animationsPaused = false;
|
||
}
|
||
|
||
/**
|
||
* 检测聊天模式状态
|
||
*/
|
||
function checkChatModeStatus() {
|
||
const chatContainer = document.getElementById('chatContainer');
|
||
const welcomeScreen = document.getElementById('welcomeScreen');
|
||
|
||
// 判断是否在聊天模式
|
||
const isInChatMode = chatContainer && chatContainer.style.display !== 'none' &&
|
||
(!welcomeScreen || welcomeScreen.style.display === 'none');
|
||
|
||
if (isInChatMode) {
|
||
optimizeForChatMode();
|
||
} else {
|
||
restoreFromChatMode();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 监听模式切换
|
||
*/
|
||
function setupModeObserver() {
|
||
// 监听聊天容器的显示状态变化
|
||
const chatContainer = document.getElementById('chatContainer');
|
||
const welcomeScreen = document.getElementById('welcomeScreen');
|
||
|
||
if (!chatContainer) {
|
||
setTimeout(setupModeObserver, 500);
|
||
return;
|
||
}
|
||
|
||
// 创建MutationObserver监听display变化
|
||
const observer = new MutationObserver((mutations) => {
|
||
mutations.forEach((mutation) => {
|
||
if (mutation.type === 'attributes' &&
|
||
(mutation.attributeName === 'style' || mutation.attributeName === 'class')) {
|
||
checkChatModeStatus();
|
||
}
|
||
});
|
||
});
|
||
|
||
// 开始观察
|
||
if (chatContainer) {
|
||
observer.observe(chatContainer, {
|
||
attributes: true,
|
||
attributeFilter: ['style', 'class']
|
||
});
|
||
}
|
||
|
||
if (welcomeScreen) {
|
||
observer.observe(welcomeScreen, {
|
||
attributes: true,
|
||
attributeFilter: ['style', 'class']
|
||
});
|
||
}
|
||
|
||
// 初始检查
|
||
checkChatModeStatus();
|
||
}
|
||
|
||
/**
|
||
* 添加全局样式优化
|
||
*/
|
||
function addOptimizationStyles() {
|
||
const style = document.createElement('style');
|
||
style.id = 'chat-mode-optimization';
|
||
style.textContent = `
|
||
/* 保持背景但停止过渡动画 */
|
||
.chat-mode-active .animated-gradient {
|
||
transition: none !important;
|
||
}
|
||
|
||
/* 隐藏3D ticker区域 */
|
||
.chat-mode-active .ticker-section {
|
||
display: none !important;
|
||
}
|
||
|
||
/* 隐藏脉冲环动画 */
|
||
.chat-mode-active .ticker-pulse-ring {
|
||
display: none !important;
|
||
}
|
||
|
||
/* 隐藏3D卡片和轮播 */
|
||
.chat-mode-active .ticker-carousel,
|
||
.chat-mode-active .ticker-flip-card,
|
||
.chat-mode-active .news-carousel {
|
||
display: none !important;
|
||
}
|
||
|
||
/* 聊天模式下隐藏轮播控制器 */
|
||
.chat-mode-active .carousel-control-prev,
|
||
.chat-mode-active .carousel-control-next,
|
||
.chat-mode-active .carousel-indicators {
|
||
display: none !important;
|
||
}
|
||
|
||
/* 确保spin动画关键帧存在 */
|
||
@keyframes spin {
|
||
0% { transform: rotate(0deg); }
|
||
100% { transform: rotate(360deg); }
|
||
}
|
||
|
||
/* 保持加载动画正常运行 */
|
||
.chat-mode-active .loading-spinner,
|
||
.chat-mode-active #loadingSpinner,
|
||
.chat-mode-active #chatModeLoadingSpinner {
|
||
animation: spin 1s linear infinite !important;
|
||
animation-play-state: running !important;
|
||
}
|
||
|
||
/* 只停止装饰性动画,不影响功能性动画 */
|
||
.chat-mode-active .ticker-pulse-ring,
|
||
.chat-mode-active .wave-animation {
|
||
animation-play-state: paused !important;
|
||
}
|
||
|
||
/* 减少GPU使用 */
|
||
.chat-mode-active .ticker-3d,
|
||
.chat-mode-active .particles-js,
|
||
.chat-mode-active .wave-animation {
|
||
transform: none !important;
|
||
will-change: auto !important;
|
||
}
|
||
`;
|
||
document.head.appendChild(style);
|
||
}
|
||
|
||
/**
|
||
* 初始化
|
||
*/
|
||
function init() {
|
||
// 添加优化样式
|
||
addOptimizationStyles();
|
||
|
||
// DOM加载完成后设置监听
|
||
if (document.readyState === 'loading') {
|
||
document.addEventListener('DOMContentLoaded', setupModeObserver);
|
||
} else {
|
||
setupModeObserver();
|
||
}
|
||
|
||
// 监听页面可见性变化
|
||
document.addEventListener('visibilitychange', () => {
|
||
if (document.hidden) {
|
||
// 页面不可见时暂停所有动画
|
||
optimizeForChatMode();
|
||
} else {
|
||
// 页面可见时根据模式恢复
|
||
checkChatModeStatus();
|
||
}
|
||
});
|
||
|
||
// 为body添加聊天模式类
|
||
const originalSendMessage = window.sendMessage;
|
||
if (originalSendMessage) {
|
||
window.sendMessage = function() {
|
||
document.body.classList.add('chat-mode-active');
|
||
return originalSendMessage.apply(this, arguments);
|
||
};
|
||
}
|
||
}
|
||
|
||
// 启动
|
||
init();
|
||
|
||
// 导出API供外部调用
|
||
window.chatModeOptimizer = {
|
||
pause: optimizeForChatMode,
|
||
resume: restoreFromChatMode,
|
||
check: checkChatModeStatus
|
||
};
|
||
|
||
})(); |