// 主页增强功能 - 无彩蛋版本
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 = `
${msg.type === 'ai' ? '🤖' : '😊'}
${msg.text}
`;
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);