vue实现数据栏无缝滚动实现方式-demo

效果 

 方式一

通过实现两个item 进行循环

<!--* @Author: Jackie* @Date: 2023-08-16 21:27:42* @LastEditTime: 2023-08-16 21:41:51* @LastEditors: Jackie* @Description: scroll  水平滚动 - 效果基本满足需求* @FilePath: /vue3-swiper-demo/src/components/scroll/Scroll12.vue* @version: 
-->
<template><div class="ticker-container"><div class="ticker-viewer"><div class="ticker-scroll"><divclass="ticker-scroll-item":key="index"v-for="(item, index) in items"><span v-if="item">{{ item }} ${{ item }}</span></div></div><div class="ticker-scroll"><divclass="ticker-scroll-item":key="index"v-for="(item, index) in items"><span v-if="item">{{ item }} ${{ item }}</span></div></div></div></div>
</template><script setup>
import { ref, onMounted, onUnmounted } from 'vue';
const items = ref(Array.from({ length: 26 }, (_, index) => index + 1));
</script><style lang="scss" scoped>
.ticker-container {align-items: center;background: linear-gradient(90deg, #86eef1, #bcff2f 138.82%);display: flex;height: 50px;white-space: nowrap;width: 100%;.ticker-viewer {align-items: center;cursor: pointer;display: flex;height: 100%;overflow: hidden;position: relative;width: 100%;.ticker-scroll {animation-delay: 8s;opacity: 0;animation: tickerScroll 240s linear infinite normal;transform: translateX(0);transition: all linear;will-change: transform, opacity;.ticker-scroll-item {display: inline-block;font-size: 18px;line-height: 22px;color: #fff;padding: 0 24px;}}}
}@keyframes tickerScroll {0% {opacity: 1;transform: translateX(0);}to {opacity: 1;transform: translateX(-100%);}
}@keyframes positionScroll {0% {transform: translateX(3.33333333%);}to {transform: translateX(0);}
}
</style>

方式二

通过实现两个item 进行循环

<!--* @Author: Jackie* @Date: 2023-08-16 21:02:42* @LastEditTime: 2023-08-16 21:42:04* @LastEditors: Jackie* @Description: 过渡 - 通过两次滚动实现 flex  - 效果基本满足需求* @FilePath: /vue3-swiper-demo/src/components/scroll/Scroll11.vue* @version: 
-->
<template><div class="scroll"><div class="price-band-group" ref="group"><divclass="price-band-item DIN-medium":key="index"v-for="(item, index) in items"><span v-if="item">{{ item }} ${{ item }}</span></div></div><div class="price-band-group" ref="group"><divclass="price-band-item DIN-medium":key="index"v-for="(item, index) in items"><span v-if="item">{{ item }} ${{ item }}</span></div></div></div>
</template><script setup>
import { ref, onMounted, onUnmounted } from 'vue';const scroller = ref(null);
const group = ref(null);
const timerId = ref(null);
const items = ref(Array.from({ length: 26 }, (_, index) => index + 1));
</script><style lang="scss" scoped>
.scroll {display: flex;overflow: hidden;width: 100%;height: 48px;background: linear-gradient(90deg, #31daff 0.47%, #316bff 100%);padding: 13px 0;box-sizing: border-box;overflow: auto;.price-band-group {display: flex;white-space: nowrap;/* animation: index_loop 100s linear infinite normal;animation-delay: 0.5s; */animation: tickerScroll 240s linear infinite normal;transform: translateX(0);.price-band-item {display: inline-block;font-size: 18px;line-height: 22px;color: #fff;padding: 0 24px;}}&::-webkit-scrollbar {display: none;}
}@keyframes index_loop {0% {transform: translateZ(0);}to {transform: translate3d(-50%, 0, 0);}
}@keyframes tickerScroll {0% {opacity: 1;transform: translateX(0);}to {opacity: 1;transform: translateX(-100%);}
}
</style>

方式三

通过尾部填充重复数据实现

<template><div class="scroll" ref="scroller" :style="style"><div class="price-band-group" v-if="items.length"><divclass="price-band-item DIN-medium"v-for="(item, index) in itemsWithTail":key="index"><span v-if="item !== null"> {{ item }} ${{ item }} </span></div></div></div>
</template><script setup>
import { ref, onMounted, onUnmounted, computed } from 'vue';
const scroller = ref(null);
const timerId = ref(null);
const items = ref(Array.from({ length: 12 }, (_, index) => index + 1));
const pauseAnimate = () => {timerId.value && clearInterval(timerId.value);timerId.value = null;
};
const playAnimate = () => {pauseAnimate();const maxScrollLeft = scroller.value.scrollWidth - scroller.value.clientWidth;console.log(maxScrollLeft);timerId.value = setInterval(() => {if (scroller.value.scrollLeft >= maxScrollLeft) {scroller.value.scrollLeft -= maxScrollLeft;}scroller.value.scrollLeft += 1;}, 33);
};const itemsWithTail = computed(() =>items.value.length >= 10 ? items.value.concat(items.value) : items.value//   items.value.concat(items.value.slice(0, 4))
);onMounted(() => {setTimeout(() => {scroller.value.scrollLeft = 0;playAnimate();}, 100);
});onUnmounted(() => {pauseAnimate();
});
</script><style lang="scss" scoped>
.scroll {width: 100%;height: 48px;background: linear-gradient(90deg, #31daff 0.47%, #316bff 100%);padding: 13px 0;box-sizing: border-box;overflow: hidden;transition: scroll-left 1s ease-in-out; /* 添加过渡效果 */.price-band-group {display: inline-block;white-space: nowrap;.price-band-item {display: inline-block;font-size: 18px;line-height: 22px;color: #fff;padding: 0 24px;}}&::-webkit-scrollbar {display: none;}
}
</style>

方式四

滚动到头后,直接归0

<template><div class="scroll" ref="scroller" :style="style"><div class="price-band-group"><div class="price-band-item DIN-medium" v-for="item in items" :key="item"><span v-if="item"> {{ item }} ${{ item }} </span></div></div></div>
</template><script setup>
import { ref, onMounted, onUnmounted } from 'vue';
const scroller = ref(null);
const timerId = ref(null);
const scrollLeftEnd = ref(false);
const items = ref(Array.from({ length: 22 }, (_, index) => index + 1));
const pauseAnimate = () => {timerId.value && clearInterval(timerId.value);timerId.value = null;
};
const playAnimate = () => {pauseAnimate();const maxScrollLeft = scroller.value.scrollWidth - scroller.value.clientWidth;console.log(maxScrollLeft);timerId.value = setInterval(() => {if (scroller.value.scrollLeft >= maxScrollLeft) {scroller.value.scrollLeft -= maxScrollLeft;}scroller.value.scrollLeft += 1;}, 33);
};onMounted(() => {console.log(111);// 必须在100ms后进行,否则计算不准确setTimeout(() => {scroller.value.scrollLeft = 0;playAnimate();}, 100);
});
onUnmounted(() => {pauseAnimate();
});
</script><style lang="scss" scoped>
.scroll {width: 100%;height: 48px;background: linear-gradient(90deg, #31daff 0.47%, #316bff 100%);padding: 13px 0;box-sizing: border-box;overflow: auto;.price-band-group {display: inline-block;white-space: nowrap;.price-band-item {display: inline-block;font-size: 18px;line-height: 22px;color: #fff;padding: 0 24px;}}&::-webkit-scrollbar {display: none;}
}
</style>

方式五

来回滚动方式

<template><div class="scroll" ref="scroller" :style="style"><div class="price-band-group"><div class="price-band-item DIN-medium" v-for="item in 26" :key="item"><span v-if="item"> {{ item.item }} ${{ item }} </span></div></div></div>
</template><script setup>
import { ref, onMounted, onUnmounted } from 'vue';
const scroller = ref(null);
const timerId = ref(null);
const scrollLeftEnd = ref(false);
const pauseAnimate = () => {timerId.value && clearInterval(timerId.value);timerId.value = null;
};
const playAnimate = () => {pauseAnimate();const maxScrollLeft = scroller.value.scrollWidth - scroller.value.clientWidth;console.log(maxScrollLeft);timerId.value = setInterval(() => {if (scroller.value.scrollLeft >= maxScrollLeft - 1) {scrollLeftEnd.value = true;}if (scroller.value.scrollLeft <= 1) {scrollLeftEnd.value = false;}if (scrollLeftEnd.value) {scroller.value.scrollTo({top: 0,left: (scroller.value.scrollLeft -= 1),behavior: 'smooth'}); //scrollLeft -= 1;} else {scroller.value.scrollTo({top: 0,left: (scroller.value.scrollLeft += 1),behavior: 'smooth'}); //scrollLeft += 1;}}, 33);
};onMounted(() => {console.log(111);// 必须在100ms后进行,否则计算不准确setTimeout(() => {scroller.value.scrollLeft = 0;playAnimate();}, 100);
});
onUnmounted(() => {pauseAnimate();
});
</script><style lang="scss" scoped>
.scroll {width: 100%;height: 48px;background: linear-gradient(90deg, #31daff 0.47%, #316bff 100%);padding: 13px 0;box-sizing: border-box;overflow: auto;.price-band-group {display: inline-block;white-space: nowrap;.price-band-item {display: inline-block;font-size: 18px;line-height: 22px;color: #fff;padding: 0 24px;}}&::-webkit-scrollbar {display: none;}
}
</style>

方式六

scroll滚动 - 循环滚动,不超出不滚动

<!--* @Author: Jackie* @Date: 2023-08-17 10:55:21* @LastEditTime: 2023-08-17 11:39:17* @LastEditors: Jackie* @Description: scroll滚动 - 循环滚动,不超出不滚动* @FilePath: /vue3-swiper-demo/src/components/scroll/Scroll13.vue* @version: 
-->
<template><div class="ticker-container"><div class="ticker-viewer" ref="scrollWiewer"><divclass="ticker-scroll"ref="scrollContainer":class="{ 'scroll-animation': !shouldScroll }":style="{ animationDuration: animationDuration }"><divclass="ticker-scroll-item":key="index"v-for="(item, index) in items"><span v-if="item">{{ item }} ${{ item }}</span></div></div><divclass="ticker-scroll"v-if="shouldScroll":style="{ animationDuration: animationDuration }"><divclass="ticker-scroll-item":key="index"v-for="(item, index) in items"><span v-if="item">{{ item }} ${{ item }}</span></div></div></div></div>
</template><script setup>
import { ref, onMounted, onUnmounted, computed } from 'vue';const items = ref(Array.from({ length: 26 }, (_, index) => index + 1));
const shouldScroll = ref(false);
const scrollContainer = ref(null);
const scrollWiewer = ref(null);// 计算动画持续时间
const animationDuration = computed(() => {const itemCount = items.value.length;// 根据元素数量调整倍数const durationMultiplier = 2; // 调整这个值以适应您的需求return `${itemCount * durationMultiplier}s`;
});onMounted(() => {const wiewerWidth = scrollWiewer.value.offsetWidth;const containerWidth = scrollContainer.value.offsetWidth;const contentWidth = scrollContainer.value.scrollWidth;console.log(containerWidth, wiewerWidth, containerWidth > wiewerWidth);shouldScroll.value = containerWidth > wiewerWidth;
});onUnmounted(() => {shouldScroll.value = false;
});
</script><style lang="scss" scoped>
.ticker-container {align-items: center;background: linear-gradient(90deg, #86eef1, #bcff2f 138.82%);display: flex;height: 50px;white-space: nowrap;width: 100%;.ticker-viewer {align-items: center;cursor: pointer;display: flex;height: 100%;overflow: hidden;position: relative;width: 100%;.ticker-scroll {/* opacity: 0; */transition: all linear;will-change: transform, opacity;/* animation: tickerScroll 20s linear infinite normal; */animation-name: tickerScroll;animation-timing-function: linear;animation-iteration-count: infinite;animation-direction: normal;transform: translateX(0);/* 没有超出不滚动 */&.scroll-animation {animation: none; // stopScroll 1s linear 1 normal;transform: translateX(0);}.ticker-scroll-item {display: inline-block;font-size: 18px;line-height: 22px;color: #fff;padding: 0 24px;}}}
}@keyframes tickerScroll {0% {opacity: 1;transform: translateX(0);}to {opacity: 1;transform: translateX(-100%);}
}@keyframes stopScroll {0% {transform: translateX(0);}
}@keyframes positionScroll {0% {transform: translateX(3.33333333%);}to {transform: translateX(0);}
}
</style>

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

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

相关文章

Linux线程同步与互斥

&#x1f30e;Linux线程同步与互斥 文章目录&#xff1a; Linux线程同步与互斥 Linux线程互斥 线程锁       互斥量Mutex         初始化互斥量的两种方式         申请锁方式         解除与销毁锁 问题解决及线程饥饿       互斥锁的底…

MWD天气图像多分类数据集,用于图像分类总共6个类别,多云,下雨,下雪,雾天,正常天气,共60000张图像数据

MWD天气图像多分类数据集&#xff0c;用于图像分类 总共6个类别&#xff0c;多云&#xff0c;下雨&#xff0c;下雪&#xff0c;雾天&#xff0c;正常天气&#xff0c;共60000张图像数据 MWD天气图像多分类数据集 (Multi-Weather Dataset, MWD) 数据集描述 MWD天气图像多分类…

AcWing算法基础课-790数的三次方根-Java题解

大家好&#xff0c;我是何未来&#xff0c;本篇文章给大家讲解《AcWing算法基础课》790 题——数的三次方根。本题考查算法为浮点数二分查找。本文详细介绍了一个使用二分法计算浮点数三次方根的算法。通过逐步逼近目标值&#xff0c;程序能够在给定的区间内精确计算出结果&…

【Elasticsearch系列廿】Logstash 学习

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

什么是Rspack?

Rspack 是一个基于 Rust 编写的高性能 JavaScript 打包工具&#xff0c;旨在提供与 webpack 生态系统的强兼容性&#xff0c;允许无缝替换 webpack&#xff0c;并提供极快的构建速度。 介绍 - Rspack 它由字节跳动 Web Infra 团队孵化&#xff0c;具有以下特点&#xff1a; 高…

2024年汉字小达人区级自由报名备考冲刺:最新问题和官模题练一练

2024年第十一届汉字小达人的区级活动的时间9月25-30日正式开赛&#xff0c;还有两天就开始比赛。 今天继续回答几个关于汉字小达人的最新问题&#xff0c;做几道2024年官方模拟题&#xff0c;帮助孩子们更精准地备考2024年汉字小达人。 【温馨提示】本专题在比赛期间持续更新…

委托的注册及注销+观察者模式

事件 委托变量如果公开出去&#xff0c;很不安全&#xff0c;外部可以随意调用 所以取消public,封闭它&#xff0c;我们可以自己书写两个方法&#xff0c;供外部注册与注销&#xff0c;委托调用在子方法里调用&#xff0c;这样封装委托变量可以使它更安全&#xff0c;这个就叫…

LLM大模型训练/推理的显卡内存需求计算

无论你是从头开始训练 LLM、对其进行微调还是部署现有模型&#xff0c;选择合适的 GPU 对成本和效率都至关重要。在这篇博客中&#xff0c;我们将详细介绍使用单个和多个 GPU 以及不同的优化器和批处理大小进行 LLM 训练和推理时 GPU 要求的所有信息。 计算机处理器由多个决定…

C/C++逆向:switch语句逆向分析

在逆向分析中&#xff0c;switch语句会被编译器转化为不同的底层实现方式&#xff0c;这取决于编译器优化和具体的场景。常见的实现方式包括以下几种&#xff1a; ①顺序判断&#xff08;if-else链&#xff09;&#xff1a; 编译器将switch语句转化为一系列的if-else语句。这…

管道物体计数系统源码分享

管道物体计数检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

信创背景下中职计算机组装与维护课程教学解决方案

在当前的国际形势下&#xff0c;确保信息化系统的安全性和可靠性显得尤为重要。为了提高信息技术的安全性和可靠性&#xff0c;国家鼓励并支持使用国产的信息技术、工具和资源来替代现有的技术体系。这一过程被称为“安全可信的创新替代”&#xff0c;它已经成为国家安全战略的…

VMware ESXi 8.0U3b macOS Unlocker OEM BIOS 2.7 标准版和厂商定制版

VMware ESXi 8.0U3b macOS Unlocker & OEM BIOS 2.7 标准版和厂商定制版 ESXi 8.0U3 标准版&#xff0c;Dell (戴尔)、HPE (慧与)、Lenovo (联想)、Inspur (浪潮)、Cisco (思科)、Hitachi (日立)、Fujitsu (富士通)、NEC (日电) 定制版、Huawei (华为) OEM 定制版 请访问…

OpenResty安装及使用

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

构建高可用和高防御力的云服务架构第四部分:REDIS(4/5)

本文的目的是深入探讨Redis在构建高可用和高防御力云服务架构中的应用。我们将分析Redis的工作原理、核心特性以及如何通过Redis优化云服务架构的性能和安全性。此外&#xff0c;我们还将提供实际案例和最佳实践&#xff0c;帮助读者更好地理解和应用Redis&#xff0c;以构建更…

中小企业体系技术抽象沉淀-异地灾备篇

IT团队内部使用工具 系列文章&#xff1a;https://blog.csdn.net/caicongyang/article/details/136857045 DDL DML管控 https://github.com/hhyo/Archery/ flyway 文档编写 wiki 技术对外输出文档推荐gitbook 同城双活数据同步方案 总览&#xff1a; vivo 系列文章&#x…

普通程序员如何快速入门AIGC

文章目录 第1阶段&#xff1a;基础知识打牢 (1-2周)第2阶段&#xff1a;深度学习理论与实践 (2-4周)第3阶段&#xff1a;AIGC 生成技术入门 (3-5周)第4阶段&#xff1a;进阶学习和项目实战 (5-8周)第5阶段&#xff1a;保持学习和更新 (持续进行) 要快速入门 AIGC&#xff08;AI…

SPI驱动学习六(SPI_Master驱动程序)

目录 前言一、SPI_Master驱动程序框架1. SPI传输概述1.1 数据组织方式1.2 SPI控制器数据结构 2. SPI传输函数的两种方法2.1 老方法2.2 新方法 二、如何编写SPI_Master驱动程序1. 编写设备树2. 编写驱动程序 三、SPI_Master驱动程序简单示例demo1. 使用老方法编写的SPI Master驱…

Webrtc开发实战系列 - win10+vs2022下编译最新webrtc代码

1. 准备起步 操作系统&#xff1a;windows 10 安装 vs2019/vs2022 安装 win10 sdk 19041 一定勾选 Debugging Tools for Windows 科学上网准备代理工具 磁盘剩余空间至少 30G 推荐用一台干净的机器或者虚拟机来编译WebRTC&#xff0c;安装过python的会出现一些非常棘手…

昂首资本:欧美货币对的交易智慧

在外汇市场的海洋中&#xff0c;昂首资本的投资者们深知&#xff0c;把握欧美货币对的交易时段是获取收益的关键。欧美货币对&#xff0c;即欧元对美元&#xff0c;因其在欧洲和美国市场的活跃交易时段而备受瞩目。这两个时段不仅交易量巨大&#xff0c;而且价格波动剧烈&#…

【隐私计算篇】利用多方安全计算MPC实现VGG16人脸识别隐私推理

1. 背景介绍 本文主要介绍一种利用多方安全计算MPC技术&#xff0c;实现VGG16的人脸识别模型&#xff0c;侧重于模型推理阶段&#xff0c;目前已经公开专利&#xff0c;因此以下内容的分享都是基于公开材料。该分享涉及到最小化多方安全计算(MPC)以及明密文混合计算的思想&…