362 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			362 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// 主页增强功能 - 无彩蛋版本
 | 
						||
document.addEventListener('DOMContentLoaded', function() {
 | 
						||
    
 | 
						||
    // 页面加载动画
 | 
						||
    document.body.classList.add('page-loading');
 | 
						||
    setTimeout(() => {
 | 
						||
        document.body.classList.remove('page-loading');
 | 
						||
    }, 100);
 | 
						||
    
 | 
						||
    // 数字统计动画
 | 
						||
    animateCounters();
 | 
						||
    
 | 
						||
    // 场景分类筛选
 | 
						||
    initScenarioFilter();
 | 
						||
    
 | 
						||
    // 滚动动画
 | 
						||
    initScrollAnimations();
 | 
						||
    
 | 
						||
    // 轮播图增强
 | 
						||
    enhanceCarousel();
 | 
						||
    
 | 
						||
    // 功能卡片交互
 | 
						||
    enhanceFeatureCards();
 | 
						||
    
 | 
						||
    console.log('🎨 主页功能已加载完成!');
 | 
						||
});
 | 
						||
 | 
						||
// 数字统计动画
 | 
						||
function animateCounters() {
 | 
						||
    const counters = document.querySelectorAll('.stat-number');
 | 
						||
    
 | 
						||
    const observer = new IntersectionObserver((entries) => {
 | 
						||
        entries.forEach(entry => {
 | 
						||
            if (entry.isIntersecting) {
 | 
						||
                const counter = entry.target;
 | 
						||
                const target = parseInt(counter.getAttribute('data-count'));
 | 
						||
                animateCounter(counter, target);
 | 
						||
                observer.unobserve(counter);
 | 
						||
            }
 | 
						||
        });
 | 
						||
    });
 | 
						||
    
 | 
						||
    counters.forEach(counter => observer.observe(counter));
 | 
						||
}
 | 
						||
 | 
						||
function animateCounter(element, target) {
 | 
						||
    let count = 0;
 | 
						||
    const duration = 2000; // 2秒
 | 
						||
    const step = target / (duration / 16); // 60fps
 | 
						||
    
 | 
						||
    const timer = setInterval(() => {
 | 
						||
        count += step;
 | 
						||
        if (count >= target) {
 | 
						||
            count = target;
 | 
						||
            clearInterval(timer);
 | 
						||
        }
 | 
						||
        element.textContent = Math.floor(count);
 | 
						||
    }, 16);
 | 
						||
}
 | 
						||
 | 
						||
// 场景分类筛选
 | 
						||
function initScenarioFilter() {
 | 
						||
    const navButtons = document.querySelectorAll('.scenario-nav-btn');
 | 
						||
    const scenarioCards = document.querySelectorAll('.scenario-card-new');
 | 
						||
    
 | 
						||
    navButtons.forEach(btn => {
 | 
						||
        btn.addEventListener('click', function() {
 | 
						||
            // 更新激活状态
 | 
						||
            navButtons.forEach(b => b.classList.remove('active'));
 | 
						||
            this.classList.add('active');
 | 
						||
            
 | 
						||
            // 筛选场景
 | 
						||
            const category = this.getAttribute('data-category');
 | 
						||
            
 | 
						||
            scenarioCards.forEach(card => {
 | 
						||
                if (category === 'all' || card.getAttribute('data-category') === category) {
 | 
						||
                    card.style.display = 'block';
 | 
						||
                    card.style.animation = 'fadeInUp 0.5s ease forwards';
 | 
						||
                } else {
 | 
						||
                    card.style.display = 'none';
 | 
						||
                }
 | 
						||
            });
 | 
						||
        });
 | 
						||
    });
 | 
						||
}
 | 
						||
 | 
						||
// 滚动动画
 | 
						||
