文字跑马灯

·  阅读 121
文字跑马灯

前段时间刷短视频的时候“你是我的神”这个词特别火,我还纳闷特意去搜了一下。结果显然而知,尬的双脚能抠出三室两厅外加一个卫生间。第二天和大学同学玩游戏,A同学(男)对B同学(男)说了一些挺尬的话,这个具体的多尬貌似情侣间的吧 哈哈^_^,B同学轻描淡写的说了句:“你是我的神”。我瞬间就get到了B同学内心想法,结合昨天看到的这个梗。笑完了...

需求背景

1.最近在开发业务中遇到需要实现一个跑马灯效果,首先我们正常思维就是看查看我们项目中引用的第三方UI库是否有跑马灯的组件,其次看项目中是否有用到类似的例子然后CV大法。搞定。但是令人遗憾的是这两条路都被堵死了。由于我们UI组件库是老版本,新的UI组件库和老版本UI组件库不兼容,如果升级的话风险需要评估。第二点往常的项目中确实有用到文字跑马灯的效果,之前的组件宽度是写死的用作当前屏幕的宽度。如果我只是想让半屏的滚动,显然滚动时间会很长时间,产品认为这个不符合他的预期。没有办法只能自己搞了。

设计思路

首先要知道可视区域的宽度,然后需要知道内容的宽度。因为内容在可视区域内滑动当内容画出可视区域之后要瞬间将内容的头部转移到可视区域的尾部然后再次的滚动。

代码部分

这里我们已vue为例

<template>
  <div class='route__container__notify'>
    <div ref='wrapRef' id='route__container__wrap' class='route__container__wrap'>
      <div ref='contentRef' class='route__container__text' :style='transitionText'>
        {{ notifyText }}
      </div>
    </div>
  </div>
</template>
<script>
  export default {
    data () {
      return {
        transitionText: '',
        notifyText: '眨眼和闪烁眨眼和闪烁',
        wrapWidth: '',
        contentWidth: '',
        timer: '',
        speed: 50
      }
    },
    mounted () {
      this.wrapWidth = this.$refs.wrapRef.clientWidth
      this.contentWidth = this.$refs.contentRef.clientWidth
      this.$nextTick(async() => {
        this.transitionText = {
          transitionDelay: '1s',
          transitionDuration: `${this.contentWidth / this.speed}s`,
          transform: `translateX(-${this.contentWidth}px)`
        }
        await this.sleep((this.contentWidth / this.speed) * 1000 + 1000)
        await this.animationFn()
      })
    },
    destroyed () {
      console.log('destroyed')
      clearTimeout(this.timer)
    },
    methods: {
      async animationFn () {
        const time = this.contentWidth + this.wrapWidth
        this.transitionText = {
          transitionDuration: '0s',
          transform: `translateX(${this.wrapWidth}px)`
        }
        await this.sleep(20)
        this.transitionText = {
          transitionDuration: `${time / this.speed}s`,
          transform: `translateX(-${this.contentWidth}px)`
        }
        await this.sleep((time / this.speed) * 1000)
        return this.animationFn()
      },
      sleep (time) {
        return new Promise((resolve) => {
          this.timer = setTimeout(resolve, time)
        })
      }
    }
  }
</script>
<style lang="scss" scoped>
  .route__container__notify {
    position: relative;
    overflow: hidden;
    height: 40px;
    color: #ed6a0c;
    background-color: #fffbe8;
    .route__container__wrap {
      position: relative;
      display: flex;
      flex: 1;
      align-items: center;
      height: 100%;
      white-space: nowrap;
      width: 100%;
      animation: marquee 10s linear infinite;
      .route__container__text {
        position: absolute;
        white-space: nowrap;
        transition-timing-function: linear; 
      }
    }
  }
</style>
复制代码

总结

由于项目时间比较紧,写的比较潦草。对于性能考虑的话还需要进一步优化。抱拳啦

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改