全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

中高端软件定制开发服务商

与我们取得联系

13245491521     13245491521

2024-12-24_作为一个前端你连requestAnimationFrame的用法、优势和应用场景都搞不清楚?

您的位置:首页 >> 新闻 >> 行业资讯

作为一个前端你连requestAnimationFrame的用法、优势和应用场景都搞不清楚? 点击关注公众号,“技术干货”及时达! 前言如果你是一名前端开发,那么你多少有了解过requestAnimationFrame吧?如果没有也接着往下看,会有详细用法说明。 其实很多人会局限于把requestAnimationFrame应用于一些纯动画相关的需求上,但其实在前端很多业务场景下requestAnimationFrame都能用于性能优化,下面将细说一下requestAnimationFrame的具体用法和几种应用场景。 requestAnimationFrame作用与用法requestAnimationFrame简述「MDN官方说法是这样的」 基本示例script lang="ts" setup function init() { console.log('您好,我是requestAnimationFrame'); } requestAnimationFrame(init)/script「效果如下」 但是例子上面是最基本的调用方式,并且只简单执行了一次,而对于动画是要一直执行的。 下面直接上图看看官方的文档对这个的说明,上面说具体用法应该要递归调用,而不是单次调用。 递归调用示例script lang="ts" setup function init() { console.log('您好,递归调用requestAnimationFrame'); requestAnimationFrame(init) } requestAnimationFrame(init)/script「执行动图效果如下」 requestAnimationFrame会一直递归调用执行,并且调用的频率通常是与当前显示器的刷新率相匹配(这也是这个API核心优势),例如屏幕75hz就1秒执行75次。 而且如果使用的是定时器实现此功能是无法适应各种屏幕帧率的。 回调函数requestAnimationFrame执行后的回调函数有且只会返回一个参数,并且返回的参数是一个毫秒数,这个参数所表示是的上一帧渲染的结束时间,直接看看下面代码示例与打印效果。 script lang="ts" setup function init(val) { console.log('您好,requestAnimationFrame回调:', val); requestAnimationFrame(init); } requestAnimationFrame(init);/script 「注意:」 如果我们同时调用了很多个requestAnimationFrame,那么他们会收到相同的时间戳,因为与屏幕的帧率相同所以并不会不一样。 终止执行终止此API的执行,官方提供的方法是window.cancelAnimationFrame(),语法如下 ancelAnimationFrame(requestID) 直接看示例更便于理解,用法非常类似定时器的clearTimeout(),直接把 requestAnimationFrame 返回值传给 cancelAnimationFrame() 即可终止执行。 template div button @click="stop"/button /div/templatescript lang="ts" setup let myReq; function init(val) { console.log('您好,requestAnimationFrame回调:', val); myReq = requestAnimationFrame(init); } requestAnimationFrame(init); function stop() { cancelAnimationFrame(myReq); }/script requestAnimationFrame优势动画更丝滑,不会出现卡顿对比传统的setTimeout 和 setInterval动画会更流畅丝滑。 主要 「原因」 是由于运行的浏览器会监听显示器返回的VSync信号确保同步,收到信号后再开始新的渲染周期,因此做到了与浏览器绘制频率绝对一致。所以帧率会相当平稳,例如显示屏60hz,那么会固定1000/60ms刷新一次。 但如果使用的是setTimeout 和 setInterval来实现同样的动画效果,它们会受到事件队列宏任务、微任务影响会导致执行的优先级顺序有所差异,自然做不到与绘制同频。 所以使用setTimeout 和 setInterval不但无法自动匹配显示屏帧率,也无法做到完全固定的时间去刷新。 性能更好,切后台会暂停当我们把使用了requestAnimationFrame的页面切换到后台运行时,requestAnimationFrame会暂停执行从而提高性能,切换回来后会马上提着执行。 效果如下动图,隐藏后停止运行,切换回来接着运行。 应用场景:常规动画用一个很简单的示例:用requestAnimationFrame使一张图片动态也丝滑旋转,直接看示例代码和效果。 「思路」:首先在页面初始化时执行window.requestAnimationFrame(animate)使动画动起来,实现动画一直丝滑转运。在关闭页面时用window.cancelAnimationFrame(rafId)去终止执行。 template div class="container" div :style="imgStyle" class="earth"/div /div/template script setup import { ref, onMounted, reactive, onUnmounted } from 'vue'; const imgStyle = reactive({ transform: 'rotate(0deg)', }); let rafId = null; // 请求动画帧方法 function animate(time) { const angle = (time % 10000) / 5; // 控制转的速度 imgStyle.transform = `rotate(${angle}deg)`; rafId = window.requestAnimationFrame(animate); } // 开始动画 onMounted(() = { rafId = window.requestAnimationFrame(animate); }); // 卸载时生命周末停止动画 onUnmounted(() = { if (rafId) { window.cancelAnimationFrame(rafId); } });/script style scoped body { box-sizing: border-box; background-color: #ccc; height: 100vh; display: flex; justify-content: center; align-items: center; } .container { position: relative; height: 100%; width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; } .earth { height: 100px; width: 100px; background-size: cover; border-radius: 50%; background-image: url('@/assets/images/about_advantage_3.png'); /* 替换为实际的路径 */ }/style 看看动图效果 应用场景:滚动加载在滚动事件中用requestAnimationFrame去加载渲染数据使混动效果更加丝滑。主要好久有几个 「提高性能」: 添加requestAnimationFrame之后会在下一帧渲染之前执行,而不是每次在滚动事件触发的时候就立即执行。这可以减少大量不必要的计算,提高性能。 「用户体验更好」:确保在绘制下一帧时再执行,使帧率与显示屏相同,视觉上会更丝滑。 代码示例和效果如下: template div class="container" ref="scrollRef" div v-for="(item, index) in items" :key="index" class="item" {{ item }} /div div v-if="loading" class="loading"数据加载中.../div /div /template script setup lang="ts" import { ref, onMounted, onUnmounted } from 'vue'; const loading = ref(false); let rafId: number | null = null; // 数据列表 const items = refstring[](Array.from({ length: 50 }, (_, i) = `Test ${i + 1}`)); // 滚动容器 const scrollRef = refHTMLElement | null(null); // 模拟一个异步加载数据效果 const moreData = () = { return new Promisevoid((resolve) = { setTimeout(() = { const newItems = Array.from({ length: 50 }, (_, i) = `Test ${items.value.length + i + 1}`); items.value.push(...newItems); resolve(); }, 1000); }); }; // 检查是否需要加载更多数据 const checkScrollPosition = () = { if (loading.value) return; const container = scrollRef.value; if (!container) return; const scrollTop = container.scrollTop; const clientHeight = container.clientHeight; const scrollHeight = container.scrollHeight; if (scrollHeight - scrollTop - clientHeight = 100) { startLoading(); } }; // 加载数据 const startLoading = async () = { loading.value = true; await moreData(); loading.value = false; }; // 监听滚动事件 const handleScroll = () = { console.log('滚动事件触发啦'); if (rafId !== null) { window.cancelAnimationFrame(rafId); } rafId = window.requestAnimationFrame(checkScrollPosition); }; // 添加滚动事件监听器 onMounted(() = { if (scrollRef.value) { scrollRef.value.addEventListener('scroll', handleScroll); } }); // 移除相关事件 onUnmounted(() = { if (rafId !== null) { window.cancelAnimationFrame(rafId); } if (scrollRef.value) { scrollRef.value.removeEventListener('scroll', handleScroll); } }); /script style scoped .container { padding: 20px; max-width: 800px; overflow-y: auto; margin: 0 auto; height: 600px; } .item { border-bottom: 1px solid #ccc; padding: 10px; } .loading { padding: 10px; color: #999; text-align: center; } /style看看下面动图效果 小结通过代码示例配合动图讲解后,再通过两个简单的事例可能大家会发现,只要在页面需要运动的地方其实都可以用到 requestAnimationFrame 使效果变的更加丝滑。 除了上面两个小示例其它非常多地方都可以用到requestAnimationFrame去优化性能,比较常见的例如游戏开发、各种动画效果和动态变化的布局等等。 ?文章就写到这啦,如果文章写的哪里不对或者有什么建议欢迎指出。 ?点击关注公众号,“技术干货”及时达! 阅读原文

上一篇:2024-07-30_Runway深夜炸场,Gen-3 Alpha图生视频上线,11秒让你脑洞乱飞 下一篇:2022-08-25_像经典计算机一样「开箱即用」,百度走出中国量子计算产业化的重要一步

TAG标签:

20
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版域名注册主机空间手机网站建设网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。
项目经理在线

相关阅读 更多>>

猜您喜欢更多>>

我们已经准备好了,你呢?
2022我们与您携手共赢,为您的企业营销保驾护航!

不达标就退款

高性价比建站

免费网站代备案

1对1原创设计服务

7×24小时售后支持

 

全国免费咨询:

13245491521

业务咨询:13245491521 / 13245491521

节假值班:13245491521()

联系地址:

Copyright © 2019-2025      ICP备案:沪ICP备19027192号-6 法律顾问:律师XXX支持

在线
客服

技术在线服务时间:9:00-20:00

在网站开发,您对接的直接是技术员,而非客服传话!

电话
咨询

13245491521
7*24小时客服热线

13245491521
项目经理手机

微信
咨询

加微信获取报价