【问题标题】:Drawing successive frames to an HTML5 Canvas only shows the last frame将连续帧绘制到 HTML5 Canvas 仅显示最后一帧
【发布时间】:2023-03-03 08:47:24
【问题描述】:

我有一个复杂的循环来计算我想在画布元素中显示的各种静止帧。每次计算帧时都会显示它,我调用一个计时器并等到我清除它,然后显示下一帧,依此类推。

    drawing(transform(alone, Box, canvasx.width, canvasx.height), false, "00f", canvasx);
    drawing(transform(Lines, Box, canvasx.width, canvasx.height), false, "ff0000", canvasx);

    var date = new Date();
    var curDate = null;

    do {
        curDate = new Date();
    }
    while (curDate - date < 550);

    if (alone.length > 0) {
        canvasx.width = canvasx.width;
    } 

如果我在 var date line 中放置一个断点并每次按播放键,每个单独的帧都会显示,但是当我让它穿过画布时,它在运行时是空的,最后它显示最后一帧。

现在,如果我删除 canvasx.width = canvasx.width;,我仍然会得到相同的行为,但很明显,最后我将所有帧都绘制在另一个之上。

显然它不是动画,所以我不能在 setinterval 中调用绘图。

有人知道为什么吗?

【问题讨论】:

    标签: javascript html canvas


    【解决方案1】:

    必须使用setTimeout 而不是您的循环。

    // JavaScript is single thread, and this BLOCKS the re-rendering and display of the canvas
    do {
        curDate = new Date();
    }
    while (curDate - date < 550);
    

    另外我宁愿使用context.clearRect(参见MDC)而不是调整大小,这没有任何性能差异。

    应该这样做:

    function drawCanvas() {
        if (alone.length > 0) {
            // clear canvas
        } 
        drawing(transform(alone, Box, canvasx.width, canvasx.height), false, "00f", canvasx);
        drawing(transform(Lines, Box, canvasx.width, canvasx.height), false, "ff0000", canvasx);
        setTimeout(drawCanvas, 550);
    }
    

    永远不要试图在 JavaScript 中模拟 sleep,当你是 sleeping 时,你会阻止整个浏览器做任何事情。

    【讨论】:

    • 问题是它的 while 循环每次都会计算新结果,我试图将结果发送到像你写的那样的函数中,但显然是徒劳的,因为如果 while 循环无法完成,画布没有得到更新。我想出了一个愚蠢的解决方案来展示我想要的东西,但它只能在 chrome 上正常工作。 elasticrash.info/demos/003/index.html 因为我弹出和关闭模式
    • 哦,我将其标记为正确,因为我明白我必须做什么。
    • 附带说明一下,我还看到 Safari OS X 中仅更改画布大小并不能完全清除它的情况; clearRect 绝对是更好的选择。
    • @Phrogz 很高兴知道,很多网站都建议使用宽度重置:/
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    • 2021-12-03
    • 1970-01-01
    相关资源
    最近更新 更多