canvas调帧

2022/12/18

# requestAnimationFrame

  • 调用:requestAnimationFrame(callback)
  • callback自动传入参数为当前的时间戳
  • 根据浏览器性能差异下一次刷新时执行
const loop = (timeStamp = Date.now()) => {
    /* animation ~~~ */
    requestAnimationFrame()
    loop();
}
1
2
3
4
5

  • 离开页面挂起,返回时继续执行

# 动画帧数

  • 一秒更新的次数,可以通过时间戳来计算得出,但是根据浏览器的性能差异会有不同的效果,(例如:性能好的浏览器每秒刷新次数多
  • 肉眼能反应的较舒适的帧数是每秒30帧-60帧,也就是 17-34 毫秒
  • 可以固定好每秒的运动量,以及通过时间戳差计算出该有的运动量

















 




 













 
 
 
 
 
 
 
 
 
 
 





<body>
    <canvas id="canvas"></canvas>
    <script>
        const canvas = document.querySelector("#canvas");
        canvas.setAttribute("style", "width: 100vw; height: 100vh");
        const { innerWidth, innerHeight, devicePixelRatio: dpr } = window;

        canvas.width = innerWidth * dpr;
        canvas.height = innerHeight * dpr;

        const ctx = canvas.getContext("2d");
        ctx.scale(dpr, dpr);

        const xOffset = 100;
        const yOffset = 60;

        // 一秒钟旋转度数
        const SECOND_ROTATE = 30;

        const dreaImg = (() => {
            let angle = 0;
            return (diffTime) => {
                angle += diffTime / 1000 * SECOND_ROTATE;

                ctx.save();
                ctx.translate(xOffset, yOffset);
                ctx.rotate(angle * Math.PI / 180);
                ctx.translate(-xOffset, -yOffset);

                ctx.fillStyle = "#000000";
                ctx.fillRect(50, 50, 100, 20);

                ctx.restore();
            }
        })();

        let lastTime = Date.now();
        const loop = (timeStamp = Date.now()) => {
            let diffTime = timeStamp - lastTime;
            lastTime = timeStamp;
            // 每秒钟控制在 30-60 帧
            diffTime = diffTime < 17 ? 17 : (diffTime > 34 ? 34 : diffTime);

            ctx.clearRect(0, 0, innerWidth, innerHeight);
            dreaImg(diffTime);
            requestAnimationFrame(loop);
        }

        loop();
    </script>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
上次更新: 6/13/2025