index.vue 3.84 KB
<template>
  <transition name="fade">
    <!--主要内容-->
    <div class="noticebar">
      <div style="margin-left:5px"></div>
      <svg-icon icon-class='notice' />
      <div style="margin-right:5px"></div>
      <div ref="back" class="back">
        <div ref="text" class="text" @mouseover="mouseOver" @mouseleave="mouseLeave">
          <p v-for="(item, index) in noticeList" :key="index">
            <span> {{ item.noticeTitle }}</span>
            <span class="noticePublishTime">{{ item.noticePublishTime }}</span>
            <el-button type="text" @click="handleNotice(item)" style="color:#F56C6C;font-size: 14px;">[点击查看]</el-button>
          </p>
        </div>
      </div>
    </div>
  </transition>
</template>
<script>
export default {
  props: {
    noticeList: {
      type: Array,
      default: []
    }
  },
  data () {
    return {
      speed: 50, // 速度(单位px/s)
      backWidth: '', // 父级宽度
      backHeight: '', // 父级高度
      wordLength: '', // 文本长度
      state: 1,
      firstAnimationTime: '', // 状态一动画效果
      secondAnimationTime: '', // 状态二动画效果
    };
  },
  watch: {
    noticeList: {
      handler (newName, oldName) {
        let that = this
        this.Listener();
        setTimeout(res => {
          that.getData();
        }, 100);
      },
      deep: true
    }
  },
  methods: {
    handleNotice (item) {
      this.$alertMes(item.noticeTitle, item.noticeContent)
    },
    // 获取数据
    getData () {
      let style = document.styleSheets[0];
      let text = this.$refs.text;
      let back = this.$refs.back;
      this.backWidth = back.offsetWidth;
      this.backHeight = back.offsetHeight;
      text.style.lineHeight = this.backHeight + 'px';
      this.wordLength = text.offsetWidth;
      this.ComputationTime(); // 计算时间
      style.insertRule(
        `@keyframes firstAnimation {0%   {left:0px;}100%  {left:-${this.wordLength}px;}}`
      );
      style.insertRule(
        `@keyframes secondAnimation {0%   {left:${this.backWidth}px;}100%  {left:-${this.wordLength}px;}}`
      );
      setTimeout(res => {
        this.changeState();
      }, 300);
    },
    // 用速度计算时间(想要保持速度一样,2种状态时间不同需算出)
    ComputationTime () {
      this.firstAnimationTime = this.wordLength / this.speed;
      this.secondAnimationTime =
        (this.wordLength + this.backWidth) / this.speed;
    },
    // 根据状态切换动画
    changeState () {
      let text = this.$refs.text;
      if (this.state == 1) {
        text.style.animation = `firstAnimation ${this.firstAnimationTime}s linear`;
        this.state = 2;
      } else {
        text.style.animation = `secondAnimation ${this.secondAnimationTime}s linear infinite`;
      }
    },
    Listener () {
      let text = this.$refs.text;
      text.addEventListener(
        'animationend',
        res => {
          this.changeState();
        },
        false
      )
    },
    mouseOver () {
      let text = this.$refs.text;
      text.style.animationPlayState = 'paused'
    },
    mouseLeave () {
      let text = this.$refs.text;
      text.style.animationPlayState = ''
    }
  }
};
</script>
<style lang="scss" scoped>
.noticebar {
  display: flex;
  align-items: center;
  width: 100%;
  height: 28px;
  background: rgba(0, 0, 0, 0.1);

  .icon {
    img {
      height: 100%;
      width: 100%;
    }
  }

  .back {
    overflow: hidden;
    white-space: nowrap;
    margin: 0 auto;
    height: 100%;
    width: 100%;
    cursor: pointer;
    position: relative;
    font-size: 14px;
    color: #fff;

    .text {
      position: absolute;
      display: inline-block;
      padding: 2px 0;
      display: flex;

      p {
        margin-right: 80px;
        display: flex;
        align-items: center;
        height: 28px;
        line-height: 28px;
      }
    }
  }
}
</style>