讲师中心 微信公众号
AI工具推荐 视频效率加速

如何通过 闭包实现对前端动画执行队列的“暂停与恢复”控制

大雪君_2125

大雪君_2125

发布时间:2026-05-12 13:57:36

|

355人浏览过

|

来源于php中文网

原创

可通过闭包封装动画状态实现独立暂停/恢复,核心是用闭包保存isPaused、lastTime、tasks,并暴露pause()/resume()方法;利用requestAnimationFrame循环中判断isPaused跳过执行,恢复时通过delta累积保证时间连续性。

如何通过 闭包实现对前端动画执行队列的“暂停与恢复”控制

可以通过闭包封装动画状态和控制逻辑,让每个动画队列拥有独立的暂停/恢复能力,核心在于用闭包保存 isPaused 状态、上一帧时间戳、待执行任务列表,并暴露可控的 pause() 和 resume() 方法。

闭包封装动画控制器

闭包的作用是隔离并持久化动画的私有状态(如是否暂停、上次执行时间、剩余任务),避免全局污染或多个队列互相干扰。一个典型的控制器结构如下:

  • 内部变量 isPaused = false 控制当前是否冻结执行
  • lastTime = 0 记录上一次 requestAnimationFrame 触发的时间,用于计算真实经过时间
  • tasks = [] 存储待执行的动画帧函数(如更新样式、调用回调)
  • 返回对象包含 add(task)、pause()、resume()、start() 等方法

利用 requestAnimationFrame 实现“可暂停”的循环

标准 requestAnimationFrame 无法暂停,但可以在每次回调中判断 isPaused 状态决定是否跳过执行,同时保留时间上下文:

  • 在 raf 回调里,先检查 if (isPaused) { requestAnimationFrame(loop); return; }
  • 若未暂停,则用 performance.now() 获取当前时间,减去 lastTime 得到本次耗时 delta
  • 遍历 tasks,对每个任务传入 delta,支持基于时间的平滑更新(如 easing 计算)
  • 更新 lastTime = now,再递归调用 requestAnimationFrame(loop)

暂停/恢复时保持时间连续性

真正影响动画流畅度的是“暂停期间流逝的时间是否被跳过”。理想做法是:暂停时不更新 lastTime,恢复时用当前时间减去暂停开始时间,补上“丢失”的 delta,或直接将 lastTime 设为恢复时刻的时间 —— 这样后续帧计算不会突变。

根据ui图生成前端页面
根据ui图生成前端页面

将一个或多个 UI 原型图、线框图、产品截图或设计稿转换为标准化、可直接交付的 PRD 风格文档,供产品、设计、前端和测试共同使用。适用于 Codex 需要分析 PC 网页、桌面端、移动端、响应式页面、独立弹窗、表单、表格、看板、数据大屏或多页面流程截图,还原页面结构与交互,强制套用固定文档模板,抽取跨页面共享规则,或把一组原型沉淀为单页规范文档加整体业务流程文档的场景。不适用于纯视觉审美点评、代码实现、接口设计、埋点方案、竞品分析或无 UI 输入的业务需求创作。

下载

立即学习“前端免费学习笔记(深入)”;

  • 点击 pause() 时记录 pauseStartTime = performance.now()
  • 点击 resume() 时,不重置 lastTime,而是让下一次 loop 中的 delta 自动包含暂停段(即 now - lastTime 会变大)
  • 如果需要“冻结式暂停”(如暂停后 resume 从同一帧继续),则在 pause() 时缓存当前帧状态,在 resume() 后强制执行一次同步更新

简单可用的代码示例

以下是一个最小可运行的闭包动画队列实现:

function createAnimationQueue() {
  let isPaused = false;
  let lastTime = 0;
  let tasks = [];
  let rafId = null;
<p>function loop(now) {
if (isPaused) {
rafId = requestAnimationFrame(loop);
return;
}
const delta = now - lastTime;
lastTime = now;</p><pre class='brush:php;toolbar:false;'>for (let i = 0; i < tasks.length; i++) {
  tasks[i](delta);
}

rafId = requestAnimationFrame(loop);

}

return { add(task) { tasks.push(task); }, pause() { isPaused = true; }, resume() { isPaused = false; if (!rafId) { lastTime = performance.now(); rafId = requestAnimationFrame(loop); } }, start() { if (!rafId) { lastTime = performance.now(); rafId = requestAnimationFrame(loop); } }, clear() { if (rafId) { cancelAnimationFrame(rafId); rafId = null; } tasks = []; } }; }

// 使用示例 const queue = createAnimationQueue(); queue.add((delta) => { el.style.transform = translateX(${x += delta * 0.5}px); }); queue.start();

// 暂停/恢复 buttonPause.addEventListener('click', () => queue.pause()); buttonResume.addEventListener('click', () => queue.resume());

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2663

2023.08.11

前端如何实现即时通讯
前端如何实现即时通讯

实现即时通讯的方法有WebSocket、Long Polling、Server-Sent Events、WebRTC等等。详细介绍:1、WebSocket,它可以在客户端和服务器之间建立持久连接,实现实时的双向通信,前端可以使用 WebSocket API来创建WebSocket连接,并通过发送和接收消息来实现即时通讯;2、Long Polling,是一种模拟实时通信的技术等等。

5763

2023.10.09

前端和后端的区别
前端和后端的区别

前端关注的是用户界面的设计和交互,而后端则注重数据处理和逻辑控制。想了解更多前端后端的相关内容,可以阅读本专题下面的文章。

6750

2024.03.19

php和前端的关联介绍
php和前端的关联介绍

php既可以作为前端语言,也可以作为后端语言。想了解更多php和前端的相关内容,可以阅读本专题下面的文章。

6458

2024.03.22

前端外包工作内容有哪些
前端外包工作内容有哪些

前端外包工作内容包括:1. 网站和应用程序开发;2. 用户界面和交互设计;3. 用户体验优化;4. 设计和视觉开发;5. 跨浏览器兼容性;6. 性能优化;7. 维护和更新;8. 项目管理和沟通。想了解更多前端的相关内容,可以阅读本专题下面的文章。

923

2024.05.22

js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

5226

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

1289

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

5164

2023.07.04

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

60

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn