|
|
/**
|
|
|
* 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();
|
|
|
}
|
|
|
|
|
|
})(); |