共计 6472 个字符,预计需要花费 17 分钟才能阅读完成。
需求背景:例如大屏需要显示一周的排班信息、菜单信息、亦或者轮播展示某个部门的员工信息,这时候需要进行跑马灯似的无缝滚动效果
实现方式一
@keyframes ygmove {
to {
transform: translateX(-1700px); // 规定 ygmove 动画是在 x 轴负方向移动 1700px 的距离
}
}
template>
div>
div class="yg-list flex">
div class="yg-content">
div class="yg-content-move flex">
div
class="yg-item flex"
v-for="(ygItem, ygIndex) in ygData"
:key="ygIndex"
>
div class="yg-info flex">
div class="yg-img">
img :src="ygItem.headImg" alt="">
div>
div class="yg-name">{{ygItem.name}}div>
div class="yg-gangwei">{{ygItem.yggangweiEnumValue}}div>
div>
div class="yg-zheng-pic">
img :src="ygItem.zhengshiUrl" alt="">
div>
div>
div>
div>
div>
div>
template>
script>
export default {
data() {
return {
ygData: [
{
headImg: require('../src/assets/zheng-em-man.png'),
zhengshiUrl: 'https://wx2.sinaimg.cn/mw690/005Dg9pggy1hqv02dv5pkj32vo2vokc6.jpg',
name: '动作 1',
yggangweiEnumValue: '保姆'
}, {
headImg: require('../src/assets/zheng-em-man.png'),
zhengshiUrl: 'https://ww2.sinaimg.cn/mw690/005Dg9pggy1hqv02lw9elj33pc3pcb29.jpg',
name: '动作 2',
yggangweiEnumValue: '保姆'
}, {
headImg: require('../src/assets/zheng-em-man.png'),
zhengshiUrl: 'https://wx4.sinaimg.cn/mw690/005Dg9pggy1hqv02i51fej33pc3pce81.jpg',
name: '动作 3',
yggangweiEnumValue: '保姆'
}, {
headImg: require('../src/assets/zheng-em-man.png'),
zhengshiUrl: 'https://ww2.sinaimg.cn/mw690/005Dg9pggy1hqv02lw9elj33pc3pcb29.jpg',
name: '动作 4',
yggangweiEnumValue: '保姆'
}, {
headImg: require('../src/assets/zheng-em-man.png'),
zhengshiUrl: 'https://wx4.sinaimg.cn/mw690/005Dg9pggy1hqv02i51fej33pc3pce81.jpg',
name: '动作 5',
yggangweiEnumValue: '保姆'
}, {
headImg: require('../src/assets/zheng-em-man.png'),
zhengshiUrl: 'https://wx2.sinaimg.cn/mw690/005Dg9pggy1hqv02dv5pkj32vo2vokc6.jpg',
name: '动作 1',
yggangweiEnumValue: '保姆'
}, {
headImg: require('../src/assets/zheng-em-man.png'),
zhengshiUrl: 'https://ww2.sinaimg.cn/mw690/005Dg9pggy1hqv02lw9elj33pc3pcb29.jpg',
name: '动作 2',
yggangweiEnumValue: '保姆'
}
]
}
},
methods: {}
}
script>
style scoped lang="scss">
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
::-webkit-scrollbar {
width: 0 !important;
}
::-webkit-scrollbar {
width: 0 !important;
height: 0;
}
.flex {
display: flex;
}
.yg-list {
padding: 15px;
width: 712px;
height: 180px;
background: linear-gradient(0deg, rgba(0, 115, 255, 0.59) 0%, rgba(0, 140, 255, 0) 100%);
border: 1px solid #5FB2FF;
overflow-x: scroll;
white-space: nowrap;
.yg-content {
width: 1000px;
height: 150px;
overflow: hidden;
.yg-content-move {
// ygmove 动画名
// 10s 动画完成一个周期所花费的秒或毫秒
// infinite 动画被播放的次数
// linear 规定动画的速度曲线
animation: ygmove 10s infinite linear;
}
}
.yg-item {
flex-shrink: 0;
padding: 12px;
margin-right: 20px;
width: 320px;
height: 148px;
border: 1px solid rgba(0, 229, 255, 0.5);
.yg-info {
justify-content: space-between;
flex-direction: column;
align-items: center;
margin-right: 15px;
width: 78px;
height: 124px;
font-size: 14px;
color: #fff;
.yg-img {
width: 78px;
height: 78px;
border-radius: 4px;
box-shadow: 0px 0px 5px 0px #00E5FF;
overflow: hidden;
}
}
.yg-zheng-pic {
width: 203px;
height: 124px;
border-radius: 4px;
overflow: hidden;
img {
width: 100%;
height: 100%;
}
}
}
}
@keyframes ygmove {
to {
transform: translateX(-1700px);
}
}
style>
实现方式二
- 使用 vue-seamless-scroll(推荐)
- 步骤
- 下包
--> npm
npm install vue-seamless-scroll --save
--> yarn
yarn add vue-seamless-scroll
--> cdn
https://cdn.jsdelivr.net/npm/vue-seamless-scroll@latest/dist/vue-seamless-scroll.min.js
- 引入组件
import seamlessScroll from 'vue-seamless-scroll'
Vue.use(seamlessScroll)
- 使用
template>
div>
div class="yg-list flex">
div class="yg-content">
vue-seamless-scroll :data="ygData" class="yg-content" :class-option="defaultOption">
div class="yg-content-move flex">
div
class="yg-item flex"
v-for="(ygItem, ygIndex) in ygData"
:key="ygIndex"
>
div class="yg-info flex">
div class="yg-img">
img :src="ygItem.headImg" alt="">
div>
div class="yg-name">{{ygItem.name}}div>
div class="yg-gangwei">{{ygItem.yggangweiEnumValue}}div>
div>
div class="yg-zheng-pic">
img :src="ygItem.zhengshiUrl" alt="">
div>
div>
div>
vue-seamless-scroll>
div>
div>
div>
template>
script>
export default {
data() {
return {
ygData: [
{
headImg: require('../src/assets/zheng-em-man.png'),
zhengshiUrl: 'https://wx2.sinaimg.cn/mw690/005Dg9pggy1hqv02dv5pkj32vo2vokc6.jpg',
name: '动作 1',
yggangweiEnumValue: '保姆'
}, {
headImg: require('../src/assets/zheng-em-man.png'),
zhengshiUrl: 'https://ww2.sinaimg.cn/mw690/005Dg9pggy1hqv02lw9elj33pc3pcb29.jpg',
name: '动作 2',
yggangweiEnumValue: '保姆'
}, {
headImg: require('../src/assets/zheng-em-man.png'),
zhengshiUrl: 'https://wx4.sinaimg.cn/mw690/005Dg9pggy1hqv02i51fej33pc3pce81.jpg',
name: '动作 3',
yggangweiEnumValue: '保姆'
}, {
headImg: require('../src/assets/zheng-em-man.png'),
zhengshiUrl: 'https://ww2.sinaimg.cn/mw690/005Dg9pggy1hqv02lw9elj33pc3pcb29.jpg',
name: '动作 4',
yggangweiEnumValue: '保姆'
}, {
headImg: require('../src/assets/zheng-em-man.png'),
zhengshiUrl: 'https://wx4.sinaimg.cn/mw690/005Dg9pggy1hqv02i51fej33pc3pce81.jpg',
name: '动作 5',
yggangweiEnumValue: '保姆'
}, {
headImg: require('../src/assets/zheng-em-man.png'),
zhengshiUrl: 'https://wx2.sinaimg.cn/mw690/005Dg9pggy1hqv02dv5pkj32vo2vokc6.jpg',
name: '动作 1',
yggangweiEnumValue: '保姆'
}, {
headImg: require('../src/assets/zheng-em-man.png'),
zhengshiUrl: 'https://ww2.sinaimg.cn/mw690/005Dg9pggy1hqv02lw9elj33pc3pcb29.jpg',
name: '动作 2',
yggangweiEnumValue: '保姆'
}
],
}
},
computed: {
defaultOption () {
return {
step: 10,
limitMoveNum: this.ygData.length,
hoverStop: true,
direction: 2,
openWatch: true,
singleHeight: 0,
singleWidth: 0,
waitTime: 1000,
delay: 0
}
}
}
}
script>
style scoped lang="scss">
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
::-webkit-scrollbar {
width: 0 !important;
}
::-webkit-scrollbar {
width: 0 !important;
height: 0;
}
.flex {
display: flex;
}
.yg-list {
padding: 15px;
width: 712px;
height: 180px;
background: linear-gradient(0deg, rgba(0, 115, 255, 0.59) 0%, rgba(0, 140, 255, 0) 100%);
border: 1px solid #5FB2FF;
overflow-x: scroll;
white-space: nowrap;
.yg-content {
width: 1000px;
height: 150px;
overflow: hidden;
.yg-content-move {
// animation: ygmove 5s infinite ease-in;
}
}
.yg-item {
flex-shrink: 0;
padding: 12px;
margin-right: 20px;
width: 320px;
height: 148px;
// background-color: orange;
border: 1px solid rgba(0, 229, 255, 0.5);
.yg-info {
justify-content: space-between;
flex-direction: column;
align-items: center;
margin-right: 15px;
width: 78px;
height: 124px;
font-size: 14px;
color: #fff;
.yg-img {
width: 78px;
height: 78px;
border-radius: 4px;
box-shadow: 0px 0px 5px 0px #00E5FF;
overflow: hidden;
}
}
.yg-zheng-pic {
width: 203px;
height: 124px;
border-radius: 4px;
overflow: hidden;
img {
width: 100%;
height: 100%;
}
}
}
}
// @keyframes ygmove {
// to {
// transform: translateX(-1700px);
// }
// }
// .yg-content:hover .yg-content-move {
// animation-play-state: paused;
// }
style>
两者的比较
通过 css 的方式不太灵活,第一种方法适用于轮播数量已知的情况下,存在以下问题
- 它需要根据滚动窗口大小对滚动数据追加相应的前几条数据方便实现无缝效果,例如滚动窗口可以看到两个滚动卡片,一共五个卡片,当五个卡片滚动完一次后会出现滚动窗口留白的情况,因为滚动窗口可以看到两个卡片,需要将前两个卡片数据追加到数据末尾来填充留白问题
- 而且在数据不确定的情况下,动画时间也需要进行相应设置例如数据有五条,动画设置 5s 完成就行,当数据变成 10 条时,动画完成时间还是 5s,造成速度是之前的二倍
尽管可以根据数据量不同来操作 dom 设置这些数据,但还是相对麻烦的,而相比来说第二种方式可以动态设置数据量以及速度,避免了之前的问题
原文地址: vue 大屏轮播(跑马灯)实现思路
正文完