3

Having some trouble trying to get my Canvas/Stage to resize and fit correctly within the parent container. I've found other similar posts and while the answers did help me with obtaining the new screen size it still doesn't want to fit within the container and instead goes right to the edges of the screen (which is expected from the examples), going over the parent container with the left/right content.

I've tried many different ways but still cannot find the correct way where it, doesn't go outside the parent container and the scale X/Y doesn't throw off the position of the shape within the canvas. The most obvious way for me was to set a constraint to the actual canvas/stage via CSS but that ends up throwing off the scaling making the shape appear outside the canvas.

In the code link, I included my hacky approach that I was trying to do and while it looks correct in some cases with smaller device screens, the canvas width will still go outside the parent container. I'm not sure if I'm overthinking this a lot or if there is a much simpler way to approach my issue, any help or tips would be great.

Live CodeSandbox: https://codesandbox.io/s/white-surf-yc2vh

Desired Result Image: https://i.stack.imgur.com/rRdBK.jpg

Jastreb
  • 37
  • 4
  • 1. Do you want the canvas to stay at a fixed size (as it is in your code), or do you want to resize the canvas to fit inside the parent container ? And 2. do you want the content to be resized relative to the canvas, so that e.g. the shape becomes smaller if the canvas gets smaller, or should the content get clipped if the canvas gets too small ? – kca Jan 04 '22 at 16:52
  • Sorry for the late reply. 1. I'd like the canvas to resize to fit inside the parent container. 2. This is an issue I have at the moment, ideally I would like for the content (in this case the circle) to have the same look (width/height, etc) even when the canvas gets smaller. In my hacky solution, I noticed that the circle looks different when the canvas is smaller than on a larger screen even with the scaling applied (this could be an issue with how I'm calculating it). So I think the content should get clipped when the canvas gets too small. – Jastreb Jan 04 '22 at 19:45

1 Answers1

2

I think what you want / need is to resize the canvas so that it fits into the container, while keeping the aspect ratio which you have specified.

You can use this function to resize some rectangle (rect) so that it fits into some other rectangle (container):

// fit a rect into some container, keeping the aspect ratio of the rect
export const fitRectIntoContainer = (rectWidth, rectHeight, containerWidth, containerHeight) => {

    const widthRatio = containerWidth / rectWidth;    // ratio container width to rect width
    const heightRatio = containerHeight / rectHeight; // ratio container height to rect height

    const ratio = Math.min( widthRatio, heightRatio ); // take the smaller ratio

    // new rect width and height, scaled by the same ratio
    return {
        width: rectWidth * ratio,
        height: rectHeight * ratio,
    };
};

Then you can resize the canvas so that it fits into the container:

const canvasSize = fitRectIntoContainer( 700, 600, size.width, size.height );
const canvasWidth = canvasSize.width;
const canvasHeight = canvasSize.height;

Then I guess you don't need any scaling anymore (so scaleX and scaleY can be both 1, or undefined)

kca
  • 4,856
  • 1
  • 20
  • 41
  • Just did a quick test and that seems to have solved all the issues that I had. Your solution is great and simple, never thought of that approach. Thank you for the help, really appreciate it! – Jastreb Jan 05 '22 at 18:17
  • Thank you for the nice feedback. This kind of problem is always simple as soon as you have the solution, but amazingly hard to wrap your head around if you don't yet know which way to go. You are not alone :-) – kca Jan 06 '22 at 17:09