动画效果

在工业监控系统、生产看板等场景中,经常需要模拟生产线的动态运行效果。本文将基于 Vue3 和 requestAnimationFrame 实现一个高性能的横向循环滚动效果,完美模拟生产线传输带的视觉体验。我们将从代码实现到原理分析,全面讲解如何打造流畅、高效的滚动动画。

一、效果展示与应用场景

先来看下最终实现的效果:一系列生产物料图标将沿着横向轨道从左向右连续滚动,到达终点后自动循环,形成无限滚动的生产线效果。这种效果非常适合:

  • 工业监控大屏中的生产线模拟
  • 生产进度可视化展示
  • 物流传输过程动态演示
  • 数据看板中的动态元素展示

相比传统的轮播组件,这种实现方式具有更高的性能和更自然的动画效果,尤其适合长时间运行的监控场景。

二、核心实现方案

我们将使用以下技术栈和方案:

  • Vue3 + TypeScript:提供组件化开发和类型安全
  • requestAnimationFrame:实现高性能动画,替代传统的 setInterval
  • CSS 滚动优化:隐藏滚动条并优化滚动容器样式
  • 循环逻辑设计:通过重置 scrollLeft 实现无缝循环

下面是完整的实现代码:

1. 模板结构(Template)

<template><!-- 生产线滚动容器 --><div class="ktscx-box" ref="scrollDom"><div class="ktscx"><!-- 生产线上的物品,这里循环生成40个 --><divclass="ktscx-item"v-for="(item, index) in 40":key="index"></div></div></div>
</template>

模板结构非常简洁,主要包含两个层级:

  • 外层 ktscx-box:作为滚动容器,通过 ref 绑定到组件实例
  • 内层 ktscx:包含所有滚动项的容器,设置为 200% 宽度确保能产生滚动效果
  • 循环生成的 ktscx-item:生产线中的物品元素,共 40 个

2. 脚本逻辑(Script)

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';// 定义滚动容器的ref,指向DOM元素
const scrollDom = ref<HTMLDivElement | null>(null);
let timer: number | null = null; // 动画帧ID,用于控制动画// 开始横向滚动(从左向右视觉效果)
const startScroll = () => {if (!scrollDom.value) return;// 启动动画帧,开始滚动timer = requestAnimationFrame(scrollStep);
};// 停止滚动
const stopScroll = () => {if (timer) {cancelAnimationFrame(timer);timer = null;}
};// 动画帧执行的滚动逻辑
const scrollStep = () => {const moveDom = scrollDom.value;if (!moveDom) {stopScroll();return;}// 每次滚动的步长(负值表示向右滚动)const step = -1; moveDom.scrollLeft += step;// 计算最大可滚动距离 = 内容总宽度 - 容器可视宽度const maxScrollLeft = moveDom.scrollWidth - moveDom.clientWidth;// 当滚动到最左侧时,重置到最右侧(形成循环)if (moveDom.scrollLeft <= 0) {moveDom.scrollLeft = maxScrollLeft; }// 继续请求下一帧动画,形成连续滚动timer = requestAnimationFrame(scrollStep);
};// 组件挂载时启动滚动
onMounted(() => {startScroll();
});// 组件卸载时停止滚动,防止内存泄漏
onUnmounted(() => {stopScroll();
});
</script>

脚本逻辑解析:

  1. 核心变量

    • scrollDom:通过 ref 绑定到滚动容器 DOM 元素
    • timer:存储动画帧 ID,用于控制动画的启动和停止
  2. 动画控制函数

    • startScroll():启动滚动动画,通过 requestAnimationFrame 触发第一帧
    • stopScroll():停止滚动动画,通过 cancelAnimationFrame 取消动画帧
    • scrollStep():每帧执行的滚动逻辑,是实现动画的核心
  3. 滚动原理

    • 通过修改容器的 scrollLeft 属性实现滚动
    • 负的步长值(step = -1)使内容从左向右滚动
    • 当滚动到最左侧(scrollLeft <= 0)时,重置到最大滚动位置,实现循环

3. 样式设计(Style)

