关于vue文字公告横向滚动的文章网上已经有很多了,但是对我的项目的需求来说还存在两个问题要解决:
- 是设置文字滚动的平均速度还是设置滚动的总时长?不少文章是设定了文字滚动的总时间而不是平均滚动速度,这样会造成一个问题:文字滚动的速度会和文本内容的长度的关联,文本越长,滚动越快,用户体验不好。
- 在不同的手机端,文字滚动速度不一样,比如安卓手机上滚动的速度比ios的快,这造成用户体验不一致的情况。由于滚动的单位使用的是px,而不同的移动设备分辨率会有差别,如果用同样的滚动数值,肯定会造成速度不一致的情况。
为了解决上述的两个问题,这里采用根据分辨率的大小来设置不同的滚动数值,但是最终用户从视觉感官上来看,又会觉得它们速度是一致的,因为他们的滚动所用的时间是一样的。
<!-- 公告栏组件 -->
<template>
<div class="notice-bar" @click="tipClick">
<div class="notice-bar__icon">
<img src="../assets/images/patient/homepage/">
</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: {
type: String,
default: ''
},
speed: {
type: Number,
default: 50
},
defaultWidth: {
type: Number,
default: 375
}
},
data () {
return {
contentStyle: {
transitionDuration: '0s',
transform: 'translateX(0px)'
},
wrapWidth: 0,
contentWidth: 0,
time: 0,
timer: null,
convertSpeed: 1
}
},
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>
效果
文字滚动效果展示
本文转自 /post/6980259055038136327,如有侵权,请联系删除。