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.

185 lines
5.5 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.

/**
* Features Block Animation
* 特性展示区块动画效果
*/
// 等待GSAP准备就绪事件
function waitForGSAPReady(callback) {
if (window.gsap && window.ScrollTrigger) {
callback();
} else {
document.addEventListener('gsapReady', callback);
// 备用方案:如果事件未触发,使用定时器
setTimeout(() => {
if (window.gsap && window.ScrollTrigger) {
callback();
}
}, 3000);
}
}
// 初始化特性区块动画
function initFeaturesAnimation() {
// 等待GSAP兼容性就绪
if (!document.body.classList.contains('gsap-ready')) {
document.addEventListener('gsapCompatibilityReady', initFeaturesAnimation);
return;
}
// 标题动画
const header = document.querySelector('.features-header');
if (header) {
// 检查是否在Elementor元素内
if (!header.closest('.elementor-element') || header.hasAttribute('data-gsap-ready')) {
createHeaderAnimation(header);
} else {
header.addEventListener('gsapElementReady', () => {
createHeaderAnimation(header);
});
}
}
// 统计数据项目动画
const statItems = document.querySelectorAll('.features-stat-item');
if (statItems.length > 0) {
statItems.forEach((item, index) => {
// 检查元素是否被Elementor暂停
if (item.hasAttribute('data-gsap-paused')) {
return;
}
// 监听元素准备就绪事件
item.addEventListener('gsapElementReady', () => {
createStatItemAnimation(item, index);
});
// 如果元素已经准备就绪,直接创建动画
if (item.hasAttribute('data-gsap-ready') || !item.closest('.elementor-element')) {
createStatItemAnimation(item, index);
}
});
}
// 数字计数动画
const statNumbers = document.querySelectorAll('.stat-number');
if (statNumbers.length > 0) {
statNumbers.forEach((numberElement, index) => {
// 检查元素是否被Elementor暂停
if (numberElement.hasAttribute('data-gsap-paused')) {
return;
}
// 监听元素准备就绪事件
numberElement.addEventListener('gsapElementReady', () => {
createNumberAnimation(numberElement, index);
});
// 如果元素已经准备就绪,直接创建动画
if (numberElement.hasAttribute('data-gsap-ready') || !numberElement.closest('.elementor-element')) {
createNumberAnimation(numberElement, index);
}
});
}
}
// 创建标题动画
function createHeaderAnimation(header) {
gsap.fromTo(header,
{
opacity: 0,
y: 30
},
{
opacity: 1,
y: 0,
duration: 1,
ease: "power2.out",
scrollTrigger: {
trigger: header,
start: "top 85%",
end: "bottom 20%",
toggleActions: "play none none reverse"
}
}
);
}
// 创建统计项目动画
function createStatItemAnimation(item, index) {
gsap.fromTo(item,
{
opacity: 0,
y: 50
},
{
opacity: 1,
y: 0,
duration: 0.8,
ease: "power2.out",
delay: index * 0.15, // 逐个显示每个延迟0.15秒
scrollTrigger: {
trigger: item,
start: "top 80%",
end: "bottom 20%",
toggleActions: "play none none reverse"
}
}
);
}
// 创建数字计数动画
function createNumberAnimation(numberElement, index) {
const text = numberElement.textContent;
const hasPlus = text.includes('+');
const number = parseInt(text.replace(/[^0-9]/g, ''));
if (!isNaN(number)) {
// 设置初始值为0
numberElement.textContent = hasPlus ? '0+项' : '0项';
// 创建计数动画
gsap.to({value: 0}, {
value: number,
duration: 2,
ease: "power2.out",
delay: index * 0.15 + 0.5, // 在元素显示后开始计数
onUpdate: function() {
const currentValue = Math.round(this.targets()[0].value);
if (hasPlus) {
numberElement.textContent = currentValue + '+项';
} else {
numberElement.textContent = currentValue + '项';
}
},
scrollTrigger: {
trigger: numberElement,
start: "top 80%",
toggleActions: "play none none none"
}
});
}
}
// 等待GSAP准备就绪后初始化
waitForGSAPReady(() => {
// 注册 ScrollTrigger 插件
gsap.registerPlugin(ScrollTrigger);
// DOM 加载完成后初始化动画
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initFeaturesAnimation);
} else {
initFeaturesAnimation();
}
// 如果是动态加载的内容,提供重新初始化的函数
window.reinitFeaturesAnimation = function() {
// 刷新 ScrollTrigger
ScrollTrigger.refresh();
initFeaturesAnimation();
};
});
// 如果GSAP未加载显示警告
if (typeof gsap === 'undefined') {
}