function initScrollAnimations() {
 | 
						||
    const observerOptions = {
 | 
						||
        threshold: 0.1,
 | 
						||
        rootMargin: '0px 0px -50px 0px'
 | 
						||
    };
 | 
						||
    
 | 
						||
    const observer = new IntersectionObserver((entries) => {
 | 
						||
        entries.forEach(entry => {
 | 
						||
            if (entry.isIntersecting) {
 | 
						||
                entry.target.classList.add('animate-in');
 | 
						||
                
 | 
						||
                // 为子元素添加延迟动画
 | 
						||
                const children = entry.target.querySelectorAll('.stat-card, .feature-card-advanced, .step-item');
 | 
						||
                children.forEach((child, index) => {
 | 
						||
                    setTimeout(() => {
 | 
						||
                        child.classList.add('fade-in');
 | 
						||
                    }, index * 100);
 | 
						||
                });
 | 
						||
            }
 | 
						||
        });
 | 
						||
    }, observerOptions);
 | 
						||
    
 | 
						||
    // 观察需要动画的元素
 | 
						||
    document.querySelectorAll('.stats-showcase, .learning-steps, .scenarios-grid').forEach(el => {
 | 
						||
        observer.observe(el);
 | 
						||
    });
 | 
						||
}
 | 
						||
 | 
						||
// 轮播图增强
 | 
						||
function enhanceCarousel() {
 | 
						||
    const carousel = document.querySelector('#heroCarousel');
 | 
						||
    if (!carousel) return;
 | 
						||
    
 | 
						||
    // 增强指示器点击效果
 | 
						||
    document.querySelectorAll('.carousel-indicators button').forEach(indicator => {
 | 
						||
        indicator.addEventListener('click', function() {
 | 
						||
            this.style.transform = 'scale(1.5)';
 | 
						||
            setTimeout(() => {
 | 
						||
                this.style.transform = '';
 | 
						||
            }, 200);
 | 
						||
        });
 | 
						||
    });
 | 
						||
    
 | 
						||
    // 控制器悬停效果
 | 
						||
    document.querySelectorAll('.kid-control').forEach(control => {
 | 
						||
        control.addEventListener('mouseenter', function() {
 | 
						||
            this.style.transform = 'scale(1.1)';
 | 
						||
        });
 | 
						||
        
 | 
						||
        control.addEventListener('mouseleave', function() {
 | 
						||
            this.style.transform = 'scale(1)';
 | 
						||
        });
 | 
						||
    });
 | 
						||
}
 | 
						||
 | 
						||
// 功能卡片交互增强
 | 
						||
function enhanceFeatureCards() {
 | 
						||
    // 语音波浪动画控制
 | 
						||
    const waveDemo = document.querySelector('.voice-wave-demo');
 | 
						||
    if (waveDemo) {
 | 
						||
        const waveCard = waveDemo.closest('.feature-card-advanced');
 | 
						||
        
 | 
						||
        waveCard.addEventListener('mouseenter', function() {
 | 
						||
            const bars = waveDemo.querySelectorAll('.wave-bar');
 | 
						||
            bars.forEach((bar, index) => {
 | 
						||
                bar.style.animationDuration = '0.8s';
 | 
						||
                bar.style.animationDelay = (index * 0.1) + 's';
 | 
						||
            });
 | 
						||
        });
 | 
						||
        
 | 
						||
        waveCard.addEventListener('mouseleave', function() {
 | 
						||
            const bars = waveDemo.querySelectorAll('.wave-bar');
 | 
						||
            bars.forEach((bar, index) => {
 | 
						||
                bar.style.animationDuration = '1.5s';
 | 
						||
                bar.style.animationDelay = (index * 0.2) + 's';
 | 
						||
            });
 | 
						||
        });
 | 
						||
    }
 | 
						||
    
 | 
						||
    // 聊天演示动画
 | 
						||
    const chatDemo = document.querySelector('.chat-demo');
 | 
						||
    if (chatDemo) {
 | 
						||
        const aiCard = chatDemo.closest('.feature-card-advanced');
 | 
						||
        
 | 
						||
        aiCard.addEventListener('mouseenter', function() {
 | 
						||
            const typingIndicator = chatDemo.querySelector('.typing-indicator');
 | 
						||
            if (typingIndicator) {
 | 
						||
                typingIndicator.style.animationDuration = '1s';
 | 
						||
            }
 | 
						||
        });
 | 
						||
    }
 | 
						||
}
 | 
						||
 | 
						||
// 场景预览功能
 | 
						||
