<template>
  <div class="gmv-show-gmv" ref="num">
    <template v-for="(n,i) in nums">
      <DigitAnimation v-bind="$attrs" :show="frame[i].show" :num="frame[i].num" :speed="frame[i].speed" :key="i"></DigitAnimation>
    </template>
  </div>
</template>
 <script>
import DigitAnimation from './DigitAnimation'
import { getRollOption, init } from './frame'
export default {
  components: {
    DigitAnimation
  },
  props: {
    // 需要在多长时间内更新完整个增量数字
    time: {
      type: Number,
      default: 2000
    },
    // 数字的位数
    len: {
      type: Number,
      default: 9
    },
    // 初始化开始数字
    start: {
      type: Number,
      default: 0
    },
    // 当前增量
    incr: {
      type: Number,
      default: 1
    }
  },
  data() {
    return {
      progress: 0,
      frame: [],
      timer: null,
      begin: 0, // 动画结束后的数字
      nums: []
    }
  },
  created() {
    let vm = this
    vm.begin = vm.start
    vm.showNums()
  },
  mounted() {
    let vm = this
    window.setTimeout(() => {
      vm.updata(vm.incr)
    }, 1000)
  },
  methods: {
    updata(incr) {
      let vm = this
      // 若当前动画未执行完
      if (vm.timer || vm.progress) {
        vm.stop()
      }
      let { time, begin, len } = vm
      let { freq, data, total } = getRollOption({ time, begin, incr, len })
      let { nums, changeMax, ends } = init({ start: begin, incr, len })
      // 提前更新结束后的数字，防止提前结束动画引起某个数字隐藏不显示
      vm.begin += incr
      let i = 0
      let show = true

      // 每10ms，进行一次检测
      vm.timer = window.setInterval(() => {
        if (vm.progress == 1) {
          this.$emit('begin')
        }
        let item = data[i]
        show = !show
        // 根据每一帧的数据切换动画
        if (item != undefined) {
          for (let l = 0; l < nums.length; l++) {
            if (l >= changeMax && item[l].change) {
              item[l].show = show
              vm.frame.splice(l, 1, item[l])
            }
          }
        }
        // 仅当进入动画时更新下一帧
        if (show) {
          i++
        }
        vm.progress++
        this.$emit('progress', vm.progress / total)
        if (i > total - 1) {
          vm.showNums()
          window.clearInterval(vm.timer)
          this.$emit('done')
        }
      }, freq)
    },
    showNums() {
      let vm = this
      vm.nums = vm.begin
        .toString()
        .padStart(vm.len, '0')
        .split('')
        .map(n => parseInt(n))
      vm.frame = []
      for (let i = 0; i < vm.nums.length; i++) {
        vm.frame.push({
          num: vm.nums[i],
          speed: 1000,
          show: true
        })
      }
    },
    stop() {
      this.progress = 0
      // 提前结束是，直接更新至最新
      this.showNums()
      window.clearInterval(this.timer)
    },
    parse() {
      window.clearInterval(this.timer)
    }
  }
}
</script>
 
<style lang="scss" scoped>
.gmv-show-gmv {
  width: 100%;
  display: flex;
  justify-items: start;
  align-items: center;
}
</style>
