You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

276 lines
9.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* Solution Block JavaScript
* 解决方案区块交互效果
*/
(function() {
'use strict';
// 移除no-js类添加js-loaded类表示JavaScript已加载
document.documentElement.classList.remove('no-js');
document.body.classList.remove('no-js');
document.body.classList.add('js-loaded');
// 确保 GSAP 和 ScrollTrigger 已加载
if (typeof gsap === 'undefined' || typeof ScrollTrigger === 'undefined') {
console.warn('GSAP or ScrollTrigger not loaded');
return;
}
// 注册 ScrollTrigger 插件
gsap.registerPlugin(ScrollTrigger);
// 初始化解决方案区块动画
function initSolutionAnimations() {
const solutionBlocks = document.querySelectorAll('.solution-block');
solutionBlocks.forEach(block => {
const header = block.querySelector('.solution-header');
const panels = block.querySelector('.solution-panels');
const panelItems = block.querySelectorAll('.solution-panel');
if (!header || !panels || !panelItems.length) return;
// 创建时间线
const tl = gsap.timeline({
scrollTrigger: {
trigger: block,
start: 'top 80%',
end: 'bottom 20%',
toggleActions: 'play none none reverse'
}
});
// 标题动画
tl.to(header, {
opacity: 1,
y: 0,
duration: 0.8,
ease: 'power2.out'
})
// 面板容器动画
.to(panels, {
opacity: 1,
y: 0,
duration: 0.8,
ease: 'power2.out'
}, '-=0.4')
// 面板项目动画
.fromTo(panelItems, {
scale: 0.9,
opacity: 0
}, {
scale: 1,
opacity: 1,
duration: 0.6,
stagger: 0.1,
ease: 'power2.out'
}, '-=0.6');
});
}
// 初始化面板状态
function initPanelStates() {
const panels = document.querySelectorAll('.solution-panel');
panels.forEach(panel => {
const panelText = panel.querySelector('.panel-text');
const panelDescription = panel.querySelector('.panel-description');
if (panelText) {
gsap.set(panelText, { y: 20 });
}
if (panelDescription) {
gsap.set(panelDescription, { opacity: 0, y: 20 });
}
});
}
// 增强手风琴效果(仅桌面端)
function initAccordionEffect() {
// 只在桌面端启用悬停效果
if (window.innerWidth <= 768) return;
const solutionPanels = document.querySelectorAll('.solution-panels');
solutionPanels.forEach(panelsContainer => {
const panels = panelsContainer.querySelectorAll('.solution-panel');
panels.forEach(panel => {
const panelText = panel.querySelector('.panel-text');
const panelDescription = panel.querySelector('.panel-description');
// 鼠标进入事件
panel.addEventListener('mouseenter', () => {
// 使用 GSAP 实现平滑的宽度变化
gsap.to(panel, {
flex: 2,
duration: 0.6,
ease: 'power2.out'
});
// 其他面板缩小
panels.forEach(otherPanel => {
if (otherPanel !== panel) {
gsap.to(otherPanel, {
flex: 0.5,
duration: 0.6,
ease: 'power2.out'
});
}
});
// 文本动画
if (panelText) {
gsap.to(panelText, {
y: 0,
duration: 0.6,
ease: 'power2.out'
});
}
if (panelDescription) {
gsap.to(panelDescription, {
opacity: 1,
y: 0,
duration: 0.6,
delay: 0.2,
ease: 'power2.out'
});
}
});
});
// 鼠标离开事件
panelsContainer.addEventListener('mouseleave', () => {
// 重置所有面板
panels.forEach(resetPanel => {
gsap.to(resetPanel, {
flex: 1,
duration: 0.6,
ease: 'power2.out'
});
const resetText = resetPanel.querySelector('.panel-text');
const resetDescription = resetPanel.querySelector('.panel-description');
if (resetText) {
gsap.to(resetText, {
y: 20,
duration: 0.6,
ease: 'power2.out'
});
}
if (resetDescription) {
gsap.to(resetDescription, {
opacity: 0,
y: 20,
duration: 0.4,
ease: 'power2.out'
});
}
});
});
});
}
// 移动端优化
function initMobileOptimization() {
const isMobile = window.innerWidth <= 768;
if (isMobile) {
// 移动端禁用悬停效果,改为点击效果
const panels = document.querySelectorAll('.solution-panel');
panels.forEach(panel => {
// 移除所有悬停事件监听器
panel.style.pointerEvents = 'auto';
panel.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
const description = panel.querySelector('.panel-description');
if (!description) return;
const isExpanded = gsap.getProperty(description, 'opacity') > 0.5;
// 重置所有面板
panels.forEach(p => {
const desc = p.querySelector('.panel-description');
if (desc) {
gsap.to(desc, {
opacity: 0,
y: 20,
duration: 0.3,
ease: 'power2.out'
});
}
});
// 如果当前面板未展开,则展开它
if (!isExpanded) {
gsap.to(description, {
opacity: 1,
y: 0,
duration: 0.3,
delay: 0.1,
ease: 'power2.out'
});
}
});
});
}
}
// 清理事件监听器
function cleanupEventListeners() {
const panels = document.querySelectorAll('.solution-panel');
const panelsContainers = document.querySelectorAll('.solution-panels');
// 移除面板事件
panels.forEach(panel => {
const newPanel = panel.cloneNode(true);
panel.parentNode.replaceChild(newPanel, panel);
});
// 移除容器事件
panelsContainers.forEach(container => {
const newContainer = container.cloneNode(true);
container.parentNode.replaceChild(newContainer, container);
});
}
// 窗口大小改变时重新初始化
function handleResize() {
// 防抖处理
clearTimeout(window.solutionResizeTimeout);
window.solutionResizeTimeout = setTimeout(() => {
cleanupEventListeners();
initPanelStates();
initAccordionEffect();
initMobileOptimization();
}, 250);
}
// DOM 加载完成后初始化
function init() {
initPanelStates();
initSolutionAnimations();
initAccordionEffect();
initMobileOptimization();
// 监听窗口大小变化
window.addEventListener('resize', handleResize);
}
// 确保 DOM 加载完成
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();