index.vue 4.75 KB
<!--
 * @Description: 
 * @Autor: renchao
 * @LastEditTime: 2023-11-09 16:47:44
-->
<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: '', // 状态二动画效果
      };
    },
    mounted () {
      this.Listener();
      this.getData()
    },
    watch: {
      noticeList: {
        handler (newName, oldName) {
          let that = this
          this.Listener();
          setTimeout(res => {
            that.getData();
          }, 300);
        },
        deep: true
      }
    },
    methods: {
      /**
       * @description: handleNotice
       * @param {*} item
       * @author: renchao
       */
      handleNotice (item) {
        this.$alertMes(item.noticeTitle, item.noticeContent)
      },
      /**
       * @description: 获取数据
       * @author: renchao
       */
      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);
      },
      /**
       * @description: 用速度计算时间(想要保持速度一样,2种状态时间不同需算出)
       * @author: renchao
       */
      ComputationTime () {
        this.firstAnimationTime = this.wordLength / this.speed;
        this.secondAnimationTime =
          (this.wordLength + this.backWidth) / this.speed;
      },
      /**
       * @description: 根据状态切换动画
       * @author: renchao
       */
      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`;
        }
      },
      /**
       * @description: Listener
       * @author: renchao
       */
      Listener () {
        let text = this.$refs.text;
        text.addEventListener(
          'animationend',
          res => {
            this.changeState();
          },
          false
        )
      },
      /**
       * @description: mouseOver
       * @author: renchao
       */
      mouseOver () {
        let text = this.$refs.text;
        text.style.animationPlayState = 'paused'
      },
      /**
       * @description: mouseLeave
       * @author: renchao
       */
      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>