all files / src/components/Barrage/ item.vue

0% Statements 0/21
0% Branches 0/4
0% Functions 0/4
0% Lines 0/21
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                                                                                                                                                                                                                 
<template>
  <li class="barrage-item"
      :style="styles"
      :class="[
        playing ? 'playing' : '',
        played ? 'played' : ''
      ]">
    <span class="content" v-text="barrage.text" :style="{color: barrage.color}"></span>
  </li>
</template>
 
<script>
  export default {
    name: 'barrage-item',
    props: {
      id: {
        type: Number
      },
      delay: {
        type: Number,
        default: 10
      },
      barrage: {
        type: Object,
        required: true
      }
    },
    data () {
      return {
        // 定时器
        timers: {
          transform: null,
          playing: null
        },
        // 播放状态
        played: false,
        playing: false,
        styles: {
          'z-index': (this.id + 1) * 10,
          transition: `transform ${this.delay}s linear`
        }
      }
    },
    ready () {
      this.startAnimation()
    },
    mounted () {
      this.startAnimation()
    },
    beforeDestroy () {
      if (this.timers.transform) {
        clearTimeout(this.timers.transform)
        this.timers.transform = null
      }
      if (this.timers.playing) {
        clearTimeout(this.timers.playing)
        this.timers.playing = null
      }
    },
    methods: {
      randomTop () {
        // cound height range
        const innerHeight = document.documentElement.clientHeight - 500
 
        let top = Math.floor(Math.random() * innerHeight)
        return `${top}px`
      },
      startAnimation () {
        this.$nextTick(() => {
          // 开始动画
          this.timers.transform = setTimeout(() => {
            this.playing = true
            // 计算出一个随机高度,相对左距
            this.$set(this.styles, 'top', this.randomTop())
          })
          // 结束动画
          this.timers.playing = setTimeout(() => {
            this.playing = false
            this.played = true
            this.$nextTick(() => {
              this.$emit('end', this.id)
            })
          }, this.delay * 1000)
        })
      }
    }
  }
</script>
 
<style lang="scss" scoped>
  .barrage-item {
    width: auto;
    right: 0px;
    display: block;
    position: fixed;
    transform: translate3d(100%, 0, 0);
    &.playing {
      transform: translate3d(calc(-100vw - 200%), 0, 0);
    }
    &.played {
      visibility: hidden;
    }
  }
</style>