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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
  | <template> 
 |    <view class="tn-count-scroll-class tn-count-scroll"> 
 |      <view 
 |        v-for="(item, index) in columns" 
 |        :key="index" 
 |        class="tn-count-scroll__box" 
 |        :style="{ 
 |          width: $t.string.getLengthUnitValue(width), 
 |          height: heightPxValue + 'px' 
 |        }" 
 |      > 
 |        <view 
 |          class="tn-count-scroll__column" 
 |          :style="{ 
 |            transform: `translate3d(0, -${keys[index] * heightPxValue}px, 0)`, 
 |            transitionDuration: `${duration}s` 
 |          }" 
 |        > 
 |          <view 
 |            v-for="(value, value_index) in item" 
 |            :key="value_index" 
 |            class="tn-count-scroll__column__item" 
 |            :class="[fontColorClass]" 
 |            :style="{ 
 |              height: heightPxValue + 'px', 
 |              lineHeight: heightPxValue + 'px', 
 |              fontSize: fontSizeStyle || '32rpx', 
 |              fontWeight: bold ? 'bold': 'normal', 
 |              color: fontColorStyle || '#080808' 
 |            }" 
 |          > 
 |            {{ value }} 
 |          </view> 
 |        </view> 
 |      </view> 
 |    </view> 
 |  </template> 
 |    
 |  <script> 
 |    import componentsColorMixin from '../../libs/mixin/components_color.js' 
 |    export default { 
 |      name: 'tn-count-scroll', 
 |      mixins: [componentsColorMixin], 
 |      props: { 
 |        value: { 
 |          type: Number, 
 |          default: 0 
 |        }, 
 |        // 行高 
 |        height: { 
 |          type: Number, 
 |          default: 32 
 |        }, 
 |        // 单个字的宽度 
 |        width: { 
 |          type: [String, Number], 
 |          default: 'auto' 
 |        }, 
 |        // 是否加粗 
 |        bold: { 
 |          type: Boolean, 
 |          default: false 
 |        }, 
 |        // 持续时间 
 |        duration: { 
 |          type: Number, 
 |          default: 1.2 
 |        }, 
 |        // 十分位分割符 
 |        decimalSeparator: { 
 |          type: String, 
 |          default: '.' 
 |        }, 
 |        // 千分位分割符 
 |        thousandthsSeparator: { 
 |          type: String, 
 |          default: '' 
 |        } 
 |      }, 
 |      computed: { 
 |        heightPxValue() { 
 |          return uni.upx2px(this.height || 0) 
 |        } 
 |      }, 
 |      data() { 
 |        return { 
 |          // 每列的数据 
 |          columns: [], 
 |          // 每列对应值所在的滚动位置 
 |          keys: [] 
 |        } 
 |      }, 
 |      watch: { 
 |        value(val) { 
 |          this.initColumn(val) 
 |        } 
 |      }, 
 |      created() { 
 |        // 为了达到一进入就有滚动效果,延迟执行初始化 
 |        this.initColumn() 
 |        setTimeout(() => { 
 |          this.initColumn(this.value) 
 |        }, 20) 
 |      }, 
 |      methods: { 
 |        // 初始化每一列的数据 
 |        initColumn(val) { 
 |          val = val + '' 
 |          let digit = val.length, 
 |              columnArray = [], 
 |              rows = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; 
 |          for (let i = 0; i < digit; i++) { 
 |            if (val[i] === this.decimalSeparator || val[i] === this.thousandthsSeparator) { 
 |              columnArray.push(val[i]) 
 |            } else { 
 |              columnArray.push(rows) 
 |            } 
 |          } 
 |          this.columns = columnArray 
 |          this.roll(val) 
 |        }, 
 |        // 滚动处理 
 |        roll(value) { 
 |          let valueArray = value.toString().split(''), 
 |              lengths = this.columns.length, 
 |              indexs = []; 
 |           
 |          while (valueArray.length) { 
 |            let figure = valueArray.pop() 
 |            if (figure === this.decimalSeparator || figure === this.thousandthsSeparator) { 
 |              indexs.unshift(0) 
 |            } else { 
 |              indexs.unshift(Number(figure)) 
 |            } 
 |          } 
 |          while(indexs.length < lengths) { 
 |            indexs.unshift(0) 
 |          } 
 |          this.keys = indexs 
 |        } 
 |      } 
 |    } 
 |  </script> 
 |    
 |  <style lang="scss" scoped> 
 |     
 |    .tn-count-scroll { 
 |      display: inline-flex; 
 |      align-items: center; 
 |      justify-content: space-between; 
 |       
 |      &__box { 
 |        overflow: hidden; 
 |      } 
 |       
 |      &__column { 
 |        transform: translate3d(0, 0, 0); 
 |        display: flex; 
 |        align-items: center; 
 |        justify-content: center; 
 |        flex-direction: column; 
 |        transition-timing-function: cubic-bezier(0, 1, 0, 1); 
 |         
 |        &__item { 
 |          display: flex; 
 |          align-items: center; 
 |          justify-content: center; 
 |        } 
 |      } 
 |    } 
 |  </style> 
 |  
  |