<style scoped lang="scss">
.ktscx-box {width: 83%;height: 20px;overflow-x: auto;  // 允许横向滚动position: absolute;top: 256px;margin-left: 3%;// 隐藏滚动条,提升视觉体验&::-webkit-scrollbar {display: none;}.ktscx {width: 200%;  // 宽度设为200%,确保内容超出容器宽度产生滚动height: 20px;display: flex;justify-content: space-around;  // 物品均匀分布align-items: center;.ktscx-item {width: 20px;height: 10px;// 使用背景图作为生产线物品background-image: url('@/assets/images/yundong4.png');background-size: 100% 100%;background-repeat: no-repeat;flex-shrink: 0;  // 防止物品被压缩变形}}
}
</style>

样式设计要点:

  1. 滚动容器样式

    • 设置 overflow-x: auto 允许横向滚动
    • 使用 ::-webkit-scrollbar { display: none } 隐藏滚动条
    • 固定高度和宽度,确保滚动区域可控
  2. 内容容器样式

    • 宽度设为 200%,确保内容宽度超过容器宽度,产生滚动空间
    • 使用 flex 布局使物品均匀分布
  3. 滚动项样式

    • 固定宽高,使用背景图展示物品
    • flex-shrink: 0 确保物品不会被压缩变形

三、核心技术点解析

1. requestAnimationFrame 为什么比 setInterval 更好?

本实现使用 requestAnimationFrame 而非传统的 setInterval 来驱动动画,原因如下:

  • 与浏览器刷新同步:requestAnimationFrame 会在浏览器每次重绘前执行,与显示器刷新率(通常 60Hz)保持同步,避免动画卡顿
  • 自动性能调整:在性能较低的设备上,浏览器会自动降低执行频率,保证动画的流畅度
  • 后台暂停:当页面处于后台或隐藏标签页时,动画会自动暂停,减少不必要的性能消耗
  • 精确计时:基于系统时间计算帧间隔,避免 setInterval 可能产生的累积误差

对于生产线这种需要长时间运行的动画,这些优势尤为重要。

2. 循环滚动的实现原理

