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.
103 lines
3.5 KiB
103 lines
3.5 KiB
// 关于页面特色区块数字计数动画
|
|
(function() {
|
|
'use strict';
|
|
|
|
// 数字计数动画函数
|
|
function animateNumber(element, targetNumber, duration = 2000) {
|
|
const startNumber = 0;
|
|
const increment = targetNumber / (duration / 16); // 60fps
|
|
let currentNumber = startNumber;
|
|
|
|
const timer = setInterval(() => {
|
|
currentNumber += increment;
|
|
|
|
if (currentNumber >= targetNumber) {
|
|
currentNumber = targetNumber;
|
|
clearInterval(timer);
|
|
}
|
|
|
|
// 格式化数字显示
|
|
let displayNumber = Math.floor(currentNumber);
|
|
let displayText = '';
|
|
|
|
if (element.textContent.includes('+')) {
|
|
displayText = displayNumber + '+项';
|
|
} else if (element.textContent.includes('项')) {
|
|
displayText = displayNumber + '项';
|
|
} else {
|
|
displayText = displayNumber.toString();
|
|
}
|
|
|
|
element.textContent = displayText;
|
|
}, 16);
|
|
}
|
|
|
|
// 提取数字的函数
|
|
function extractNumber(text) {
|
|
const match = text.match(/\d+/);
|
|
return match ? parseInt(match[0]) : 0;
|
|
}
|
|
|
|
// 检查元素是否在视窗中
|
|
function isElementInViewport(el) {
|
|
const rect = el.getBoundingClientRect();
|
|
return (
|
|
rect.top >= 0 &&
|
|
rect.left >= 0 &&
|
|
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
|
|
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
|
|
);
|
|
}
|
|
|
|
// 初始化计数动画
|
|
function initCountAnimation() {
|
|
const statNumbers = document.querySelectorAll('.about-stat-number');
|
|
let animated = false;
|
|
|
|
function checkAndAnimate() {
|
|
if (animated) return;
|
|
|
|
const featuresSection = document.querySelector('.about-features-section');
|
|
if (!featuresSection) return;
|
|
|
|
const rect = featuresSection.getBoundingClientRect();
|
|
const isVisible = rect.top < window.innerHeight && rect.bottom > 0;
|
|
|
|
if (isVisible) {
|
|
animated = true;
|
|
|
|
statNumbers.forEach((element, index) => {
|
|
const originalText = element.textContent;
|
|
const targetNumber = extractNumber(originalText);
|
|
|
|
// 添加动画类
|
|
element.classList.add('animate');
|
|
|
|
// 延迟启动动画
|
|
setTimeout(() => {
|
|
animateNumber(element, targetNumber, 2000);
|
|
}, index * 200);
|
|
});
|
|
|
|
// 移除滚动监听器
|
|
window.removeEventListener('scroll', checkAndAnimate);
|
|
window.removeEventListener('resize', checkAndAnimate);
|
|
}
|
|
}
|
|
|
|
// 监听滚动和窗口大小变化
|
|
window.addEventListener('scroll', checkAndAnimate);
|
|
window.addEventListener('resize', checkAndAnimate);
|
|
|
|
// 初始检查
|
|
checkAndAnimate();
|
|
}
|
|
|
|
// DOM加载完成后初始化
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', initCountAnimation);
|
|
} else {
|
|
initCountAnimation();
|
|
}
|
|
|
|
})(); |