feat: add count-up animation for homepage statistics
This commit is contained in:
@@ -47,7 +47,7 @@
|
||||
<div class="absolute inset-0 bg-gradient-to-br from-blue-500/20 to-blue-600/5 rounded-2xl blur-xl group-hover:blur-2xl transition-all duration-300"></div>
|
||||
<div class="relative bg-gradient-to-br from-white to-blue-50/30 rounded-2xl p-6 border border-blue-100/50 shadow-lg group-hover:shadow-blue-500/20 group-hover:scale-[1.02] transition-all duration-300">
|
||||
<div class="text-center">
|
||||
<div class="text-4xl md:text-5xl lg:text-6xl font-black text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-blue-700 mb-3 group-hover:scale-110 transition-transform duration-300">700+</div>
|
||||
<div class="text-4xl md:text-5xl lg:text-6xl font-black text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-blue-700 mb-3 group-hover:scale-110 transition-transform duration-300 counter" data-target="700" data-suffix="+">0+</div>
|
||||
<div class="text-gray-700 text-sm md:text-base font-medium">视觉理解大模型</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -56,7 +56,7 @@
|
||||
<div class="absolute inset-0 bg-gradient-to-br from-blue-500/20 to-blue-600/5 rounded-2xl blur-xl group-hover:blur-2xl transition-all duration-300"></div>
|
||||
<div class="relative bg-gradient-to-br from-white to-blue-50/30 rounded-2xl p-6 border border-blue-100/50 shadow-lg group-hover:shadow-blue-500/20 group-hover:scale-[1.02] transition-all duration-300">
|
||||
<div class="text-center">
|
||||
<div class="text-4xl md:text-5xl lg:text-6xl font-black text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-blue-700 mb-3 group-hover:scale-110 transition-transform duration-300">99.9%</div>
|
||||
<div class="text-4xl md:text-5xl lg:text-6xl font-black text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-blue-700 mb-3 group-hover:scale-110 transition-transform duration-300 counter" data-target="99.9" data-suffix="%">0%</div>
|
||||
<div class="text-gray-700 text-sm md:text-base font-medium">SLA 可用性</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -65,7 +65,7 @@
|
||||
<div class="absolute inset-0 bg-gradient-to-br from-blue-500/20 to-blue-600/5 rounded-2xl blur-xl group-hover:blur-2xl transition-all duration-300"></div>
|
||||
<div class="relative bg-gradient-to-br from-white to-blue-50/30 rounded-2xl p-6 border border-blue-100/50 shadow-lg group-hover:shadow-blue-500/20 group-hover:scale-[1.02] transition-all duration-300">
|
||||
<div class="text-center">
|
||||
<div class="text-4xl md:text-5xl lg:text-6xl font-black text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-blue-700 mb-3 group-hover:scale-110 transition-transform duration-300">15+</div>
|
||||
<div class="text-4xl md:text-5xl lg:text-6xl font-black text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-blue-700 mb-3 group-hover:scale-110 transition-transform duration-300 counter" data-target="15" data-suffix="+">0+</div>
|
||||
<div class="text-gray-700 text-sm md:text-base font:medium">合作伙伴</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -74,7 +74,7 @@
|
||||
<div class="absolute inset-0 bg-gradient-to-br from-blue-500/20 to-blue-600/5 rounded-2xl blur-xl group-hover:blur-2xl transition-all duration-300"></div>
|
||||
<div class="relative bg-gradient-to-br from-white to-blue-50/30 rounded-2xl p-6 border border-blue-100/50 shadow-lg group-hover:shadow-blue-500/20 group-hover:scale-[1.02] transition-all duration-300">
|
||||
<div class="text-center">
|
||||
<div class="text-4xl md:text-5xl lg:text-6xl font-black text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-blue-700 mb-3 group-hover:scale-110 transition-transform duration-300">40+</div>
|
||||
<div class="text-4xl md:text-5xl lg:text-6xl font-black text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-blue-700 mb-3 group-hover:scale-110 transition-transform duration-300 counter" data-target="40" data-suffix="+">0+</div>
|
||||
<div class="text-gray-700 text-sm md:text-base font-medium">软著专利</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -83,3 +83,51 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
const counters = document.querySelectorAll('.counter');
|
||||
const duration = 2000;
|
||||
let animated = false;
|
||||
|
||||
function animateCounter(counter: Element) {
|
||||
const target = parseFloat(counter.getAttribute('data-target') || '0');
|
||||
const suffix = counter.getAttribute('data-suffix') || '';
|
||||
const isDecimal = target % 1 !== 0;
|
||||
const startTime = performance.now();
|
||||
const startValue = 0;
|
||||
|
||||
function update(currentTime: number) {
|
||||
const elapsed = currentTime - startTime;
|
||||
const progress = Math.min(elapsed / duration, 1);
|
||||
const easeOutQuart = 1 - Math.pow(1 - progress, 4);
|
||||
const currentValue = startValue + (target - startValue) * easeOutQuart;
|
||||
|
||||
if (isDecimal) {
|
||||
counter.textContent = currentValue.toFixed(1) + suffix;
|
||||
} else {
|
||||
counter.textContent = Math.floor(currentValue) + suffix;
|
||||
}
|
||||
|
||||
if (progress < 1) {
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
}
|
||||
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting && !animated) {
|
||||
animated = true;
|
||||
counters.forEach(animateCounter);
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.3 });
|
||||
|
||||
counters.forEach((counter) => {
|
||||
observer.observe(counter);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user