tn-count-scroll.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <template>
  2. <view class="tn-count-scroll-class tn-count-scroll">
  3. <view
  4. v-for="(item, index) in columns"
  5. :key="index"
  6. class="tn-count-scroll__box"
  7. :style="{
  8. width: $t.string.getLengthUnitValue(width),
  9. height: heightPxValue + 'px'
  10. }"
  11. >
  12. <view
  13. class="tn-count-scroll__column"
  14. :style="{
  15. transform: `translate3d(0, -${keys[index] * heightPxValue}px, 0)`,
  16. transitionDuration: `${duration}s`
  17. }"
  18. >
  19. <view
  20. v-for="(value, value_index) in item"
  21. :key="value_index"
  22. class="tn-count-scroll__column__item"
  23. :class="[fontColorClass]"
  24. :style="{
  25. height: heightPxValue + 'px',
  26. lineHeight: heightPxValue + 'px',
  27. fontSize: fontSizeStyle || '32rpx',
  28. fontWeight: bold ? 'bold': 'normal',
  29. color: fontColorStyle || '#080808'
  30. }"
  31. >
  32. {{ value }}
  33. </view>
  34. </view>
  35. </view>
  36. </view>
  37. </template>
  38. <script>
  39. import componentsColorMixin from '../../libs/mixin/components_color.js'
  40. export default {
  41. name: 'tn-count-scroll',
  42. mixins: [componentsColorMixin],
  43. props: {
  44. value: {
  45. type: Number,
  46. default: 0
  47. },
  48. // 行高
  49. height: {
  50. type: Number,
  51. default: 32
  52. },
  53. // 单个字的宽度
  54. width: {
  55. type: [String, Number],
  56. default: 'auto'
  57. },
  58. // 是否加粗
  59. bold: {
  60. type: Boolean,
  61. default: false
  62. },
  63. // 持续时间
  64. duration: {
  65. type: Number,
  66. default: 1.2
  67. },
  68. // 十分位分割符
  69. decimalSeparator: {
  70. type: String,
  71. default: '.'
  72. },
  73. // 千分位分割符
  74. thousandthsSeparator: {
  75. type: String,
  76. default: ''
  77. }
  78. },
  79. computed: {
  80. heightPxValue() {
  81. return uni.upx2px(this.height || 0)
  82. }
  83. },
  84. data() {
  85. return {
  86. // 每列的数据
  87. columns: [],
  88. // 每列对应值所在的滚动位置
  89. keys: []
  90. }
  91. },
  92. watch: {
  93. value(val) {
  94. this.initColumn(val)
  95. }
  96. },
  97. created() {
  98. // 为了达到一进入就有滚动效果,延迟执行初始化
  99. this.initColumn()
  100. setTimeout(() => {
  101. this.initColumn(this.value)
  102. }, 20)
  103. },
  104. methods: {
  105. // 初始化每一列的数据
  106. initColumn(val) {
  107. val = val + ''
  108. let digit = val.length,
  109. columnArray = [],
  110. rows = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
  111. for (let i = 0; i < digit; i++) {
  112. if (val[i] === this.decimalSeparator || val[i] === this.thousandthsSeparator) {
  113. columnArray.push(val[i])
  114. } else {
  115. columnArray.push(rows)
  116. }
  117. }
  118. this.columns = columnArray
  119. this.roll(val)
  120. },
  121. // 滚动处理
  122. roll(value) {
  123. let valueArray = value.toString().split(''),
  124. lengths = this.columns.length,
  125. indexs = [];
  126. while (valueArray.length) {
  127. let figure = valueArray.pop()
  128. if (figure === this.decimalSeparator || figure === this.thousandthsSeparator) {
  129. indexs.unshift(0)
  130. } else {
  131. indexs.unshift(Number(figure))
  132. }
  133. }
  134. while(indexs.length < lengths) {
  135. indexs.unshift(0)
  136. }
  137. this.keys = indexs
  138. }
  139. }
  140. }
  141. </script>
  142. <style lang="scss" scoped>
  143. .tn-count-scroll {
  144. display: inline-flex;
  145. align-items: center;
  146. justify-content: space-between;
  147. &__box {
  148. overflow: hidden;
  149. }
  150. &__column {
  151. transform: translate3d(0, 0, 0);
  152. display: flex;
  153. align-items: center;
  154. justify-content: center;
  155. flex-direction: column;
  156. transition-timing-function: cubic-bezier(0, 1, 0, 1);
  157. &__item {
  158. display: flex;
  159. align-items: center;
  160. justify-content: center;
  161. }
  162. }
  163. }
  164. </style>