123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- // 数字滚动效果 - 使用 Intersection Observer
- console.log('Number counter script loaded');
- // 数字计数器类
- class NumberCounter {
- constructor(element) {
- this.element = element;
- this.target = this.parseTargetNumber();
- this.isAnimating = false;
- this.hasAnimated = false;
-
- console.log('NumberCounter created for:', this.element.className, 'Target:', this.target);
- }
- parseTargetNumber() {
- const originalText = this.element.textContent.trim();
- console.log('Parsing target number from:', originalText);
-
- // 移除逗号并解析数字
- const number = parseInt(originalText.replace(/,/g, ''));
-
- if (isNaN(number)) {
- console.error('Invalid number:', originalText);
- return 0;
- }
-
- console.log('Parsed number:', number);
- return number;
- }
- animate(duration = 2000) {
- if (this.isAnimating || this.hasAnimated) {
- console.log('Animation already running or completed for:', this.element.className);
- return;
- }
- console.log('Starting animation for:', this.element.className, 'Target:', this.target);
-
- this.isAnimating = true;
- const start = 0;
- const startTime = performance.now();
- const update = (currentTime) => {
- const elapsed = currentTime - startTime;
- const progress = Math.min(elapsed / duration, 1);
- // 缓动函数 - easeOutQuart
- const easeOutQuart = 1 - Math.pow(1 - progress, 4);
- const current = Math.floor(start + (this.target - start) * easeOutQuart);
- // 格式化数字(添加千位分隔符)
- // const formatted = current.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
- // this.element.textContent = formatted;
- this.element.textContent = current;
- if (progress < 1) {
- requestAnimationFrame(update);
- } else {
- // 确保最终显示正确的目标值
- // const finalFormatted = this.target.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
- // this.element.textContent = finalFormatted;
- this.element.textContent = this.target;
-
- // 添加动画完成类
- this.element.classList.add('animated');
-
- this.isAnimating = false;
- this.hasAnimated = true;
-
- console.log('Animation completed for:', this.element.className, 'Final value:', finalFormatted);
- }
- };
- requestAnimationFrame(update);
- }
- }
- // 等待页面加载完成
- window.addEventListener('load', function() {
- console.log('Window load event fired');
-
- // 查找数字元素
- const numberElements = document.querySelectorAll('.number-1, .number-2, .number-3');
- console.log('Found number elements:', numberElements.length);
- if (numberElements.length === 0) {
- console.error('No number elements found!');
- return;
- }
- // 显示原始内容
- numberElements.forEach((element, index) => {
- console.log(`Element ${index + 1} (${element.className}) original content:`, element.textContent);
- });
- // 创建数字计数器实例
- const counters = Array.from(numberElements).map(element => new NumberCounter(element));
- // 创建 Intersection Observer
- const observer = new IntersectionObserver((entries) => {
- entries.forEach(entry => {
- if (entry.isIntersecting) {
- console.log('Element entered viewport:', entry.target.className);
-
- // 找到对应的计数器并开始动画
- const counter = counters.find(c => c.element === entry.target);
- if (counter) {
- counter.animate(2000);
- }
-
- // 一旦动画开始,就不再观察这个元素
- observer.unobserve(entry.target);
- }
- });
- }, {
- threshold: 0.5, // 当元素50%可见时触发
- rootMargin: '0px 0px -50px 0px' // 稍微提前触发
- });
- // 开始观察所有数字元素
- numberElements.forEach(element => {
- observer.observe(element);
- console.log('Started observing element:', element.className);
- });
- });
- // 添加全局函数用于手动测试
- window.testNumberAnimation = function() {
- console.log('Manual test triggered');
- const elements = document.querySelectorAll('.number-1, .number-2, .number-3');
- elements.forEach((el, i) => {
- console.log(`Element ${i + 1}:`, el.textContent);
- });
- };
|