I have a html5 canvas element that takes size of the parent div in JSX.
<canvas
ref={canvasRef}
width={canvasParentRef.current?.offsetWidth}
height={canvasParentRef.current?.offsetHeight}
className={style.canvas}
/>
In this canvas I always have a rectangle on the center position, and possibly some other rectangles which position is based on the coordinates of the center rectangle.
I have a function to calculate position of the main rectangle that is centered on canvas.
const centerRectCoords = () => {
const {width, height} = rect;
const canvas = canvasRef.current;
const startX = canvas.width / 2 - width / 2;
const startY = canvas.height / 2 - height / 2;
return {
startX,
startY,
endX: startX + width,
endY: startY + height,
};
};
But I have a problem, everything looks too blurry on higher resolution screens. To prevent that, I have found some solution on MDN to scale canvas up. For that I have a following function:
const scaleCanvas = (
canvas: HTMLCanvasElement,
ctx: CanvasRenderingContext2D
): void => {
const canvasParent = canvasParentRef.current;
if (!canvasParent) return;
const { devicePixelRatio } = window;
const dimensions = canvasParent.getBoundingClientRect();
canvas.width = dimensions.width * devicePixelRatio;
canvas.height = dimensions.height * devicePixelRatio;
ctx.scale(devicePixelRatio, devicePixelRatio);
canvas.style.width = `${dimensions.width}px`;
canvas.style.height = `${dimensions.height}px`;
};
This function is called in useEffect
on mount.
But now whenever I generate these rectangles on higher resolution screen, they are not centered, because width and height on canvas is now bigger than style.width and style.height. I thought to maybe use style.width and style.height in centerRectCoords
function calculation, but those values are undefined because canvas is not visible in my app on load, it is another tab.
How can I make everything scale nicely on bigger and smallers screens, with correct sizing and without it being blurry?