window.showPreview = function(scenarioType) {
 | 
						||
    const modal = document.getElementById('scenarioPreview');
 | 
						||
    const title = document.getElementById('previewTitle');
 | 
						||
    const chat = document.getElementById('previewChat');
 | 
						||
    
 | 
						||
    // 预设对话内容
 | 
						||
    const dialogues = {
 | 
						||
        friend: [
 | 
						||
            { type: 'ai', text: '你好呀,我叫小明!你叫什么名字?' },
 | 
						||
            { type: 'user', text: '你好小明,我叫小红!' },
 | 
						||
            { type: 'ai', text: '很高兴认识你小红!我们可以做朋友吗?' },
 | 
						||
            { type: 'user', text: '当然可以!我也想和你做朋友!' }
 | 
						||
        ],
 | 
						||
        party: [
 | 
						||
            { type: 'ai', text: '小红,下周是我的生日,你愿意来参加我的生日派对吗?' },
 | 
						||
            { type: 'user', text: '哇,真的吗?我很想去!' },
 | 
						||
            { type: 'ai', text: '太好了!派对在下周六下午3点,记得带上好心情哦!' }
 | 
						||
        ],
 | 
						||
        restaurant: [
 | 
						||
            { type: 'ai', text: '欢迎光临!小朋友想吃点什么呢?' },
 | 
						||
            { type: 'user', text: '我想要一份儿童套餐,谢谢!' },
 | 
						||
            { type: 'ai', text: '好的,儿童套餐有汉堡、薯条和果汁,这样可以吗?' }
 | 
						||
        ],
 | 
						||
        shopping: [
 | 
						||
            { type: 'ai', text: '小朋友,你在找什么东西吗?' },
 | 
						||
            { type: 'user', text: '我想买一些水果给妈妈!' },
 | 
						||
            { type: 'ai', text: '真懂事!我们这里有苹果、香蕉和橙子,你想要哪种?' }
 | 
						||
        ],
 | 
						||
        actor: [
 | 
						||
            { type: 'ai', text: '现在你是一只小猫咪,你会怎么介绍自己呢?' },
 | 
						||
            { type: 'user', text: '喵~我是一只可爱的小猫,我喜欢吃鱼和玩毛线球!' },
 | 
						||
            { type: 'ai', text: '表演得太棒了!你还能学其他小动物吗?' }
 | 
						||
        ],
 | 
						||
        story: [
 | 
						||
            { type: 'ai', text: '让我们一起编一个故事吧!从前有一只勇敢的小兔子...' },
 | 
						||
            { type: 'user', text: '这只小兔子住在一个神奇的森林里!' },
 | 
						||
            { type: 'ai', text: '哇!那这个森林里还有什么特别的地方吗?' }
 | 
						||
        ]
 | 
						||
    };
 | 
						||
    
 | 
						||
    const dialogue = dialogues[scenarioType] || dialogues.friend;
 | 
						||
    
 | 
						||
    // 设置标题
 | 
						||
    const titles = {
 | 
						||
        friend: '👫 和小明交朋友',
 | 
						||
        party: '🎂 生日派对邀请',
 | 
						||
        restaurant: '🏪 餐厅点餐小达人',
 | 
						||
        shopping: '🛍️ 超市购物助手',
 | 
						||
        actor: '🎭 小小演员训练营',
 | 
						||
        story: '🌈 创意故事大王'
 | 
						||
    };
 | 
						||
    
 | 
						||
    title.textContent = titles[scenarioType] || '对话预览';
 | 
						||
    
 | 
						||
    // 清空并重新填充对话
 | 
						||
    chat.innerHTML = '';
 | 
						||
    
 | 
						||
    dialogue.forEach((msg, index) => {
 | 
						||
        setTimeout(() => {
 | 
						||
            const msgDiv = document.createElement('div');
 | 
						||
            msgDiv.className = `chat-bubble ${msg.type}-bubble`;
 | 
						||
            msgDiv.innerHTML = `
 | 
						||
                <span class="avatar">${msg.type === 'ai' ? '🤖' : '😊'}</span>
 | 
						||
                <span class="text">${msg.text}</span>
 | 
						||
            `;
 | 
						||
            chat.appendChild(msgDiv);
 | 
						||
            
 | 
						||
            // 滚动到底部
 | 
						||
            chat.scrollTop = chat.scrollHeight;
 | 
						||
        }, index * 1000);
 | 
						||
    });
 | 
						||
    
 | 
						||
    // 显示弹窗
 | 
						||
    modal.style.display = 'flex';
 | 
						||
    
 | 
						||
    // 添加点击外部关闭功能
 | 
						||
    modal.addEventListener('click', function(e) {
 | 
						||
        if (e.target === modal) {
 | 
						||
            closePreview();
 | 
						||
        }
 | 
						||
    });
 | 
						||
};
 | 
						||
 | 
						||
