为什么 context.restore() 不会将上下文的比例设置回 (1, 1)

Why wont the context.restore() set the scale of the context back to (1, 1)?

本文关键字:设置 restore context 为什么 上下文      更新时间:2023-09-26

我正在制作一个HTML5游戏引擎,我希望我的Camera对象具有zoom属性。在渲染器中,我认为我可以轻松实现它,如下所示:

context.save();
context.scale(camera.zoom, camera.zoom);
draw();
context.restore();

不过,有一个问题。当我第一次测试这个时,相机似乎永远变焦了!我认为context.save()context.restore()可能没有按预期工作,并且上下文的内部缩放因子正在乘以相机的无穷zoom

这解决了这种情况:

context.save();
context.scale(camera.zoom, camera.zoom);
draw();
context.scale(1/camera.zoom, camera.zoom);
context.restore();

这现在有效,但恐怕这不是最优雅/最快速的解决方案。另外,我认为有可能由于浮点计算不精确,比例因子总是略有变化。也就是说,1/camera.zoom可能并不总是产生相同的结果。

所以,有两个问题:

  1. 为什么 context.restore() 不将上下文的比例设置回 (1, 1)?
  2. 如何手动操作上下文的缩放?

<小时 />编辑:

有人指出,context.save()context.restore()的数量可能不同,但事实并非如此。

以下是我的测量方法:

renderer.context.save = (function()
{
    var original = renderer.context.save;
    return function()
    {
        renderer.saved ++;
        original.call(renderer.context);
    }
})();
renderer.context.restore = (function()
{
    var original = renderer.context.restore;
    return function()
    {
        renderer.saved --;
        original.call(renderer.context);
    }
})();

renderer.saved值在最后一次还原上下文之前(绘制后)1,并在每次渲染后0

好像我不小心解决了这个问题。它现在有效。

主要嫌疑人是代码的这一部分:

renderer.context.save();
//Erase everything.
renderer.context.globalAlpha = 1;
renderer.context.fillStyle = renderer.settings.fillStyle;
renderer.context.fillRect(0, 0, renderer.width, renderer.height);
//Zoom.
renderer.context.scale(camera.zoom, camera.zoom);

我相信我在实际保存上下文之前曾经缩放过,导致恢复对缩放没有影响。