vue文字公告自动横向循环滚动

vue文字公告自动横向循环滚动

关于vue文字公告横向滚动的文章网上已经有很多了,但是对我的项目的需求来说还存在两个问题要解决:

  1. 是设置文字滚动的平均速度还是设置滚动的总时长?不少文章是设定了文字滚动的总时间而不是平均滚动速度,这样会造成一个问题:文字滚动的速度会和文本内容的长度的关联,文本越长,滚动越快,用户体验不好。
  2. 在不同的手机端,文字滚动速度不一样,比如安卓手机上滚动的速度比ios的快,这造成用户体验不一致的情况。由于滚动的单位使用的是px,而不同的移动设备分辨率会有差别,如果用同样的滚动数值,肯定会造成速度不一致的情况。

为了解决上述的两个问题,这里采用根据分辨率的大小来设置不同的滚动数值,但是最终用户从视觉感官上来看,又会觉得它们速度是一致的,因为他们的滚动所用的时间是一样的。

<!-- 公告栏组件 -->
<template>
  <div class="notice-bar" @click="tipClick">
    <div class="notice-bar__icon">
      <img src="../assets/images/patient/homepage/tip.png">
    </div>
    <div ref="wrap" class="notice-bar__wrap">
      <div ref="content" class="notice-bar__content" :style="contentStyle">{{ text }}</div>
    </div>
  </div>
</template>

<script>
export default {
  name'NoticeBar',
  props: {
    text: {
      typeString,
      default''
    },
    speed: {
      typeNumber,
      default50
    },
    defaultWidth: {
      typeNumber,
      default375
    }
  },
  data () {
    return {
      contentStyle: {
        transitionDuration'0s',
        transform'translateX(0px)'
      },
      wrapWidth0,
      contentWidth0,
      time0,
      timernull,
      convertSpeed1
    }
  },
  created () {},
  mounted () {
    if (this.text) {
      this.init()
    }
  },
  watch: {
    text (val) {
      this.init()
    }
  },
  methods: {
    init () {
      const _width = window.innerWidth
      this.convertSpeed = _width / this.defaultWidth * this.speed  // 根据分辨率转化成不同的速度
      this.wrapWidth = this.$refs.wrap.offsetWidth
      this.contentWidth = this.$refs.content.offsetWidth
      this.startAnimate()
      this.timer = setInterval(() => {
        this.startAnimate()
      }, this.time * 1000)
      this.$once('hook:beforeDestroy', () => {
        clearInterval(this.timer)
        this.timer = null
      })
    },
    startAnimate () {
      this.contentStyle.transitionDuration = '0s'
      this.contentStyle.transform = 'translateX(' + this.wrapWidth + 'px)'
      this.time = (this.wrapWidth + this.contentWidth) / this.convertSpeed
      setTimeout(() => {
        this.contentStyle.transitionDuration = this.time + 's'
        this.contentStyle.transform = 'translateX(-' + this.contentWidth + 'px)'
      }, 200)
    },
    tipClick () {
      this.$emit('click')
    }
  }
}
</script>
<style scoped lang='less'>
    .notice-bar {
      position: relative;
      width: 100%;
      .px2rem(height, 80);
      .px2rem(padding-left, 0);
      .px2rem(padding-right, 0);
      .px2rem(font-size, 28);
      font-family: PingFangSC-Regular, PingFang SC;
      font-weight: 400;
      color: #868DAA;
      display: flex;
      align-items: center;
      .notice-bar__icon {
        .px2rem(width, 56);
        .px2rem(height, 28);
        .px2rem(margin-right, 20);
        img {
          width: 100%;
        }
      }
      .notice-bar__wrap {
        position: relative;
        display: flex;
        flex: 1;
        height: 100%;
        align-items: center;
        overflow: hidden;
        .notice-bar__content {
          position: absolute;
          white-space: nowrap;
          transition-timing-function: linear;
        }
      }
    }
</style>

组件调用:

<template>
 <div>
        ...
        <notice-bar v-if="notice" :text="notice" @click="openTip" />
        ...
    </div>  
</template>
<script>
 import NoticeBar from '@/components/NoticeBar'
    export default {
        components: {
            NoticeBar
        },
         data () {
            return {
         notice''
            }
         },
        methods: {
            openTip () {}
  }
    }
</script>

文章出自:https://juejin.cn/post/6980259055038136327

作者:渔获飞


原文始发于微信公众号(前端24):vue文字公告自动横向循环滚动

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/216477.html

(0)
李, 若俞的头像李, 若俞

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!