I'm developing a small browser game where the map size is 300x300
. Hence, I set my HMTL canvas's width and height to 300x300
. Then, when I want to spawn an object at the center, I spawn it at position 150, 150
. Also, when doing physics calculations involving position and velocity, I am likewise using static units that work well within the 300x300
size.
However, some users have tiny screens, or much larger screens, and I would like to scale the canvas size to accommodate them.
However, if I change the actual canvas's resolution, then all my calculations are thrown off. 150x150
is no longer the center, and likewise objects move either faster or slower. As a result, it seems ideal to keep the canvas resolution to be 300x300
and then simply scale the size via CSS, like this:
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
canvas.style.width = "600px";
canvas.style.height = "600px";
ctx.fillStyle = 'red';
ctx.font = "600 48px Arial";
ctx.fillText("hello", 150, 150);
canvas { border: 1px solid #333; }
<canvas width="300" height="300"></canvas>
However, the issue with this is that the screen is now blurry.
Is there a way to both scale the screen size without it looking blurry in addition to being able to still just use static values like 150x150
to refer to the center?
I can't post an answer to this since it was closed for whatever reason, but I believe the solution is the following:
export function resize2DContext(context, canvasWidth, canvasHeight) {
context.setTransform(1, 0, 0, 1, 0, 0);
const canvas = context.canvas;
const gameWidth = 600; // native game width
const gameHeight = 600; // native game height
canvas.style.width = canvasWidth + "px";
canvas.style.height = canvasHeight + "px";
canvas.width = canvasWidth;
canvas.height = canvasHeight;
context.scale(canvasWidth / gameWidth, canvasHeight / gameHeight);
}
And by handling input events like this:
function handlePointerMove(e) {
const xRatio = gameWidth / canvasWidth;
const yRatio = gameHeight / canvasHeight;
pointerX = e.offsetX * xRatio;
pointerY = e.offsetY * yRatio;
}