vue文字跑马灯
<script setup>
import { nextTick, onBeforeUnmount, onMounted, ref } from "vue"
const props = defineProps(['lists'])
const text = ref("")
const textCopy = ref("")
const timmer = ref(null)
const maxWidth = ref(0)
const textWidth = ref(0)
const distance = ref(0)
const marquee = ref(null)
const calcute = () => {
maxWidth.value = document.querySelector('.marquee-wrap').clientWidth
textWidth.value = document.querySelector('.getWidth').scrollWidth
distance.value = 0
if (textWidth.value <= maxWidth.value) {
textCopy.value = ""
return
}
textCopy.value = text.value
tMove()
}
const tMove = () => {
distance.value -= 1
if (-distance.value >= textWidth.value) {
distance.value = 0
cancelAnimationFrame(timmer.value)
text.value = props.lists.join(' ')
nextTick(() => calcute())
} else {
timmer.value = requestAnimationFrame(tMove)
}
marquee.value.style.transform = 'translateX(' + distance.value + 'px)'
}
onMounted(() => {
text.value = props.lists.join(' ')
nextTick(() => calcute())
})
onBeforeUnmount(() => {
cancelAnimationFrame(timmer.value)
})
</script>
<template>
<div class="marquee-wrap">
<!-- 滚动内容 -->
<div class="marqueeScroll" ref="marquee">
<p class="marquee">{{ text }}</p>
<!-- 文字副本 -->
<p class="marqueeCopy">{{ textCopy }}</p>
</div>
<!-- 为了计算总文本宽度,通过css在页面中隐藏 -->
<p class="getWidth">{{ text }}</p>
</div>
</template>
<style scoped>
.marquee-wrap {
width: 100%;
overflow: hidden;
position: relative;
}
.marqueeScroll {
display: flex;
}
.marqueeScroll p {
word-break: keep-all;
white-space: nowrap;
text-indent: 1em;
}
.marquee {
margin-right: 0px;
}
.getWidth {
word-break: keep-all;
white-space: nowrap;
position: absolute;
opacity: 0;
top: 0;
}
</style>