Vue3文字实现左右和上下滚动

可自定义设置以下属性:

滚动文字数组(sliderText),类型:Array<{title: string, link?: string}>,必传,默认[]

滚动区域宽度(width),类型:number | string,默认 ‘100%’

滚动区域高度(height),类型:number,单位px,默认 60

滚动区域背景色(backgroundColor),类型:string,默认 ‘#FFF’

滚动区域展示条数,水平滚动时生效(amount),类型:number,默认 4

水平滚动文字各列间距或垂直滚动文字两边的边距(gap),类型:number,单位px,默认 20

是否垂直滚动(vertical),类型:boolean,默认 false

文字滚动时间间隔,垂直滚动时生效(interval),类型:number,单位ms,默认 3000

详见:描述

1:创建文字滚动组件TextScroll.vue:

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { requestAnimationFrame, cancelAnimationFrame, rafTimeout, cancelRaf } from '../index'
interface Text {title: string // 文字标题link?: string // 跳转链接
}
interface Props {sliderText: Text[] // 滚动文字数组width?: number|string // 滚动区域宽度,单位pxheight?: number // 滚动区域高度,单位pxbackgroundColor?: string // 滚动区域背景色amount?: number // 滚动区域展示条数,水平滚动时生效gap?: number // 水平滚动文字各列间距或垂直滚动文字两边的边距,单位pxvertical?: boolean // 是否垂直滚动interval?: number // 文字滚动时间间隔,单位ms,垂直滚动时生效
}
const props = withDefaults(defineProps<Props>(), {sliderText: () => [],width: '100%',height: 60,backgroundColor:  '#FFF',amount: 4,gap: 20,vertical: false,interval: 3000,
})
// horizon
const left = ref(0)
const fpsRaf = ref(0) // fps回调标识
const moveRaf = ref() // 一个 long 整数,请求 ID ,是回调列表中唯一的标识。是个非零值,没别的意义
const fps = ref(60)
const textData = ref<Text[]>([...props.sliderText])
const horizonRef = ref()
const distance = ref(0) // 每条滚动文字移动距离const step = computed(() => { // 移动参数(120fps: 0.5, 60fps: 1)if (fps.value === 60) {return 1} else {return 60 / fps.value}
})
function getFPS () { // 获取屏幕刷新率// @ts-ignoreconst requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFramevar start: any = nullfunction timeElapse (timestamp: number) {/*timestamp参数:与performance.now()的返回值相同,它表示requestAnimationFrame() 开始去执行回调函数的时刻*/if (!start) {if (fpsRaf.value > 10) {start = timestamp}fpsRaf.value = requestAnimationFrame(timeElapse)} else {fps.value = Math.floor(1000 / (timestamp - start))console.log('fps', fps.value)distance.value = getDistance() // 获取每列文字宽度onStart() // 开始滚动}}fpsRaf.value = requestAnimationFrame(timeElapse)
}
function getDistance ():number {return parseFloat((horizonRef.value.offsetWidth / props.amount).toFixed(2))
}
function moveLeft () {if (left.value >= distance.value) {textData.value.push(textData.value.shift() as Text) // 将第一条数据放到最后left.value = 0} else {left.value += step.value // 每次移动step(px)}moveRaf.value = requestAnimationFrame(moveLeft)
}const totalWidth = computed(() => { // 文字滚动区域总宽度if (typeof props.width === 'number') {return props.width + 'px'} else {return props.width}
})
const len = computed(() => {return props.sliderText.length
})
onMounted(() => {if (props.vertical) {onStart() // 启动垂直滚动} else {getFPS()}
})
function onStart () {if (props.vertical) {if (len.value > 1) {startMove() // 开始滚动}} else {if (textData.value.length > props.amount) { // 超过amount条开始滚动moveRaf.value = requestAnimationFrame(moveLeft) // 开始动画}}
}
function onStop () {if (props.vertical) {if (len.value > 1) {cancelRaf(timer)}} else {cancelAnimationFrame(moveRaf.value) // 暂停动画}
}
const emit = defineEmits(['click'])
function onClick (title: string) { // 通知父组件点击的标题emit('click', title)
}// vertical
const actIndex = ref(0)
var timer: any = nullfunction startMove () {timer = rafTimeout(() => {if (actIndex.value === len.value - 1) {actIndex.value = 0} else {actIndex.value++}startMove()}, props.interval)
}
</script>
<template><div v-if="!vertical" class="m-slider-horizon" @mouseenter="onStop" @mouseleave="onStart" ref="horizonRef" :style="`height: ${height}px; width: ${totalWidth}; background: ${backgroundColor};`"><a:style="`will-change: transform; transform: translateX(${-left}px); width: ${distance - gap}px; margin-left: ${gap}px;`"class="u-slide-title"v-for="(text, index) in textData":key="index":title="text.title":href="text.link ? text.link:'javascript:;'":target="text.link ? '_blank':'_self'"@click="onClick(text.title)">{{ text.title || '--' }}</a></div><div v-else class="m-slider-vertical" @mouseenter="onStop" @mouseleave="onStart" :style="`height: ${height}px; width: ${totalWidth}; background: ${backgroundColor};`"><TransitionGroup name="slide"><divclass="m-slider":style="`width: calc(${totalWidth} - ${2*gap}px); height: ${height}px;`"v-for="(text, index) in sliderText":key="index"v-show="actIndex===index"><aclass="u-slider":title="text.title":href="text.link ? text.link:'javascript:;'":target="text.link ? '_blank':'_self'"@click="onClick(text.title)">{{ text.title }}</a></div></TransitionGroup></div>
</template>
<style lang="less" scoped>
// 水平滚动
.m-slider-horizon {box-shadow: 0px 0px 5px #D3D3D3;border-radius: 6px;white-space: nowrap;overflow: hidden;text-align: center; // 水平居中&:after { // 垂直居中content: '';height: 100%;display: inline-block;vertical-align: middle;}.u-slide-title {display: inline-block;vertical-align: middle;font-size: 16px;color: #333;font-weight: 400;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;cursor: pointer;&:hover {color: @themeColor;}}
}// 垂直滚动
.slide-enter-active, .slide-leave-active {transition: all 1s ease;
}
.slide-enter-from {transform: translateY(50px) scale(0.6);opacity: 0;
}
.slide-leave-to {transform: translateY(-50px) scale(0.6);opacity: 0;
}
.m-slider-vertical {position: relative;overflow: hidden;border-radius: 6px;.m-slider {position: absolute;left: 0;right: 0;margin: 0 auto;text-align: center; // 水平居中&:after { // 垂直居中content: '';height: 100%;display: inline-block;vertical-align: middle;}.u-slider {max-width: 100%;display: inline-block;vertical-align: middle;font-size: 18px;line-height: 28px;color: #333;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;cursor: pointer;&:hover {color: @themeColor;}}}
}
</style>

2:在要使用的页面引入

<script setup lang="ts">
import TextScroll from './TextScroll.vue'
import { ref } from 'vue'
const sliderText = ref([{title: '美国作家杰罗姆·大卫·塞林格创作的唯一一部长篇小说',link: 'https://www.baidu.com'},{title: '首次出版于1951年'},{title: '塞林格将故事的起止局限于16岁的中学生霍尔顿·考尔菲德从离开学校到纽约游荡的三天时间内,塞林格将故事的起止局限于16岁的中学生霍尔顿·考尔菲德从离开学校到纽约游荡的三天时间内'},{title: '并借鉴了意识流天马行空的写作方法,充分探索了一个十几岁少年的内心世界'},{title: '愤怒与焦虑是此书的两大主题,主人公的经历和思想在青少年中引起强烈共鸣'}])
function onClick (value: string) { // 获取点击的标题console.log('value:', value)
}
</script>
<template><div><h2 class="mb10">TextScroll 横向文字滚动基本使用</h2><TextScroll:sliderText="sliderText"@click="onClick"width="100%":amount="4"backgroundColor="#FFF":height="50" /><h2 class="mt30 mb10">垂直文字滚动基本使用 (vertical)</h2><TextScroll:sliderText="sliderText"@click="onClick"verticalbackgroundColor="#e6f4ff":gap="60":interval="3000"width="100%":height="60" /></div>
</template>
<style lang="less" scoped>
</style>

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

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

相关文章

git拉取代码时出现Filename too long错误Git处理长路径

背景 git拉取代码时出现Filename too long错误 现象 如下&#xff1a; $ git checkout . error: unable to create file boot-starters/permission-access-security-service-boot-starter/src/main/java/cn/gzs***/basic/system/platform/starter/permission/access/resourc…

后端整理(MySql)

1 事务 1.1 事务ACID原则 原子性&#xff08;Atomicity&#xff09; 事务的原子性指的是事务的操作&#xff0c;要么全部成功&#xff0c;要么全部失败回滚 一致性&#xff08;Consistency&#xff09; 事务的一致性是指事务必须使数据库从一个一致状态转变成另一个一致性…

机器学习05-数据准备(利用 scikit-learn基于Pima Indian数据集作数据预处理)

机器学习的数据准备是指在将数据用于机器学习算法之前&#xff0c;对原始数据进行预处理、清洗和转换的过程。数据准备是机器学习中非常重要的一步&#xff0c;它直接影响了模型的性能和预测结果的准确性 以下是机器学习数据准备的一些常见步骤&#xff1a; 数据收集&#xff…

使用kubeadm快速部署一个k8s集群

Kubernetes概述 使用kubeadm快速部署一个k8s集群 Kubernetes高可用集群二进制部署&#xff08;一&#xff09;主机准备和负载均衡器安装 Kubernetes高可用集群二进制部署&#xff08;二&#xff09;ETCD集群部署 Kubernetes高可用集群二进制部署&#xff08;三&#xff09;部署…

JVM之垃圾回收器

1.如何判断对象可以回收 1.1 引用计数法 什么是引用计数器法 在对象中添加一个引用计数器&#xff0c;每当有一个地方引用它时&#xff0c;计数器值就加一&#xff1b;当引用失效时&#xff0c;计数器值就减一&#xff1b;任何时刻计数器为零的对象就是不可能再被使用的。 …

【C语言学习】整数范围、整数越界、无符号数

1.整数范围 对于一个字节&#xff08;8位&#xff09;&#xff0c;可以表达的范围是00000000 ~ 11111111 其中00000000 ——> 0 11111111 ~ 10000000 ——> -1 ~ -128&#xff08;从大到小&#xff09; 00000001 ~ 01111111 ——> 1~127&#xff08;从小到大&#xff…

Python需要学的基础有哪些

Python介绍 Python是一种广泛使用的高级编程语言&#xff0c;因其简洁易读的语法和强大的功能而备受欢迎。本文将介绍一些Python教学内容&#xff0c;帮助初学者快速入门编程世界 1. Python基础 Python的基础知识对于编程初学者至关重要。以下是一些重要的基础概念&#xff…

redis 持久化 与 键淘汰策略

redis运维核心&#xff1a; aof日志(全持久化 增量) 、 rdb(半持久化/全量备份) 、 键淘汰策略 、 高可用 1、Redis是基于内存的&#xff0c;一旦Redis重启/退出/故障&#xff0c;内存的数据将会全部丢失。故而有了持久化。 2、持久化&#xff1a;将内存中的数据存于磁盘中&am…

电脑第一次使用屏幕键盘

操作流程 1.在键盘上同时按WinR打开运行; 2.输入control 3.找到设置中心 4.点击屏幕键盘 效果 具体怎么使用 我不咋清除 简单 测试了一下 可以用鼠标点击屏幕键盘的按键 用键盘 按字母键和数字键 是和屏幕键盘不同步的 其他 tab、shift、后退、enter好像同步

stm32和python实现DMA+串口数据收发

STM32F103配置 1-0 串口配置 void uart_init(u32 bound){//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //使能USART1时钟RCC_AP…

ansible——playbook

playbook playbook是剧本的意思 通过 task 调用 ansible 的模块将多个 play 组织在一 个playbook中运行。 playbook本身由以下各部分组成&#xff1a; Tasks: 任务&#xff0c;即调用模块完成的某操作 Variables: 变量 Templates: 模板 Handlers: 处理器&#xff0c;当某条件…

域名校验?反爬界的掩耳盗铃!

这一集我们讲一个比较简单的域名校验&#xff0c;可能你没有听过这个名字&#xff0c;因为这个名字是我编的&#xff0c;那么它究竟是什么呢&#xff1f;又为什么说它是掩耳盗铃呢&#xff1f;我们来看看下面的案例&#xff1a; 必应搜索页隐藏内容虎嗅新闻跳转404 import re…

《Kali渗透基础》13. 无线渗透(三)

kali渗透 1&#xff1a;无线通信过程1.1&#xff1a;Open 认证1.2&#xff1a;PSK 认证1.3&#xff1a;关联请求 2&#xff1a;加密2.1&#xff1a;Open 无加密网络2.2&#xff1a;WEP 加密系统2.3&#xff1a;WPA 安全系统2.3.1&#xff1a;WPA12.3.2&#xff1a;WPA2 3&#…

大数据课程D4——hadoop的YARN

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解YARN的概念和结构; ⚪ 掌握YARN的资源调度流程; ⚪ 了解Hadoop支持的资源调度器:FIFO、Capacity、Fair; ⚪ 掌握YARN的完全分布式结构和常见问题; ⚪ 掌握YARN的服役新节点操作…

Springboot 多数据源 dynamic-datasource动态添加移除数据源

0.前言 上一篇文章我们讲了如何通过多数据源组件&#xff0c;在Spring boot Druid 连接池项目中配置多数据源&#xff0c;并且通过DS注解的方式切换数据源&#xff0c;《Spring Boot 配置多数据源【最简单的方式】》。但是在多租户的业务场景中&#xff0c;我们通常需要手动的…

react-player静音不能自动播放问题

现象 移动端不能自动播放 原因 取决于您使用的浏览器&#xff0c;但muted如果您不想与autoplay用户交互&#xff0c;则必须使用视频。 Chrome 的自动播放策略很简单&#xff1a; 始终允许静音自动播放。在以下情况下允许自动播放声音&#xff1a; 用户与域进行了交互&#x…

RunnerGo条件控制器使用方法

在做性能测试时我们需要根据业务需求、业务场景来配置测试脚本&#xff0c;举个例子&#xff1a;在登录注册场景中&#xff0c;可能会有账号密码全部正确、账号格式错误、密码错误等多种情况&#xff0c;这里的“登录/注册”事件可以视为一个场景。一个真实业务中的场景&#x…

2023 年牛客多校第五场题解

A Jujubesister 题意&#xff1a;给定长度为 n n n 的数列 { a } i 1 n \{a\}_{i1}^n {a}i1n​&#xff0c; q q q 次询问区间 [ l , r ] [l,r] [l,r] 上满足 a i a k > a j a_ia_k>a_j ai​ak​>aj​ 且满足 l ≤ i < j < k ≤ r l \le i <j<k \…

课程作业-基于Python实现的迷宫搜索游戏附源码

简单介绍一下 该项目不过是一个平平无奇的小作业&#xff0c;基于python3.8开发&#xff0c;目前提供两种迷宫生成算法与三种迷宫求解算法&#xff0c;希望对大家的学习有所帮助。 项目如果有后续的跟进将会声明&#xff0c;目前就这样吧~ 效果图如下所示&#xff1a; 环境…

14 springboot项目——首页跳转实现

templates里的静态资源无法访问&#xff0c;需要写mvc的配置类或者改application.xml配置文件实现首页访问。这两个方式用其中一种即可&#xff0c;否则会冲突。 14.1 首页跳转方式一 创建配置类&#xff0c;在config包中创建一个mvc的配置类&#xff1a; package jiang.com.s…