方式一:利用元素尺寸变化监听api,计算宽度,得出时间,进行无限次数动画。
优点:能自定义速度(0 - 1)。
<template>
<div class="box">
<i class="iconfont icon-gonggao"></i>
<div class="marquee-box">
<div ref="elRef" class="marquee">
<slot></slot>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
const props = defineProps({
speed: {
type: Number,
default: 0.1
},
})
const elRef = ref()
onMounted(() => {
marquee(elRef.value, props.speed)
})
function marquee(el: HTMLElement, speed: number = 0.1) {
const startMarquee = () => {
const parentWidth = parseInt(window.getComputedStyle(el?.parentNode).width)
const allWidth = window.innerWidth + parseInt(window.getComputedStyle(el).width)
const _speed = speed >= 1 ? 0.99 : speed <= 0 ? 0.01 : speed;
const time = allWidth * 30000 / 1920 * (1 - _speed);
el.animate([
{ transform: `translateX(${parentWidth}px)` },
{ transform: `translateX(-100%)`}
], {
duration: time,
easing: 'linear',
iterations: Infinity,
})
}
const ro= new ResizeObserver((entries, observer) => {
startMarquee()
});
ro.observe(el);
}
</script>
<style lang="less" scoped>
.box{
display: flex;
align-items: center;
padding: 1.875rem 0 1.875rem 1rem;
background-color: #FFF8EE;
color: #FC7D3C;
font-size: 18px;
.marquee-box{
flex: 1;
min-width: 0px;
margin-left: .2rem;
overflow: hidden;
}
.marquee{
display: inline-block;
white-space:nowrap;
}
.iconfont{
font-size: 1.875rem;
line-height: 1;
}
}
.h5{
.box{
padding: .5rem 0;
font-size: 0.875rem;
}
.iconfont{
font-size: 1.2rem;
}
}
</style>
方式二:利用原生跑马灯标签,简单。
缺点:不能定义速度。
<template>
<div class="box">
<i class="iconfont icon-gonggao"></i>
<marquee bgcolor= "#FFF8EE">
<slot></slot>
</marquee>
</div>
</template>
<style lang="less" scoped>
.box{
display: flex;
align-items: center;
padding: 1.875rem 0 1.875rem 1rem;
background-color: #FFF8EE;
color: #FC7D3C;
font-size: 18px;
.iconfont{
font-size: 1.875rem;
line-height: 1;
}
}
.h5{
.box{
padding: .5rem 0;
font-size: 0.875rem;
}
.iconfont{
font-size: 1.2rem;
}
}
</style>