seedance / script.js
liyangbing's picture
add feature
1c0ec4c
// 平滑滚动效果
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
// 数字动画效果
function animateValue(element, start, end, duration) {
let startTimestamp = null;
const step = (timestamp) => {
if (!startTimestamp) startTimestamp = timestamp;
const progress = Math.min((timestamp - startTimestamp) / duration, 1);
const value = Math.floor(progress * (end - start) + start);
element.textContent = value;
if (progress < 1) {
window.requestAnimationFrame(step);
}
};
window.requestAnimationFrame(step);
}
// 页面加载时触发数字动画
window.addEventListener('load', () => {
const statNumbers = document.querySelectorAll('.stat-number');
statNumbers.forEach(stat => {
const text = stat.textContent;
if (text.includes('%')) {
const value = parseInt(text);
stat.textContent = '0%';
animateValue(stat, 0, value, 2000);
setTimeout(() => {
stat.textContent = value + '%';
}, 2000);
} else if (text.includes('x')) {
stat.textContent = '0x';
setTimeout(() => {
stat.textContent = text;
}, 1500);
} else {
const value = parseInt(text);
animateValue(stat, 0, value, 2000);
}
});
});
// 滚动时的淡入效果
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -100px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, observerOptions);
// 监听需要动画的元素
document.querySelectorAll('.chart-card, .pricing-card, .testimonial-card').forEach(el => {
el.style.opacity = '0';
el.style.transform = 'translateY(30px)';
observer.observe(el);
});
// 添加visible类的样式
const style = document.createElement('style');
style.textContent = `
.visible {
opacity: 1 !important;
transform: translateY(0) !important;
transition: opacity 0.6s ease, transform 0.6s ease;
}
`;
document.head.appendChild(style);
// 导航栏滚动效果
let lastScroll = 0;
const header = document.querySelector('header');
window.addEventListener('scroll', () => {
const currentScroll = window.pageYOffset;
if (currentScroll > 100) {
header.style.boxShadow = '0 2px 10px rgba(0,0,0,0.1)';
} else {
header.style.boxShadow = 'var(--shadow-sm)';
}
lastScroll = currentScroll;
});
// 按钮点击效果
document.querySelectorAll('.primary-button, .secondary-button, .pricing-button').forEach(button => {
button.addEventListener('click', function(e) {
// 创建涟漪效果
const ripple = document.createElement('span');
const rect = this.getBoundingClientRect();
const size = Math.max(rect.width, rect.height);
const x = e.clientX - rect.left - size / 2;
const y = e.clientY - rect.top - size / 2;
ripple.style.width = ripple.style.height = size + 'px';
ripple.style.left = x + 'px';
ripple.style.top = y + 'px';
ripple.classList.add('ripple');
this.appendChild(ripple);
setTimeout(() => {
ripple.remove();
}, 600);
});
});
// 添加涟漪效果样式
const rippleStyle = document.createElement('style');
rippleStyle.textContent = `
.primary-button, .secondary-button, .pricing-button {
position: relative;
overflow: hidden;
}
.ripple {
position: absolute;
border-radius: 50%;
background: rgba(255, 255, 255, 0.5);
transform: scale(0);
animation: ripple-animation 0.6s ease-out;
}
@keyframes ripple-animation {
to {
transform: scale(4);
opacity: 0;
}
}
`;
document.head.appendChild(rippleStyle);
// 表格行悬停效果
document.querySelectorAll('tbody tr').forEach(row => {
row.addEventListener('mouseenter', function() {
this.style.transform = 'scale(1.02)';
this.style.transition = 'transform 0.3s ease';
});
row.addEventListener('mouseleave', function() {
this.style.transform = 'scale(1)';
});
});
// 加载进度条动画
window.addEventListener('load', () => {
const bars = document.querySelectorAll('.bar');
bars.forEach(bar => {
const width = bar.style.width;
bar.style.width = '0';
setTimeout(() => {
bar.style.width = width;
}, 500);
});
});
// 演示画廊交互
const galleryItems = document.querySelectorAll('.gallery-item');
const prevBtn = document.querySelector('.demo-nav.prev');
const nextBtn = document.querySelector('.demo-nav.next');
let currentIndex = 0;
function updateGallery(index) {
galleryItems.forEach((item, i) => {
item.classList.toggle('active', i === index);
});
}
if (prevBtn && nextBtn) {
prevBtn.addEventListener('click', () => {
currentIndex = (currentIndex - 1 + galleryItems.length) % galleryItems.length;
updateGallery(currentIndex);
});
nextBtn.addEventListener('click', () => {
currentIndex = (currentIndex + 1) % galleryItems.length;
updateGallery(currentIndex);
});
}
galleryItems.forEach((item, index) => {
item.addEventListener('click', () => {
currentIndex = index;
updateGallery(currentIndex);
});
});