IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> requestAnimationFrame -> 正文阅读

[游戏开发]requestAnimationFrame

requestAnimationFrame介绍

window.requestAnimationFrame()?告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行

语法:

window.requestAnimationFrame(callback);

参数:

callback: 下一次重绘之前更新动画帧所调用的函数(即上面所说的回调函数)。该回调函数会被传入DOMHighResTimeStamp参数,该参数与performance.now()的返回值相同,它表示requestAnimationFrame()?开始去执行回调函数的时刻。

返回值:

一个?long?整数,请求 ID ,是回调列表中唯一的标识。是个非零值,没别的意义。你可以传这个值给?window.cancelAnimationFrame()?以取消回调函数。?

?如何使用?

<html>

    <head></head>

    <body>
        <button id="start">开始</button>
        <button id="stop">停止</button>
        <script>
            window.onload = function () {
                function test() {
                    console.log("requestAnimationFrame ----");
                }
                requestAnimationFrame(test);
            }
        </script>
    </body>

</html>

可以看到,控制台成功的输出了一次??。?

?但是它只执行了一次,怎么做动画呢?别急,再看看?MDN?怎么说。

注意:若你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用window.requestAnimationFrame()

改下JS

window.onload = function () {
  var n = 0;
  function test() {
      n++;
      console.log("requestAnimationFrame ----", n);
      requestAnimationFrame(test);
  }
  requestAnimationFrame(test);
}

?

执行频率?

回调函数执行次数通常是每秒60次,但在大多数遵循W3C建议的浏览器中,回调函数执行次数通常与浏览器屏幕刷新次数相匹配。?

?即不用手动设置执行间隔时间,而是根据?浏览器屏幕刷新次数?自动调整了,也就是说浏览器屏幕刷新多少次,它就执行多少次。

回调函数参数

在同一个帧中的多个回调函数,它们每一个都会接受到一个相同的时间戳,即使在计算上一个回调函数的工作负载期间已经消耗了一些时间。该时间戳是一个十进制数,单位毫秒,最小精度为1ms(1000μs)。

function test(timeStamp) {
  console.log("requestAnimationFrame ----", timeStamp);
  requestAnimationFrame(test);
}
requestAnimationFrame(test);

?可以看出每次执行隔间时间戳近似等于 1000 / 60 = 16.666毫秒

如果有多个requestAnimationFrame一起执行会怎样?

function test1(timeStamp) {
  console.log("requestAnimationFrame1 ----", timeStamp);
  requestAnimationFrame(test1);
}
function test2(timeStamp) {
  console.log("requestAnimationFrame2 ----", timeStamp);
  requestAnimationFrame(test2);
}
requestAnimationFrame(test1);
requestAnimationFrame(test2);

可以看到,两个?requestAnimationFrame?在控制台输出的时间戳是一样的。也就是浏览器刷新一次的时候,执行所有的?requestAnimationFrame?,并且它们的回调参数是一模一样的。

浏览器优化

为了提高性能和电池寿命,因此在大多数浏览器里,当requestAnimationFrame()?运行在后台标签页或者隐藏的<iframe>?里时,requestAnimationFrame()?会被暂停调用以提升性能和电池寿命。

即当你切换到其他页面时,?requestAnimationFrame()?会被暂停调用

返回值

每执行一次,数值就会?+1

var stratBtn = document.querySelector("#start");
var rAF;
stratBtn.addEventListener("click", () => {
  rAF = requestAnimationFrame(test);
});

function test() {
  rAF = requestAnimationFrame(test);
  console.log("rAF:", rAF);
}

?取消执行

传这个值给?window.cancelAnimationFrame()?以取消回调函数

var stratBtn = document.querySelector("#start"),
    stopBtn = document.querySelector("#stop");
var rAF;
stratBtn.addEventListener("click", () => {
  rAF = requestAnimationFrame(test);
});
stopBtn.addEventListener("click", () => {
  cancelAnimationFrame(rAF);
});

function test() {
  rAF = requestAnimationFrame(test);
  console.log("rAF:", rAF);
}

应用

实现动画?

<html>

<head>
    <style>
        #box {
            width: 0;
            height: 50px;
            background-color: tomato;
        }
    </style>
</head>

<body>
    <button id="start">开始</button>
    <button id="stop">停止</button>
    <div id="box"></div>
    <script>
        window.onload = function () {

            var stratBtn = document.querySelector("#start"),
                stopBtn = document.querySelector("#stop"),
                box = document.querySelector("#box");

            var rAF;

            stratBtn.addEventListener("click", () => {
                rAF = requestAnimationFrame(test)
            });

            stopBtn.addEventListener("click", () => {
                cancelAnimationFrame(rAF);
            });

            function test() {
                box.style.width = `${rAF}%`;
                rAF = requestAnimationFrame(test)
            }
        }
    </script>
</body>

</html>

?requestAnimationFrame比起setTimeout、setInterval的优势主要有亮点:

1. requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率;

setTimeout、setInterval它们的内在运行机制决定了 时间间隔参数 实际上只是指定了把动画代码添加到 浏览器UI线程队列 中以等待执行的时间。如果队列前面已经加入了其它任务,那动画代码就要等前面的 任务完成后 再执行,并且如果时间间隔过短(小于16.7ms)会造成丢帧,所以就会导致动画可能不会按照预设的去执行,降低用户体验。

2.?在隐藏或不可见的元素中,将不会进行重新重绘或回流;

3.?requestAnimationFrame是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销?

参考资料:

【今天你更博学了么】一个神奇的前端动画 API requestAnimationFrame - 掘金

window.requestAnimationFrame - Web API 接口参考 | MDN

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-11-12 19:55:20  更:2021-11-12 19:55:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 0:40:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码