Maintaining aspect ratio of canvas while ensuring responsiveness

Currently, I am working on a drawing app and have come across an issue that has been challenging for me to resolve. The dilemma lies in resizing the canvas of sketches from the original resolution of 1280 x 720 to the maximum size possible upon opening the page. This resizing should maintain the 1280 x 720 aspect ratio, while also accounting for a toolbar located at the top of the page.

The goal is to center the canvas on the screen, with black stripes filling the remaining space based on the dimensions of the browser window. If the window's aspect ratio is less than that of the sketch, horizontal black stripes will be displayed (see fig 1). Conversely, if the aspect ratio is greater, vertical black stripes will be shown (refer to fig 2).

To tackle this challenge, I experimented with JavaScript by calculating the offsetWidth and offsetHeight of a div containing a programmatically generated invisible image matching the original sketch dimensions. However, relying solely on these properties proved to be unreliable as they were not consistently ready when the page loaded, necessitating the use of timers or mutation observers.

I have dedicated significant time to finding a robust solution to this problem, but each approach I discovered seemed either too hacky or prone to errors. Any assistance or suggestions would be greatly appreciated as I work within the Angular + Ionic 4 framework.

Answer №1

If my interpretation is correct, you are looking to dynamically adjust the size of your canvas based on the window's dimensions while maintaining a 1280 x 720 (1:0.5625) aspect ratio.

Here, I will present a solution that listens for window resizing even after it has loaded, requiring you to redraw all content on the canvas accordingly.

HTML

<body>
  <canvas id="canvas"></canvas>
</body>

CSS

body {
  background-color: black;
}

JavaScript:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

startListening();

function startListening() {
  // Resize the canvas each time the window is adjusted
  window.addEventListener('resize', resizeCanvas, false);
  // Manually trigger the resizeCanvas() function when the page loads to set initial dimensions
  resizeCanvas();
}

function resizeCanvas() {
  // Adjust canvas height according to window width while maintaining 1:0.5625 aspect ratio
  if(canvas.height < window.innerHeight){
    canvas.width = window.innerWidth;
    canvas.height = canvas.width * 0.5625;
  }
  
  // When canvas height reaches maximum, keep it locked and maintain 0.5625 height ratio
  if(canvas.height >= window.innerHeight){
    canvas.height = canvas.width * 0.5625;
  }
  
  // If narrowing the width, readjust both width and height accordingly
  if(canvas.width > window.innerWidth){
    canvas.width = window.innerWidth;
    canvas.height = canvas.width * 0.5625;
  }
  // Redraw the canvas with updated dimensions
  redraw();
}

function redraw() {
  ctx.fillStyle = "#FF0000";
  // Draw the canvas in center of screen using dimensions from resizeCanvas()
  ctx.fillRect((window.innerWidth - canvas.width) / 2, (window.innerHeight - canvas.height) / 2, canvas.width, canvas.height);
}

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

Unexpected outcomes arise when parsing headers from a file-based stream

Currently, I am in the process of creating a small parser to analyze some log files using node streams (more specifically io.js). I have been referring to the documentation for unshift to extract the header. While I can successfully divide the buffer and ...

Unexpected Issue with JavaScript Ajax (Using jQuery.post): The Promise State Turns to "Rejected"

Recently, I've been encountering some issues while trying to debug my jQuery.post() call. The responses I'm getting are quite puzzling and I'm at a loss on how to proceed next. If anyone has any suggestions or insights, I would greatly appre ...

Incorporate the variables specified in the parent PHP file into the PHP code being received through

I am currently working on a project that involves enabling a user to view his profile upon login. However, I am aiming to have the dashboard load all other profile pages through ajax, such as the view profile and edit profile pages. My progress so far inc ...

Execute the controller function with the value as a parameter

I encountered an issue while attempting to call a function in the c# controller and passing a value. The error message I received was: `'Unable to get property 'then' of undefined or null reference'. I also included the Driver Model but ...

Adding query parameters to the end of every link on a webpage

