1.动画文件.vue
< template>
< div class = "dashboard" @click= "setFullScreen" >
< div class = "warp-box" >
< el- scrollbar ref= "scrollRef" height= "100%" @scroll= "handelScroll" >
< div class = "animation-box" @mouseover= "stopAnim" @mouseout= "runAnim" v- if = "arrList.length"
: style= "{ animationDuration: animationDuration }" : class = "{ stopPlay: animationStopPlay }" >
< div class = "line-item" v- for = "(item, index) in arrList" : key= "index" >
< img class = "item-bg" src= "../../assets/images/dashboard/line-bg.png" / >
< div class = "item-warp" >
< div class = "item-number" >
< template v- if = "index <= 2" >
< img : class = "`icon-img img-${index}`" : src= "imgArr[index]" / >
< / template>
< template v- else > < div class = "text" > { { index } } < / div> < / template>
< / div>
< div class = "item-avatar" >
< avatarImg : avatar= "item.avatar" / >
< / div>
< div class = "item-nickname" > { { item. nickname } } < / div>
< div class = "item-point" > { { item. point } } < / div>
< / div>
< / div>
< ! -- 重复一次 实现无逢滚动 -- >
< div class = "line-item" v- for = "(item, index) in arrList" : key= "index" >
< img class = "item-bg" src= "../../assets/images/dashboard/line-bg.png" / >
< div class = "item-warp" >
< div class = "item-number" >
< template v- if = "index <= 2" >
< img : class = "`icon-img img-${index}`" : src= "imgArr[index]" / >
< / template>
< template v- else > < div class = "text" > { { index } } < / div> < / template>
< / div>
< div class = "item-avatar" >
< avatarImg : avatar= "item.avatar" / >
< / div>
< div class = "item-nickname" > { { item. nickname } } < / div>
< div class = "item-point" > { { item. point } } < / div>
< / div>
< / div>
< / div>
< / el- scrollbar>
< / div>
< / div>
< / template>
< script setup>
import p0 from '../../assets/images/dashboard/icon_0.png?v=1'
import p1 from '../../assets/images/dashboard/icon_1.png?v=1'
import p2 from '../../assets/images/dashboard/icon_2.png?v=1'
import avatarImg from './avatarImg.vue'
import { nextTick, onMounted, ref, onUnmounted, reactive } from 'vue' ;
const animationDuration = ref ( null ) ;
const animationStopPlay = ref ( false ) ;
const imgArr = reactive ( [ p0, p1, p2] ) ;
const scrollRef = ref ( null ) ;
const isLoading = ref ( false ) ;
const arrList = ref ( [
{
nickname : '昵称昵称昵称昵称' ,
avatar : "" ,
point : 5000 ,
}
] ) ;
const search = reactive ( {
page : 1 , limit : 20
} ) ;
onMounted ( ( ) => {
nextTick ( ( ) => {
setTimeout ( ( ) => {
setFullScreen ( ) ;
} , 3000 )
loadList ( ) ;
} )
} ) ;
const handelScroll = ( event ) => {
const wrapRef = scrollRef. value. wrapRef;
let poor = wrapRef. scrollHeight - wrapRef. clientHeight;
if ( event. scrollTop + 20 >= poor) {
loadList ( ) ;
}
}
const loadList = ( ) => {
console. log ( '加载更多数据...' )
if ( isLoading. value) return ;
isLoading. value = true ;
for ( let i = 0 ; i < 30 ; i++ ) {
arrList. value. push ( {
nickname : '昵称昵称昵称昵称' ,
avatar : "https://pic.qqans.com/up/2024-6/17183287196520597.jpg" ,
point : 5000 ,
} )
}
if ( arrList. value. length <= 2 ) {
animationStopPlay. value = true
animationDuration. value = 2 + 's'
} else {
animationStopPlay. value = false
animationDuration. value = arrList. value. length * 2 + 's'
}
isLoading. value = false ;
}
const setFullScreen = ( ) => {
const elem = document. getElementById ( 'app' ) ;
if ( elem. requestFullscreen) {
elem. requestFullscreen ( ) ;
} else if ( elem. mozRequestFullScreen) {
elem. mozRequestFullScreen ( ) ;
} else if ( elem. webkitRequestFullscreen) {
elem. webkitRequestFullscreen ( ) ;
} else if ( elem. msRequestFullscreen) {
elem. msRequestFullscreen ( ) ;
}
}
const stopAnim = ( ) => {
animationStopPlay. value = true
}
const runAnim = ( ) => {
if ( arrList. value. length > 2 ) {
animationStopPlay. value = false
}
}
< / script>
< style lang= "scss" scoped>
. dashboard {
display : flex;
justify- content: center;
align- items: center;
height : 100 % ;
background- image: url ( "../../assets/images/dashboard/bg-2.png" ) ;
background- size: cover;
}
. warp- box {
width : 46 % ; height: 65 % ;
margin : 9.5 % 0 0 36.5 % ;
padding : 10px 0 10px 10px;
}
. line- item{
width : 100 % ; position: relative; cursor: pointer;
font- family: XiangCuiDaZiJi35;
. item- bg{
width : 100 % ; height: auto; display: block;
}
. item- warp{
width : 100 % ; height: 100 % ; box- sizing: border- box; position: absolute; top: 0 ; left: 0 ;
display : flex; justify- content: flex- start; align- items: center;
}
}
. item- number{
text- align: center; width: 16 % ; height: 100 % ;
color : #96795c;
. icon- img{
margin : 16 % 0 0 28 % ;
width : 60px; height: auto; display: block;
}
. text{
font- size: 36px; margin: 22 % 0 0 0 ;
}
}
. item- avatar{
margin- left: 3 % ; width: 13 % ; height: 80 % ;
}
. item- nickname{
width : 44 % ;
font- size: 40px; color: #b99871;
}
. item- point{
width : 22 % ;
font- size: 28px; color: #ffffff; text- align: center;
}
. animation- box{
animation- name: carousel;
animation- timing- function : linear;
animation- iteration- count: infinite;
animation- delay: 0s;
animation- direction: normal;
& . stopPlay{
animation- play- state: paused;
}
}
@keyframes carousel {
0 % {
transform : translateY ( 0 % )
}
100 % {
transform : translateY ( - 50 % )
}
}
< / style>
2.组件avatarImg.vue(内容显示)与动画无关
< template>
< div class = "image-box" >
< img class = "avatar-img" : src= "!avatar ? avatarBg : avatar" / >
< img class = "avatar-border" src= "../../assets/images/dashboard/avatar-border.png" / >
< / div>
< / template>
< script setup>
import avatarBg from '../../assets/images/dashboard/avatar-bg.png?v=1'
import { defineProps } from 'vue' ;
defineProps ( {
avatar : {
typeof : String,
default : ( ) => {
return avatarBg;
}
}
} )
< / script>
< style lang= "scss" scoped>
. image- box{
position : relative;
. avatar- img{
width : 80px; height: 80px; display: block;
transform : rotate ( - 3deg) ;
position : absolute; top: 4px; left: 3px;
}
. avatar- border{
width : 90px; height: 90px; display: block;
position : absolute; top: 0 ; left: 0 ;
}
}
< / style>