使用方法

1
<numberRoll :number="9866.66"></numberRoll>

封装组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<template>
<ul class="number-roll" :style="{height: height + 'px'}" v-html="strHtml"></ul>
</template>

<script>
export default {
props: {
number: '',
height: {
type: String,
default: '45'
},
time: {
type: Number,
default: 2000
}
},
data() {
return {
hash: '',
arr: [],
strHtml: ''
}
},
watch: {
number: function (newValue, oldValue) {
this.startDom();
}
},
methods: {
toHash() {
let arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
let str = '';
for (let i = 0; i < 20; i++) {
str += arr[parseInt(Math.random() * arr.length)]
}
this.hash = str;
},
toNumber() {
let arr = [];
for (let i = 0; i < this.number.length; i++) {
arr.push(this.number.charAt(i))
}
this.arr = arr;
},
dom() {
let str = '';
for (let i = 0; i < this.arr.length; i++) {
if (parseInt(this.arr[i]) >= 0) {
str += `<li class="${this.hash}" style="display: flex;flex-direction: column;" data-value="${this.arr[i]}">
<span style="flex: 0 0 ${this.height}px">0</span>
<span style="flex: 0 0 ${this.height}px">1</span>
<span style="flex: 0 0 ${this.height}px">2</span>
<span style="flex: 0 0 ${this.height}px">3</span>
<span style="flex: 0 0 ${this.height}px">4</span>
<span style="flex: 0 0 ${this.height}px">5</span>
<span style="flex: 0 0 ${this.height}px">6</span>
<span style="flex: 0 0 ${this.height}px">7</span>
<span style="flex: 0 0 ${this.height}px">8</span>
<span style="flex: 0 0 ${this.height}px">9</span>
</li>`
} else {
str += `<span>${this.arr[i]}</span>`;
}
}
this.strHtml = str;
},
startDom() {
this.toHash();
this.toNumber();
this.dom();
},
animate() {
let doms = document.getElementsByClassName(this.hash);
for (let i = 0; i < doms.length; i++) {
let value = Number(doms[i].dataset.value);
let scrollTop = Number(this.height) * value;
// this.scroll(doms[i], scrollTop);
this.flash(doms[i], scrollTop);
}
},
// 数字滚动特效
scroll(dom, scrollTop) {
let top = 0;
let topAdd = scrollTop / this.time * 20;
let interval = setInterval(() => {
if (top < scrollTop) {
top = top + topAdd;
dom.style.marginTop = '-' + top + 'px';
} else {
dom.style.marginTop = '-' + scrollTop + 'px';
clearInterval(interval);
}
}, 20);
},
// 数字跳动特效
flash(dom, scrollTop) {
let top = 0;
let timeSplit = this.time * Number(this.height) / scrollTop;
let interval = setInterval(() => {
if (top < scrollTop) {
top = top + Number(this.height);
dom.style.marginTop = '-' + top + 'px';
} else {
dom.style.marginTop = '-' + scrollTop + 'px';
clearInterval(interval);
}
}, 300);
}
},
mounted() {
this.startDom();
},
updated() {
this.animate();
}
}
</script>

<style lang="scss" scoped>
.number-roll {
display: flex;
flex-direction: row;
overflow: hidden;
}
</style>