Wondering how to automatically add GET values to the end of each anchor href on a webpage? For instance, if you input google.com?label=12&id=12 I want to ensure that "?label=12&id=12" gets added to the end of every single href in an anchor tag on ...

Accordion section appears on the webpage as it is loaded

I am currently working on implementing an accordion feature for my webpage. Everything is functioning correctly when I click the button, but there is one issue - the div opens automatically when the page loads. My goal is to have the div closed initially a ...

Sending a JSON array in an AJAX request results in receiving null values in an MVC application

I've been trying to send an array of JSON objects to my controller action, but it keeps showing up as null. Here's the JavaScript code I'm using: function UpdateSelected() { var items = {}; //Loop through grid / sub grids and crea ...

Encountering an issue with the autocomplete feature in the jQuery library where it is stating "this.source is not a function."

Here's the code snippet I'm working with: $.ajax({ type: "GET", url: "https://url.com", dataType: "json", success: function (data) { $("#search").autocomplete({ source: data, select: function (even ...

Creating a library in Angular2 with multiple routes: a step-by-step guide!

Having recently delved into Angular2, I find myself in need of building a reusable library to be utilized by multiple applications as an html tag. This library will consist of various pages such as search, create, edit, etc., each requiring different rout ...

Prevent Click Event in JQuery

I have a requirement to disable all click events on my webpage. However, even after using the appropriate code to prevent these events from firing, some of them are still getting called. Let me explain with an example. <div id='parent'> ...

Troubleshooting issue: AngularJS NVD3 line chart directive does not refresh after data update (not updating in real time)

I am currently facing an issue with the nvd3-line-chart directive in my AngularJS application. The chart does not redraw when I change the underlying model... As a newcomer to AngularJS, there may be something obvious that experienced programmers will not ...

An unexpected error occurred: [$injector:modulerr] (unidentified)

My website is running smoothly with AngularJS on one page, but I'm encountering an error in the console on other pages that do not use AngularJS. The error message reads: Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.3.13/$in ...

Guide on invoking an API with a private IP on an EC2 instance

I successfully deployed an Angular app and a Java REST-API on my ec2-instance. When accessing the Java REST-API via the public IP in my Angular app, everything works fine. However, if I try to use the private IP of my instance, it results in a connection ...

Creating a seamless thread using AngularJS

I am working on a Spring MVC application that utilizes HTML and Angular on the client side. I have a method in my Angular controller that needs to run every 5 seconds. How can I achieve this using Angular? Thank you for your assistance. $scope.inspectio ...

Jquery-ajax fails to accomplish its task

I am just starting to learn about ajax and recently created a simple page on my local server to practice sending and receiving data from/to a JSON file in the same directory. Although the GET method is working perfectly fine, I am having trouble understan ...

Ways to show a div when a dropdown option is selected

Currently, I am in the process of designing a form that includes a dropdown menu. Once the user selects a particular option from the list, such as: Software developer a new section will be displayed, showing two additional options: App Developer ...

"Utilize Python's Selenium library to automate clicking the 'Get Data

Having trouble with clicking the GetData button to retrieve the output. Looking for assistance on how to achieve this. Update your code below:- from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.chrome.o ...

Troubleshooting Vue.js rendering problems on Safari_BROWSER

I'm encountering a strange issue with my portfolio website, which is built using Vue and Laravel. The problem arises specifically in Safari - the project thumbnails don't display until the browser window is resized. Here's the relevant code ...

Checking for offline status in a Cordova app using Angular

I have implemented the following code to determine whether my Cordova application is online or offline. var networkState = navigator.connection.type; var states = {}; states[Connection.UNKNOWN] = 'Unknown'; states[Connection.ETHERNET] = ' ...

Modify the background color of <td> elements depending on the specific value

I attempted to implement this approach, but unfortunately it is not working as expected. I found guidance from this source. Below is the code I am using: $today = date('Y-m-d'); $date = new DateTime(); $R1D2 = $date->setISODate($year,$week,1 ...