Tips for adjusting the size of an HTML canvas to fit the screen while preserving the aspect ratio and ensuring the canvas remains fully visible

I'm working on a game project using HTML canvas and javascript. The canvas I am using has dimensions of 1280 x 720 px with a 16:9 aspect ratio. My goal is to have the game displayed at fullscreen, but with black bars shown if the screen ratio is not 16:9.

Here are the challenges I encountered:

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

With this code, my game fills the entire screen but gets stretched if the screen's ratio is different from 16:9. I prefer not to have it stretched; rather, I would like to display black bars if necessary.

Another attempt I made was:

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

Although this preserves the correct aspect ratio, it results in parts of the canvas being cut off when the screen is wider than 16:9, which is not ideal for the game experience.

So, how can I solve this dilemma? Some suggestions involve dynamically updating canvas.width and canvas.height on window resize events, but I would prefer not to alter these dimensions since the game mechanics are based on a 1280 x 720 resolution. While scaling the drawings according to canvas.width and canvas.height could work, I am curious if there is another solution that avoids this method.

Your insights and suggestions are greatly appreciated. Thank you!

Answer №1

It has been mentioned in the previous comments that canvas is considered a "replaced-level element". Therefore, just like with images, we can apply the object-fit property to it for this purpose.

The solution involves starting with a "wrapper" element (div.fullscreen). This element is positioned to completely fill the viewport by using: position: fixed; inset: 0;. This ensures that the wrapper occupies the entire screen space (although full support for inset: 0; is not yet available: https://developer.mozilla.org/en-US/docs/Web/CSS/inset).

Next, we handle the image within this wrapper (or in your case, the canvas) by setting the max-height and max-width to 100%. We then use object-fit: contain; to ensure that the canvas maintains its aspect ratio while filling the wrapper without being cropped.

Finally, we utilize

display: flex; justify-content: center; align-items: center;
to center the canvas both vertically and horizontally within the viewport.

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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating element modules in EJS

After building experience with React, I am now faced with the task of using ejs in my current project. Specifically, I need to return multiple radio elements. My attempt at achieving this was through the following code: <% const renderRadios = (value, ...

Display a pop-up alert message when the session expires without the need to manually refresh the page

I have a query regarding the automatic display of an alert message. Even though I have set the time limit to 10 seconds, I still need to manually refresh the page for the alert message to appear. The alert message should notify the user that the session ...

The functionality of Angular animate becomes compromised when there is a conflict between predefined CSS states and transition states

Explore this example CSS code: /* animations at the start */ .error-animation.ng-enter { -webkit-transition: 0.5s linear all; transition: 0.5s linear all; opacity: 0; } ...

Performing a conditional query on a Many-to-Many relationship in TypeORM

Operating under a many-to-many relationship between Category and Product entities In need of filtering products based on category ID Attempted to implement the following code after referring to some examples, but encountered difficulties in making it fun ...

Illumination causes surfaces to transform

In my simple scene, I have a ground and an interesting light source. However, when the light hits certain meshes, it creates some strange effects. The shadows are being cast correctly, but the other meshes affected by the light are showing unusual results. ...

Having trouble receiving accurate intellisense suggestions for MongoDB operations

Implementing communication between a node application and MongoDB without using Mongoose led to the installation of typing for both Node and MongoDB. This resulted in the creation of a typings folder with a reference to index.d.ts in the server.ts file. In ...

What is the meaning of "bootstrapping" as it relates to Angular 2?

I found a question that is similar to mine, but I think my case (with version 2) has enough differences to warrant a new discussion. I'm curious about the specific purpose of calling bootstrap() in an Angular 2 application. Can someone explain it to ...

The Javascript countdown feature may experience issues on Safari and IE browsers

Why does this function work in Chrome, but not on IE or Safari? function countdown(){ var dDay = new Date().getUTCDate() + 1; var dMonth = new Date().getUTCMonth() + 1; var dYear = new Date().getUTCFullYear(); var BigDay = new Date(dYear+ ...

Submit Button in CKEditor Not Working Without Ajax Submission

Having an issue with the ckeditor. Downloaded the latest version and integrated it into my form like this: <form action="/news.php?frame=edit&amp;id=185" enctype="multipart/form-data" method="post" accept-charset="utf-8"> <textarea class="edi ...

Module for Node.js that handles .ini files where variable names can begin with a number

.ini file: [1] 10X=true [2] 10X=true node.js : var mS = ini.parse(fs.readFileSync(__dirname + '/XXX/MS.ini', 'utf-8')); console.log(mS.1.10X); I am utilizing the ini module in node.js, which can be found at this link: https://www.n ...

Display picture within a modal window, regardless of whether it is the identical image

I have a file input that allows the user to upload an image. After selecting an image, a modal opens with the uploaded image displayed inside. You can view a demo of this functionality in action on this Fiddle Example: Here is the corresponding code snip ...

The conditional rendering logic in the ng-if directive does not seem to be synchronizing

Currently, I am delving into AngularJS and working on a basic application to gain familiarity with it. Within my app, there are four tabs: List, Create, Update, and Delete. However, my goal is to only display the Update and Delete tabs when I press the b ...

Live JSON sign-up feature on site

Is there a way to retrieve user email in real-time without using JSON? Currently, I am utilizing JSON for this purpose but it poses the risk of exposing emails that are stored in $resEmailsJson. Ideally, I would like to find a solution to hide all JSON $ ...

Achieving a dynamic "Picture Presentation" feature with JavaScript/jQuery

Currently, I am in the process of developing a website that will serve as a presentation. My plan is to create a slideshow effect using JavaScript. While I have implemented some functions, I must admit that it is not very organized at the moment. The main ...

Using Node's Express bodyParser() to access a JSON string that has been parsed

Question: How can I retrieve the parsed JSON object from the server side? I have successfully sent a JSON string to the server, but I am having trouble accessing the object once it is parsed. The client-side script for sending the JSON data is as follows ...

Express fails to pass password validation

I encountered an issue with a ValidationError stating that the Path password is required while attempting to register a new User. My experience in Node, programming, and authentication is limited. Below is the code for the User model and schema where I ma ...

How to Enhance GraphQL Mutation OutputFields with a Function Generator

I'm encountering issues while trying to incorporate a function generator within a GraphQL mutation. The function generator is utilized to streamline the promise chain inside the mutation. Prior to refactoring the code, everything was functioning corr ...

Update the dropdown menu based on the revised time

I need to create a PHP site and JavaScript function that changes a dropdown menu based on specific time intervals, such as 7:00-8:00 (id530), 13:00-15:00 (id1330), or 20:00-03:00 (id2130). For example, if the time is 7:31, the dropdown menu should display/ ...

What is the best way to convert a 2D PHP array into a JavaScript array?

I have encountered a problem with a PHP array setup as follows: $output = array(array(1,1,1,1),array(2,2,2,2),array(3,3,3,3)); When I encoded the array to JSON, I received this output: $output = {"1":[1,1,1,1],"2":[2,2,2,2],"3":[3,3,3,3]} My goal is to ...

What could be causing the "function undefined" error in my HTML document?

Recently, I developed a small chat application that initially functioned well with all code contained in one HTML document. However, after separating the CSS, HTML, and JS into individual files, an issue arose when invoking the register_popup function from ...