| 1234567891011121314151617181920212223242526272829303132333435363738394041 |
- <template>
- <span ref="numberEl">{{ displayValue }}</span>
- </template>
- <script setup>
- import { ref, watch, onMounted } from "vue";
- const props = defineProps({
- value: { type: Number, default: 0 },
- duration: { type: Number, default: 1500 },
- easing: { type: Function, default: (t) => t * (2 - t) },
- });
- const displayValue = ref(0);
- const numberEl = ref(null);
- function animate(start, end) {
- const startTime = performance.now();
- const frame = (currentTime) => {
- const elapsed = currentTime - startTime;
- const progress = Math.min(elapsed / props.duration, 1);
- displayValue.value = Math.floor(start + (end - start) * props.easing(progress));
- displayValue.value = displayValue.value.toLocaleString();
- if (progress < 1) {
- requestAnimationFrame(frame);
- }
- };
- requestAnimationFrame(frame);
- }
- watch(
- () => props.value,
- (newVal, oldVal) => {
- animate(oldVal, newVal);
- }
- );
- onMounted(() => {
- animate(0, props.value);
- });
- </script>
|