I’m making an HTML5 game engine, and I want my Camera object to have a zoom property. In the renderer, I thought that I could easily implement it, like this:
context.save();
context.scale(camera.zoom, camera.zoom);
draw();
context.restore();
There is a problem, though. When I first tested this, the camera seemed to zoom forever! I figured that context.save() and context.restore() probably aren’t working as expected, and that the context’s internal scaling factor is getting multiplied by camera’s zoom ad infinitum.
This fixed the situation:
context.save();
context.scale(camera.zoom, camera.zoom);
draw();
context.scale(1/camera.zoom, camera.zoom);
context.restore();
This works now, but I’m afraid that this isn’t the most elegant/fast solution. Also, I think it is possible that, because of the floating point calculation imprecision, the scaling factor always changes slightly. That is, 1/camera.zoom might not always produce the same results.
So, two questions:
- Why wont the context.restore() set the scale of the context back to (1, 1)?
- How can I manually manipulate the scaling of the context?
Edit:
It was pointed out that the number of context.save()‘s and context.restore()‘s might be different, but that is not the case.
Here is how I measured it:
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);
}
})();
The renderer.saved value is 1 right before the context is restored one last time (after draw), and 0 after each rendering.
It seems like I have accidentally solved the problem. It works now.
The main suspect is this part of the code:
I believe that I used to zoom before actually saving the context, resulting in restoring having no effect on the zoom.