window.closePreview = function() {
 | 
						||
    const modal = document.getElementById('scenarioPreview');
 | 
						||
    modal.style.display = 'none';
 | 
						||
};
 | 
						||
 | 
						||
// 按钮点击效果增强
 | 
						||
document.addEventListener('click', function(e) {
 | 
						||
    // 为所有按钮添加点击波纹效果
 | 
						||
    if (e.target.matches('button, .btn, .btn-start, .btn-preview')) {
 | 
						||
        createRipple(e);
 | 
						||
    }
 | 
						||
});
 | 
						||
 | 
						||
function createRipple(event) {
 | 
						||
    const button = event.target;
 | 
						||
    const rect = button.getBoundingClientRect();
 | 
						||
    const size = Math.max(rect.width, rect.height);
 | 
						||
    const x = event.clientX - rect.left - size / 2;
 | 
						||
    const y = event.clientY - rect.top - size / 2;
 | 
						||
    
 | 
						||
    const ripple = document.createElement('span');
 | 
						||
    ripple.style.cssText = `
 | 
						||
        position: absolute;
 | 
						||
        width: ${size}px;
 | 
						||
        height: ${size}px;
 | 
						||
        left: ${x}px;
 | 
						||
        top: ${y}px;
 | 
						||
        background: rgba(255, 255, 255, 0.6);
 | 
						||
        border-radius: 50%;
 | 
						||
        transform: scale(0);
 | 
						||
        animation: ripple 0.6s linear;
 | 
						||
        pointer-events: none;
 | 
						||
        z-index: 1000;
 | 
						||
    `;
 | 
						||
    
 | 
						||
    // 确保按钮有相对定位
 | 
						||
    if (getComputedStyle(button).position === 'static') {
 | 
						||
        button.style.position = 'relative';
 | 
						||
    }
 | 
						||
    
 | 
						||
    button.appendChild(ripple);
 | 
						||
    
 | 
						||
    setTimeout(() => {
 | 
						||
        ripple.remove();
 | 
						||
    }, 600);
 | 
						||
}
 | 
						||
 | 
						||
// 添加CSS动画
 | 
						||
const style = document.createElement('style');
 | 
						||
style.textContent = `
 | 
						||
    @keyframes ripple {
 | 
						||
        to {
 | 
						||
            transform: scale(4);
 | 
						||
            opacity: 0;
 | 
						||
        }
 | 
						||
    }
 | 
						||
    
 | 
						||
    @keyframes fadeInUp {
 | 
						||
        from {
 | 
						||
            opacity: 0;
 | 
						||
            transform: translateY(30px);
 | 
						||
        }
 | 
						||
        to {
 | 
						||
            opacity: 1;
 | 
						||
            transform: translateY(0);
 | 
						||
        }
 | 
						||
    }
 | 
						||
    
 | 
						||
    .fade-in {
 | 
						||
        animation: fadeInUp 0.6s ease forwards;
 | 
						||
    }
 | 
						||
    
 | 
						||
    .animate-in {
 | 
						||
        animation: fadeInUp 0.8s ease forwards;
 | 
						||
    }
 | 
						||
`;
 | 
						||
document.head.appendChild(style);
 | 
						||
 | 
						||
// 性能优化:节流函数
 | 
						||
function throttle(func, wait) {
 | 
						||
    let timeout;
 | 
						||
    return function executedFunction(...args) {
 | 
						||
        const later = () => {
 | 
						||
            clearTimeout(timeout);
 | 
						||
            func(...args);
 | 
						||
        };
 | 
						||
        clearTimeout(timeout);
 | 
						||
        timeout = setTimeout(later, wait);
 | 
						||
    };
 | 
						||
}
 | 
						||
 | 
						||
// 滚动性能优化
 | 
						||
const handleScroll = throttle(() => {
 | 
						||
    // 滚动相关的性能敏感操作
 | 
						||
}, 100);
 | 
						||
 | 
						||
window.addEventListener('scroll', handleScroll);
 |