Pixi.js: 调整画布大小时,有白色背景闪烁

创建于 2016-12-03  ·  7评论  ·  资料来源: pixijs/pixi.js

我使用一个简单的独立函数调整画布大小,如下所示:

function resizeCanvas(width, height) {
    game.canvas.width = width;
    game.canvas.height = height;
    game.canvas.style.width = width / game.resolution + 'px';
    game.canvas.style.height = height / game.resolution + 'px';
}

当游戏启动时,我会做这样的事情:

game.renderer = new PIXI.WebGLRenderer(
    game.canvas.width,
    game.canvas.height,
    {
         view: game.canvas,
         backgroundColor: 0x000000,
     }
);

// recompute viewport size & canvas size with  browser window size 
game.scaler.update();  

// resize  renderer with new size.
game.renderer.resize(game.viewportWidth, game.viewportHeight);

测试用例非常简单:绘制一个小 png 图像。

浏览器:适用于 macOS 10.12 的 Chrome 55

Safari 没问题。

我知道这可能是 Chrome 的问题,但我希望有一种解决方法。

谢谢

💾 v4.x (Legacy)

最有用的评论

哦,谢谢! @mickdekkers太棒了,立即调用 render 使其与ResizeObserver回调一起工作。

所有7条评论

我使用这样的代码来修复这个错误:

    game.renderer.resize(game.viewportWidth - 1, game.viewportHeight);
    setTimeout(function() {
        game.renderer.resize(game.viewportWidth, game.viewportHeight);
    }, 1);

太丑了,谁能给我更好的建议?

当然可以,最好的办法是向Chrome团队报告。
谁能做到? 我的英语太差,无法描述这个错误。

新的 Chrome 没有这个问题。

我想确认这仍然发生在桌面 Safari(最新)和 Edge 上。 Pixi v4.3.0。

编辑:在伪代码中,我们正在做类似的事情

handleWindowDimensionChange(function() {
renderer.resize(window.innerWidth, window.innerHeight)
});

调整窗口大小会导致上述浏览器出现难看的闪烁。 不是 chrome 或 Firefox。

有没有人知道什么可能导致调整大小闪烁? 我在 Electron(测试了不同版本,但基本上是 Chromium 56、58 和 59)和 Pixi 4.5.5(在 Linux 和 macOS 上测试)中遇到了同样的问题,但只是在一个奇怪的场景中:

我正在根据 DOM 中的容器元素调整渲染器 (webgl) 的大小:如果窗口被调整大小或由 Javascript 中实现的可调整大小的小部件触发,则容器元素可以更改大小。 现在,如果我在窗口的resize和小部件的自定义resize处理程序(基于mousemove事件)中调整渲染器的大小,一切都很好,但是如果我使用新的ResizeObserver API 在容器元素上,我得到了非常糟糕的闪烁。

几个观察:

  • 闪烁是由整个画布被清除引起的(就像 OP 提到的,在我的情况下它不是白色而是透明的):当我在开发工具中使用屏幕截图进行性能记录时,这很明显:画布是空白的调整大小期间为 100 毫秒。
  • 我认为这是一个性能/时间问题,因为ResizeObserver更频繁地触发,但事实并非如此:我在两种情况下的频率相当。
  • 更重要的是,我正在限制调整大小本身,因此在两种情况下实际调用renderer.resize的频率是相同的; 调用也不会在任何一个事件处理程序中发生,而是被延迟了,所以在我看来不太可能归咎于时间。
  • 我的下一个猜测是ResizeObserver报告的值不同; 它报告容器的内容框而不是边界框,但由于不涉及边框或填充,因此值是相同的。 此外,我在两种情况下都将尺寸四舍五入为全像素。 实际上,在这两种情况下,设置的维度和频率都非常相似。
  • 如果我将油门超时增加到大约 500 毫秒或更高,闪烁就会停止
  • 使用窗口/小部件事件处理程序我需要使用getBoundingClientRect()来测量容器——为了保存这个调用(导致重新绘制)实际上是使用ResizeObserver一个重要原因,但我认为由于某种原因,缺少额外的重绘可能会导致闪烁。 所以我在调整大小之前添加了对getBoundingClientRect()的不必要的调用,但无济于事。

我不太担心,因为有一个可行的解决方法(使用两个单独的处理程序,而不是ResizeObserver ),但我真的很想知道是什么导致了这种情况。 我还关闭了autoResizeantialias但这没有区别。 任何想法我还能尝试什么?

@inukshuk在我的情况下,解决方案非常简单:只需在调整大小后调用render

app.renderer.resize(width, height)
// Immediately render because resizing clears the canvas
app.render()

这为我解决了闪烁问题。 请记住,如果您正在运行动画,它只会显示最后一帧,直到您的下一次更新循环,这可能会产生“冻结”效果。 如果你想让它顺利运行,你需要在调用渲染之前调用更新函数。

哦,谢谢! @mickdekkers太棒了,立即调用 render 使其与ResizeObserver回调一起工作。

此线程已被自动锁定,因为它在关闭后没有任何近期活动。 请为相关错误打开一个新问题。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

neciszhang picture neciszhang  ·  3评论

samueller picture samueller  ·  3评论

Makio64 picture Makio64  ·  3评论

softshape picture softshape  ·  3评论

finscn picture finscn  ·  3评论