循环滚动的核心在于巧妙利用 scrollLeft 属性和内容宽度:

  1. scrollLeft 属性表示元素内容向左滚动的像素数:

    • 增大 scrollLeft → 内容向左移动
    • 减小 scrollLeft → 内容向右移动
  2. 循环逻辑:

    • 当内容滚动到最左侧(scrollLeft <= 0)时
    • 立即将 scrollLeft 重置为最大可滚动距离(maxScrollLeft
    • 由于内容容器宽度是 200%,重置后视觉上看不出跳跃,形成无缝循环
  3. 最大可滚动距离计算:

const maxScrollLeft = moveDom.scrollWidth - moveDom.clientWidth;
  1. 其中 scrollWidth 是内容总宽度,clientWidth 是容器可视宽度。

四、功能扩展与优化

基于以上实现,我们可以进行一些实用的扩展:

1. 添加入交互控制

<!-- 在模板中添加控制按钮 -->
<div class="controls"><button @click="startScroll">启动</button><button @click="stopScroll">停止</button>
</div>

2. 滚动速度调节

// 添加速度控制变量
const speed = ref(1);// 在scrollStep中使用speed
const step = -speed.value;

3. 鼠标悬停暂停

<!-- 修改滚动容器 -->
<div class="ktscx-box" ref="scrollDom" @mouseenter="stopScroll" @mouseleave="startScroll">

4. 性能优化建议

  • 对于大量滚动项(超过 100 个),考虑使用虚拟列表技术
  • 添加 will-change: scroll-position 提示浏览器优化滚动性能
  • 避免在 scrollStep 中执行复杂计算或 DOM 操作
  • 滚动项使用相同尺寸,减少布局重排

五、总结

本文基于 Vue3 实现了一个高性能的横向循环滚动效果,完美模拟生产线传输带。核心要点包括:


使用 requestAnimationFrame 实现流畅动画,替代传统的 setInterval 通过控制 scrollLeft 属性值实现滚动效果,负步长产生从左到右的视觉体验 利用内容宽度和容器宽度的关系,实现无缝循环滚动 隐藏滚动条并优化样式,提升视觉体验

这种实现方式性能优异、代码简洁,非常适合工业监控、生产看板等场景。根据实际需求,你可以进一步扩展功能,如添加速度控制、方向切换、交互暂停等特性。

宝子们加加关注,会持续更新前端学习内容。

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

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

    相关文章

    万字长文解码如何玩转Prompt(附实践应用)

    在AI技术迅猛发展的今天&#xff0c;如何与大型语言模型高效“对话”已成为释放其潜力的关键。本文深入探讨了提示词工程&#xff08;Prompt Engineering&#xff09;这一新兴领域&#xff0c;系统解析了从基础概念到高级技巧的完整知识体系&#xff0c;并结合“淘宝XX业务数科…

    easyExcel嵌套子集合导出Excel

    我想要的Excel效果说明: 1.创建两个自定义注解:ExcelMerge(表示主对象内的单个属性,后续会根据子集合的大小合并下面的单元格),ExcelNestedList(表示嵌套的子集合) 2.NestedDataConverter.java 会把查询到的数据转换为一行一行的,相当于主表 left join 子表 ON 主.id子.主id的形…

    基于 C# WinForm 字体编辑器开发记录:从基础到进阶

    目录 基础版本实现 进阶版本改进 字体设置窗体增强 主窗体改进 功能对比 项目在本文章的绑定资源中免费的&#xff0c;0积分就可以下载哦~ 在 Windows Forms 应用开发中&#xff0c;字体编辑功能是许多文本处理软件的基础功能。本文将分享一个简易字体编辑器的开发过程&a…

    Linux基本使用和Java程序部署(含 JDK 与 MySQL)

    文章目录Linux 背景知识Linux 基本使用Linux 常用的特殊符号和操作符Linux 常用命令文本处理与分析系统管理与操作用户与权限管理文件/目录操作与内容处理工具Linux系统防火墙Shell 脚本与实践搭建 Java 部署环境apt&#xff08;Debian/Ubuntu 系的包管理利器&#xff09;介绍安…

    抗辐照CANFD通信芯片在高安全领域国产化替代的研究

    摘要&#xff1a;随着现代科技的飞速发展&#xff0c;高安全领域如航空航天、卫星通信等对电子设备的可靠性与抗辐照性能提出了极高的要求。CANFD通信芯片作为数据传输的关键组件&#xff0c;其性能优劣直接关系到整个系统的稳定性与安全性。本文聚焦于抗辐照CANFD通信芯片在高…

    Mybatis 源码解读-SqlSession 会话源码和Executor SQL操作执行器源码

    作者源码阅读笔记主要采用金山云文档记录的&#xff0c;所有的交互图和代码阅读笔记都是记录在云文档里面&#xff0c;本平台的文档编辑实在不方便&#xff0c;会导致我梳理的交互图和文档失去原来的格式&#xff0c;所以整理在文档里面&#xff0c;供大家阅读交流. 【金山文档…

    Java集合类综合练习题

    代码 import java.util.*; class ScoreRecord {private String studentId;private String name;private String subject;private int score;public ScoreRecord(String studentId, String name, String subject, int score) {this.studentId studentId;this.name name;this.s…

    秒懂边缘云|1分钟了解边缘安全加速 ESA

    普通开发者如何搭建安全快速的在线业务才能性价比最高 &#xff1f;阿里云现已为开发者推出免费版边缘安全加速 ESA&#xff0c;1 个产品就能把 CDN 缓存 API 加速 DNS WAF DDoS 防护全部搞定&#xff0c;还支持边缘函数快速部署网站和 AI 应用&#xff0c;性价比拉满。 1…

    数据结构:串、数组与广义表

    &#x1f4cc;目录&#x1f524; 一&#xff0c;串的定义&#x1f330; 二&#xff0c;案例引入场景1&#xff1a;文本编辑器中的查找替换场景2&#xff1a;用户手机号验证&#x1f4da; 三&#xff0c;串的类型定义、存储结构及其运算&#xff08;一&#xff09;串的抽象类型定…

    服务器路由相关配置Linux和Windows

    服务器路由相关配置Linux和Windowscentos路由系统核心概念传统工具集(命令)iproute2 工具集&#xff08;推荐&#xff09;NetworkManager 工具路由配置文件体系高级路由功能策略路由多路径路由路由监控工具系统级路由配置启用IP转发路由守护进程路由问题诊断流程Windows 路由Wi…

    Spring Boot启动事件详解:类型、监听与实战应用

    1. Spring Boot启动事件概述1.1 什么是Spring Boot启动事件在Spring Boot的应用生命周期中&#xff0c;从main方法执行到应用完全就绪&#xff0c;期间会发生一系列事件&#xff08;Event&#xff09;。这些事件由Spring Boot框架在特定时间点触发&#xff0c;用于通知系统当前…

    Python闭包详解:理解闭包与可变类型和不可变类型的关系

    一、定义闭包&#xff08;Closure&#xff09; 指的是一个函数对象&#xff0c;即使其外部作用域的变量已经不存在了&#xff0c;仍然能访问这些变量。简单来说&#xff0c;闭包是由函数及其相关的环境变量组成的实体。def outer():x 10def inner():print(x)return innerf ou…

    BotCash:GPT-5发布观察 工程优化的进步,还是技术突破的瓶颈?

    BotCash&#xff1a;GPT-5发布观察 工程优化的进步&#xff0c;还是技术突破的瓶颈&#xff1f; 在GPT-4以多模态能力震撼业界的一年后&#xff0c;GPT-5的亮相显得有些“平静”。当人们期待着又一场颠覆性技术革命时&#xff0c;这场发布会更像是给大模型技术按下了“精细打磨…

    AJAX学习(2)

    目录 一.XMLHttpRequest 二.XMLHttpRequest——查询参数 三.案例——地区查询 四.XMLHttpRequest_数据提交 五.Promise 六.Promise三种状态 七.PromiseeeXHR获取省份列表&#xff08;案例&#xff09; 八.封装-简易axios-获取省份列表 九.封装-简易axios-获取地区列表 …

    解决 pip 安装包时出现的 ReadTimeoutError 方法 1: 临时使用镜像源(单次安装)

    解决 pip 安装包时出现的 ReadTimeoutError 当您在使用 pip 安装 Python 包时遇到 pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(hostfiles.pythonhosted.org, port443): Read timed out. 错误时&#xff0c;这通常是由于网络问题导致的连接超时。P…

    Linux下使用Samba 客户端访问 Samba 服务器的配置(Ubuntu Debian)

    在 Linux 系统中&#xff0c;Samba 提供了与 Windows 系统文件共享的便利方式。本文将详细介绍在 Ubuntu 和 Debian 系统下如何安装 Samba 客户端、访问共享资源&#xff0c;并实现远程目录挂载和开机自动挂载。 文章参考自&#xff08;感谢分享&#xff09;&#xff1a;https…

    解决dedecms文章默认关键字太短的问题

    在管理文章或软件的时候&#xff0c;大家在添加关键字和内容摘要的时候&#xff0c;是不是对这样的情况感到比较的郁闷&#xff0c;我的关键字设定的明明非常的好&#xff0c;可是添加或修改后&#xff0c;会被无缘无故的截去很多&#xff0c;想必大家也都非常的明白&#xff0…

    K8s-kubernetes(二)资源限制-详细介绍

    K8s如何合理规定对象资源使用 基本概念 Kubernetes中&#xff0c;占用资源的最小单元为单个PodKubernetes中&#xff0c;资源占用主要针对服务器的CPU、内存 为什么要做资源限制 对于Kubernetes集群而言&#xff0c;所有Pod都会占用K8s集群所在服务器的资源&#xff0c;如果不做…

    量子神经网络:从NISQ困境到逻辑比特革命的破局之路

    ——解析2025千比特时代开发者的机遇与行动框架 引言:量子计算的“20比特魔咒”与千比特悖论 当开发者被建议“避免在>20量子比特电路训练”时,富士通却宣布2025年实现10,000物理比特系统。这一矛盾揭示了量子计算从NISQ时代向FTQC时代跃迁的核心逻辑:千比特突破非为直接…

    react+vite-plugin-react-router-generator自动化生成路由

    前言&#xff1a;react项目实际使用中有很多提升性能与功能的插件&#xff0c;今天来说一说vite里面提供的vite-plugin-react-router-generator&#xff0c;他主要提供了自动生成路由的功能&#xff0c;配合我们的loadable/component可以实现路由的懒加载与统一管理。1、实现效…