David M. Casas
David M. Casas

Reputation: 59

How to fit HTML canvas to screen while maintaining aspect ratio and not cutting off the canvas?

I'm making a game using HTML canvas and javascript. My canvas is 1280 x 720 px (16:9 ratio). I want my game to be displayed at full screen, showing black bars if the screen ratio is not 16:9.

If I do this:

canvas {
    position: absolute;
    width: 100%;
    height: 100%;
}

Then my game is played at fullscreen, but stretched to fill screen if the screen ratio is not 16:9. I don't want it to be stretched, I want to show black bars if needed.

If I do this:

canvas {
    position: relative;
    width: 100%;
    height: 100%;
}

Then the canvas keeps the right aspect ratio, but it will be cut off if the screen is wider than 16:9, and I don't want that either.

How can I achieve this? Other answers I found revolve around updating canvas.width and canvas.height on window resize, but I'd rather not resize canvas.width or canvas.height since the game is designed to work under 1280 x 720. Sure I could scale the drawing according to canvas.width and canvas.height, but I wonder if this can be achieved without doing that.

Thank you

Upvotes: 3

Views: 4127

Answers (1)

tacoshy
tacoshy

Reputation: 13012

First as stated in the comments already, canvas is a replaced-level element. As such object-fit can be applied to it just like with images that are used for this demonstration.

The solution starts with a "wrapper" (div.fullscreen). This element is positioned to fill the entire viewport by using: position: fixed; inset: 0; (inset: 0; = top, right, bottom, left: 0 not fully supported yet: https://developer.mozilla.org/en-US/docs/Web/CSS/inset).

Next we address the image within this wrapper (or the canvas in your case) and setting the max-height and max-width to 100%. Then we use object-fit: contain; to let the canvas maintain its aspect-ratio but filling the wrapper without getting cut off.

Last but not least we use display: flex; justify-content: center; align-items: center; to display the canvas in the vertical and horizontal center.

body {
  margin: 0;
}

.fullscreen {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: black;
  display: flex;
  justify-content: center;
  align-items: center;
}

.fullscreen img {
  object-fit: contain;
  max-height: 100%;
  max-width: 100%;
}
<div class="fullscreen">
  <img src="https://via.placeholder.com/1280x720.jpg">
</div>

Upvotes: 6

Related Questions