使用vue3实现
<template>
<div ref="parentBoxRef" class="marquee-container">
<span
ref="contentRef"
class="marquee-content marquee"
:style="{ animationDuration: aniDuration }"
>
<span class="msg_item" v-for="(msg, ind) in messageList">
{{ msg }}
</span>
</span>
</div>
</template>
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
interface MarqueeProps {
message: string | string[]
speed?: number
}
const props = defineProps<MarqueeProps>()
const messageList = computed(() => {
if (typeof props.message === 'string') {
return [props.message]
} else {
return props.message
}
})
const contentRef = ref()
const parentBoxRef = ref()
const aniDuration = ref<string>('60s')
onMounted(() => {
const width = contentRef.value.clientWidth
const pWidth = parentBoxRef.value.clientWidth
const minDuration = messageList.value.length * 10
if (width && pWidth) {
let duration = (width / pWidth) * 6
if (duration < 10) {
duration = 10
}
if(minDuration > duration){
duration = minDuration
}
aniDuration.value = `${duration}s`
}
})
</script>
<style scoped>
.msg_item {
margin-left: 40px;
&:nth-of-type(1) {
margin-left: 0;
}
}
.marquee-container {
width: 100%;
overflow: hidden;
white-space: nowrap;
box-sizing: border-box;
}
.marquee {
display: inline-block;
padding-left: 100%; /* 使文本从右侧开始 */
animation: marquee 10s linear infinite;
font-size: 14px;
color: #212121;
}
@keyframes marquee {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-100%);
}
}
/* .marquee-container {
overflow: hidden;
white-space: nowrap;
position: relative;
}
.marquee-content {
display: inline-block;
white-space: nowrap;
position: absolute;
left: 100%;
} */
</style>