原生js版本
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>图片数字滚动效果</title>
<style>
.number-scroll {
display: flex;
gap: 5px;
height: 80px;
}
.digit {
width: 50px;
height: 80px;
object-fit: contain;
transition: transform 0.3s ease;
}
</style>
</head>
<body>
<div class="number-scroll" id="numberContainer"></div>
<script>
// 初始化数字容器
const container = document.getElementById('numberContainer');
const digitCount = 5; // 显示5位数
const targetNumber = 20000; // 目标数值
const duration = 3000; // 动画时长(ms)
// 预加载数字图片(假设图片路径为数字0-9.png)
const digitImages = Array(10).fill().map((_, i) => {
const img = new Image();
img.src = `./${i}.png`; // 替换为实际图片路径
return img;
});
// 初始化显示位
function initDigits() {
container.innerHTML = '';
for (let i = 0; i < digitCount; i++) {
const img = document.createElement('img');
img.className = 'digit';
img.src = digitImages[0].src; // 初始显示0
container.appendChild(img);
}
}
// 数字滚动动画
function animateNumber() {
const startTime = Date.now();
const digits = container.querySelectorAll('.digit');
const update = () => {
const elapsed = Date.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
const currentVal = Math.floor(progress * targetNumber);
const paddedVal = String(currentVal).padStart(digitCount, '0');
// 更新每位数字图片
paddedVal.split('').forEach((digit, index) => {
digits[index].src = digitImages[digit].src;
digits[index].style.transform = `translateY(${10 * (1 - progress)}px)`;
});
if (progress < 1) {
requestAnimationFrame(update);
} else {
// 动画结束后的回调
console.log('Animation completed');
}
};
requestAnimationFrame(update);
}
// 初始化并开始动画
initDigits();
setTimeout(animateNumber, 500); // 延迟启动避免图片未加载
</script>
</body>
</html>
Vue版本
<template>
<div>
<div class="priceBox">
<img
v-for="(digit, index) in digitCount"
:key="index"
class="digit"
:src="currentDigits[index]"
:style="{ transform: `translateY(${offsetY}px)` }"
/>
</div>
</div>
</template>
<script>
export default {
data() {
return {
digitCount: 5, // 显示位数
targetNumber: 20000, // 目标数值
duration: 3000, // 动画时长(ms)
currentDigits: [], // 当前显示的图片路径
offsetY: 0, // Y轴偏移量
digitImages: Array(10).fill().map((_, i) => require(`../../../static/imgs/${i}.png`)) // 预加载图片
};
},
mounted() {
this.initDigits();
this.$nextTick(() => {
setTimeout(this.animateNumber, 500); // 延迟启动确保DOM渲染完成
});
},
methods: {
initDigits() {
this.currentDigits = Array(this.digitCount).fill(this.digitImages[0]);
},
animateNumber() {
const startTime = Date.now();
const animate = () => {
const elapsed = Date.now() - startTime;
const progress = Math.min(elapsed / this.duration, 1);
const currentVal = Math.floor(progress * this.targetNumber);
const paddedVal = String(currentVal).padStart(this.digitCount, '0');
// 更新数字图片和动画偏移
this.currentDigits = paddedVal.split('').map(d => this.digitImages[d]);
this.offsetY = 10 * (1 - progress);
if (progress < 1) {
requestAnimationFrame(animate);
} else {
console.log('Animation completed');
}
};
requestAnimationFrame(animate);
}
},
};
</script>
<style>
.number-scroll {
display: flex;
gap: 5px;
height: 80px;
}
.digit {
width: 50px;
height: 80px;
object-fit: contain;
transition: transform 0.3s ease;
}
</style>
效果图