简体   繁体   中英

Responsive canvas keeping given aspect ratio

I'm developing a drawing app, and I've encountered a problem which I have been trying to solve but I haven't found a reliable solution yet:

Sketches have an original resolution of 1280 x 720, and I would like to resize the canvas when the page is opened to the maximum size possible (given the screen dimensions minus a toolbar I have put on the upper side of the page) keeping the 1280 x 720 aspect ratio . The canvas needs to be centered in the screen and black stripes will cover the rest: when the the browser window dimensions relation is less than the sketch original w/h relation there will be horizontal black stripes (fig 1 ), and when it is bigger, vertical black stripes (fig 2 ).

I've tried using javascript applying to the canvas the offsetWidth and offsetHeight of a div containing an auxiliar invisible image which I generate programatically with the original sketch dimensions, but doesn't seem to be a robust way to do this. Most of the time the offset properties aren't ready when the page is loaded and I have to wait for them using a timer (or mutation observers).

Some images of what I'm trying to do:

I've spend much time on this little thing and is driving me crazy, because every solution I found is way too hacky or unreliable. Any help will be very appreciated.

I'm using Angular + Ionic 4.

If I'm understanding you correctly, you want to dynamically change the size of your canvas based on how big the window is. The one stipulation is that it must maintain the 1280 x 720 (1:0.5625) ratio.

I'm going to attempt to provide a solution that will also listen for resizing of the window after it's been loaded. Keep in mind that this means you'll need to redraw everything on the canvas from there.

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 every time the window is adjusted
  window.addEventListener('resize', resizeCanvas, false);
  // manually call the resizeCanvas() function as the window loads with it's starting dimensions (before a resize has happened)
  resizeCanvas();
}

function resizeCanvas() {
  // if the canvas height isn't maxed out, match it to the width of the page at the correct aspect ration (1:0.5625)
  if(canvas.height < window.innerHeight){
    canvas.width = window.innerWidth;
    canvas.height = canvas.width * 0.5625;
  }
  
  // if the canvas height is maxed out, stop widening the canvas and lock the canvas height at 0.5625 of that locked height
  if(canvas.height >= window.innerHeight){
    canvas.height = canvas.width * 0.5625;
  }
  
  // lastly, if we are shrinking the width back down, readjust both the width and height to match
  if(canvas.width > window.innerWidth){
    canvas.width = window.innerWidth;
    canvas.height = canvas.width * 0.5625;
  }
  // redraw the canvas with our newly calculated dimensions
  redraw();
}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM