【问题标题】:Does the animation run always with the same speed?动画是否总是以相同的速度运行?
【发布时间】:2021-08-27 14:04:49
【问题描述】:

我有这部分 JavaScript 代码绘制一个条形图(比如条形图):

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

canvas.width = window.innerHeight / 3 * 4;
canvas.height = window.innerHeight;
const xCharCnt = window.innerHeight / 3 * 4 / 48;
const yCharCnt = window.innerHeight / 34;

const foreground1 = "#AF5BEC";
let offset = 0;
const barHeight = 20;
const speed = 4;
const limit = yCharCnt * barHeight;

let requestId = window.requestAnimationFrame(render);

function render() {
    requestId = window.requestAnimationFrame(render);
    
    // Clear screen
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // Draw bar
    ctx.fillStyle = foreground1;
    ctx.fillRect(xCharCnt * 7, yCharCnt * 28, xCharCnt, -offset);
    offset = offset + speed;
    
    // Cancel animation
    if (offset >= limit) window.cancelAnimationFrame(requestId);
}

问题:

a) 它是制作动画的正确方法吗?

b) 动画是否始终以相同的速度运行,无论其运行设备的分辨率如何?

【问题讨论】:

标签: javascript animation canvas


【解决方案1】:

它将取决于帧速率,因此在设备之间会有所不同。

回调次数通常为每秒 60 次,但通常会根据 W3C 的建议与大多数 Web 浏览器中的显示刷新率相匹配。 requestAnimationFrame() 调用在大多数浏览器中在后台选项卡或隐藏中运行时会暂停,以提高性能和电池寿命。

https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

上面的链接还提供了有关如何对动画进行编码的建议,以便它们始终以相同的速度运行。翻译成您的代码,如下所示:

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

canvas.width = window.innerHeight / 3 * 4;
canvas.height = window.innerHeight;
const xCharCnt = window.innerHeight / 3 * 4 / 48;
const yCharCnt = window.innerHeight / 34;

const foreground1 = "#AF5BEC";
let offset = 0;
const barHeight = 20;
const speed = 4;
const limit = yCharCnt * barHeight;

let requestId = window.requestAnimationFrame(render);
let previousTimestamp;

function render(timestamp) {
    if(previousTimestamp === undefined) {
        previousTimestmap = timestamp;
    }

    const delta = timestamp - previousTimestamp;
    offset = Math.min(offset + (speed * delta), limit);

    // Clear screen
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // Draw bar
    ctx.fillStyle = foreground1;
    ctx.fillRect(xCharCnt * 7, yCharCnt * 28, xCharCnt, -offset);
    
    // Cancel animation
    requestId = window.requestAnimationFrame(render);
    if (offset >= limit) window.cancelAnimationFrame(requestId);

    previousTimestmap = timestamp;
}

【讨论】:

  • 感谢您的帮助。
  • 不幸的是,您修改我自己的代码不起作用。你测试过吗?这甚至是我的问题。每当我尝试从 Internet 上获取一些代码并尝试对其进行修改以使其适合我的需要时,它就不再起作用了。你的修改是相反的,也不起作用。
  • 我得到一个空白页/屏幕。控制台中没有错误/异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-18
  • 1970-01-01
  • 1970-01-01
  • 2012-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多