vue3 + css 列表无限循环滚动+鼠标移入停止滚动+移出继续滚动

news2025/3/19 23:35:12

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) { /* Firefox */
        elem.mozRequestFullScreen();
    } else if (elem.webkitRequestFullscreen) { /* Chrome, Safari & Opera */
        elem.webkitRequestFullscreen();
    } else if (elem.msRequestFullscreen) { /* IE/Edge */
        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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2318031.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AndroidStudio下载安装,环境部署以及常见问题解决教程(亲测)

AndroidStudio下载安装&#xff0c;环境部署以及常见问题解决&#xff01;&#xff01;&#xff01; 文章目录 前言 一、Android Studio 下载与安装 1.1 系统要求 1.2 下载 Android Studio 1.3 安装 Android Studio Windows 系统 1.4 初始配置 二、环境部署 2.1 安装 …

开源免费一句话生成儿童故事视频核心思想解析

再看一个演示视频&#xff0c;学会核心思想后&#xff0c;可以打造自己的内容生成工具&#xff0c;后文有基于飞书多维表格的实现效果&#xff1a; 一句话灵感生成儿童故事视频演示 这是一款专门为内容素材创作打造的创新工具&#xff0c;可根据用户输入的主题&#xff0c;快速…

数据结构——最短路(BFS,Dijkstra,Floyd)

完整版可以看我的最短路问题模版总结_稠密图最短路-CSDN博客 考研数据结构只考BFS,Dijkstra和Floyd 下面代码以Acwing模板题为例 BFS代码 适用类型&#xff1a; 1.单源最短路径 2.无权图 3.不适用于带权图和负权回路图 //Acwing走迷宫bfs #include<bits/stdc.h>usi…

Kali Linux汉化教程:轻松设置中文界面

1.打开终端 2.输入sudo dpkg-reconfigure locales&#xff0c;回车&#xff0c;输入密码&#xff0c;回车 sudo dpkg-reconfigure locales 3.往下滑&#xff0c;滑到底&#xff0c;找到‘zh_CN.UTF-8 UTF-8’,回车 4.选择‘zh_CN.UTF-8’,回车 5.没有 ‘zh_CN.UTF-8’选项的特…

C++和标准库速成(八)——指针、动态数组、const、constexpr和consteval

目录 1. 指针和动态数组1.1 栈和自由存储区1.2 使用指针1.3 动态分配的数组1.4 空指针常量 2. const2.1 const修饰类型2.2 const与指针2.3 使用const保护参数2.4 const方法(建议&#xff09; 3. constexpr4. consteval参考 1. 指针和动态数组 动态内存允许所创建的程序具有在编…

超声重建,3D重建 超声三维重建,三维可视化平台 UR 3D Reconstruction

1. 超声波3D重建技术的实现方法与算法 技术概述 3D超声重建是一种基于2D超声图像生成3D体积数据的技术&#xff0c;广泛应用于医学影像领域。通过重建和可视化三维结构&#xff0c;3D超声能够显著提高诊断精度和效率&#xff0c;同时减少医生的脑力负担。本技术文档将详细阐述…

[HelloCTF]PHPinclude-labs超详细WP-Level 6Level 7Level 8Level 9-php://协议

由于Level 6-9 关的原理都是通用的, 这里就拿第6关举例, 其他的关卡同理 源码分析 定位到代码 isset($_GET[wrappers]) ? include("php://".$_GET[wrappers]) : ; 与前几关发生变化的就是 php:// 解题分析 这一关要求我们使用 php协议 php:// 协议 php://filte…

【Linux】Bash是什么?怎么使用?

李升伟 整理 什么是 Bash&#xff1f; Bash&#xff08;Bourne Again Shell&#xff09;是一种 命令行解释器&#xff08;Shell&#xff09;&#xff0c;广泛用于 Unix 和 Linux 操作系统。它是 Bourne Shell&#xff08;sh&#xff09; 的增强版&#xff0c;提供了更多的功能…

如何创建并保存HTML文件?零基础入门教程

原文&#xff1a;如何创建并保存HTML文件&#xff1f;零基础入门教程 | w3cschool笔记 本文将以Windows系统为例&#xff0c;教你用最简单的记事本创建并保存第一个HTML网页。 &#x1f4dd; 第一步&#xff1a;准备工具 文本编辑器&#xff1a;使用系统自带的记事本&#xff…

React19源码系列之FiberRoot节点和Fiber节点

在上一篇文章&#xff0c;看了createRoot函数的大致流程。 createContainer函数创建并返回了FiberRoot 。FiberRoot是由createFiberRoot函数创建&#xff0c; createFiberRoot函数还将 FiberRoot和 根Fiber 通过current属性建立起了联系。将FiberRoot作为参数传给 ReactDOMRoo…

TCP协议的多线程应用、多线程下的网络编程

DAY13.2 Java核心基础 多线程下的网络编程 基于单点连接的方式&#xff0c;一个服务端对应一个客户端&#xff0c;实际运行环境中是一个服务端需要对应多个客户端 创建ServerSocketNable类&#xff0c;多线程接收socket对象 public class ServerSocketNable implements Run…

华为中小型企业项目案例

实验目的(1) 熟悉华为交换机和路由器的应用场景 (2) 掌握华为交换机和路由器的配置方法 实验拓扑实验拓扑如图所示。 华为中小型企业项目案例拓扑图 实验配置市场部和技术部的配置创建VLANLSW1的配置 [LSW1]vlan batch 10 20 [LSW1]q…

LabVIEW VI Scripting随机数波形图自动生成

通过LabVIEW VI Scripting 技术&#xff0c;实现从零开始编程化创建并运行一个随机数波形监测VI。核心功能包括自动化生成VI框架、添加控件与函数、配置数据流逻辑及界面布局优化&#xff0c;适用于批量生成测试工具、教学模板开发或复杂系统的模块化构建。通过脚本化操作&…

MATLAB 控制系统设计与仿真 - 26

状态空间控制系统概述 状态空间描述 现代控制理论是建立在状态空间基础上的控制系统分析和设计理论&#xff0c;它用状态变量来刻画系统的内部特征&#xff0c;用‘一节微分方程组’来描述系统的动态特性。系统的状态空间模型描述了系统输入/输出与内部状态之间的关系&#x…

Python----计算机视觉处理(Opencv:图像镜像旋转)

一、图像镜像旋转 图像的旋转是围绕一个特定点进行的&#xff0c;而图像的镜像旋转则是围绕坐标轴进行的。图像镜像旋转&#xff0c;也可 以叫做图像翻转&#xff0c;分为水平翻转、垂直翻转、水平垂直翻转三种。 通俗的理解为&#xff0c;当以图片的中垂线为x轴和y轴时&#x…

C++从入门到入土(八)——多态的原理

目录 前言 多态的原理 动态绑定与静态绑定 虚函数表 小结 前言 在前面的文章中&#xff0c;我们介绍了C三大特性之一的多态&#xff0c;我们主要介绍了多态的构成条件&#xff0c;但是对于多态的原理我们探讨的是不够深入的&#xff0c;下面这这一篇文章&#xff0c;我们将…

PyCharm安装redis,python安装redis,PyCharm使用失败问题

报错信息 Usage: D:\wb2\wbrj_pys\venv\Scripts\python.exe -m pip install [options] [package-index-options] … D:\wb2\wbrj_pys\venv\Scripts\python.exe -m pip install [options] -r [package-index-options] … D:\wb2\wbrj_pys\venv\Scripts\python.exe -m pip instal…

保姆级离线TiDB V8+解释

以前学习的时候还是3版本&#xff0c;如今已经是8版本了 https://cn.pingcap.com/product-community/?_gl1ujh2l9_gcl_auMTI3MTI3NTM3NC4xNzM5MjU3ODE2_gaMTYwNzE2NTI4OC4xNzMzOTA1MjUz_ga_3JVXJ41175MTc0MTk1NTc1OC4xMS4xLjE3NDE5NTU3NjIuNTYuMC41NDk4MTMxNTM._ga_CPG2VW1Y4…

PyTorch 深度学习实战(17):Asynchronous Advantage Actor-Critic (A3C) 算法与并行训练

在上一篇文章中&#xff0c;我们深入探讨了 Soft Actor-Critic (SAC) 算法及其在平衡探索与利用方面的优势。本文将介绍强化学习领域的重要里程碑——Asynchronous Advantage Actor-Critic (A3C) 算法&#xff0c;并展示如何利用 PyTorch 实现并行化训练来加速学习过程。 一、A…

Docker换源加速(更换镜像源)详细教程(2025.3最新可用镜像,全网最详细)

文章目录 前言可用镜像源汇总换源方法1-临时换源换源方法2-永久换源&#xff08;推荐&#xff09;常见问题及对应解决方案1.换源后&#xff0c;可以成功pull&#xff0c;但是search会出错 补充1.如何测试镜像源是否可用2.Docker内的Linux换源教程 换源速通版&#xff08;可以直…