Reputation: 257
I have a canvas like so:
But when resizing the window and redrawing, you can get anything in between.
I keep the aspect ratio with this code:
function setCanvasSize(){
ctx.canvas.width = (window.innerWidth)*0.8;
ctx.canvas.height= (window.innerWidth)*0.5;
}
setCanvasSize()
$(window).resize(function(){
setCanvasSize()
})
and that keeps it nice and clean, the same-looking size, but how many pixels are in there changes, so when my program draws, it's always in a different spot, although the aspect is the same, so it looks really weird.
Any way that I can somehow tweak how I draw things, or a way to keep how many pixels there are?
Edit: code snippet to reproduce
const ctx = document.getElementById('game').getContext("2d");
$('#game').css('width', '100%');
$(window).resize(function(){
$('#game').height($('#game').width() / 2.031);
});
const imageAt=((href,x,y,sizex,sizey)=>{
var img = new Image();
img.addEventListener('load', function() {
ctx.drawImage(img, x, y, sizex, sizey);
}, false);
img.src = href
})
imageAt('https://b.thumbs.redditmedia.com/bZedgr0gq7RQBBnVYVc-Nmzdr-5vEUg4Dj8nTrMb7yA.png',0,0,50,50)
#game{
padding-left: 0;
padding-right: 0;
display: block;
margin: 0;
border:5px solid green;
padding:0;
}
#vertical-center {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
background: black;
padding:0;
}
body{
background-color: black;
padding:0;
}
<html>
<head>
<title>Tiled Canvas Engine Test 1</title>
<meta name="viewport" content="width=device-width, initial-scale=0.75">
<link rel="stylesheet" href="./index.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="engine.js"></script>
<script defer src="script.js"></script>
</head>
<body>
<div id="vertical-center">
<canvas id="game"></canvas>
</div>
</body>
</html>
Upvotes: 0
Views: 1497
Reputation: 20150
In order to render properly the canvas
element needs to have its width
and height
attributes set explicitly. This will define the viewport into which graphics will be draw. The style attributes for width
and height
which is what jQuery sets via the width()
and height()
functions will only stretch the viewport to fit. (Note: for high DPI displays, i.e. Retina, you will want to double the dimensions when specifying the attributes).
The critical change is this:
// Updates the actual width and height attributes
canvas.width = $('#game').width() * window.devicePixelRatio;
canvas.height = $('#game').height() * window.devicePixelRatio;
The snippet below also handles clearing the canvas, redrawing the image, and saving the Image once loaded:
const ctx = document.getElementById('game').getContext("2d");
$('#game').css('width', '100%');
$(document).ready(handleResize);
$(window).resize(handleResize);
function handleResize() {
// sets the style.height and style.width for the canvas
$('#game').height($('#game').width() / 2.031);
let canvas = $('#game').get(0);
// Updates the actual width and height attributes
canvas.width = $('#game').width() * window.devicePixelRatio;
canvas.height = $('#game').height() * window.devicePixelRatio;
// redraw
if (img) {
redraw();
}
}
var img;
const imageAt = ((href, x, y, sizex, sizey) => {
img = new Image();
img.addEventListener('load', function() {
ctx.drawImage(img, x, y, sizex, sizey);
}, false);
img.src = href
})
imageAt('https://b.thumbs.redditmedia.com/bZedgr0gq7RQBBnVYVc-Nmzdr-5vEUg4Dj8nTrMb7yA.png', 0, 0, 50 * window.devicePixelRatio, 50 * window.devicePixelRatio)
function redraw() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(img, 0, 0, 50 * window.devicePixelRatio, 50 * window.devicePixelRatio);
}
#game {
padding-left: 0;
padding-right: 0;
display: block;
margin: 0;
border: 5px solid green;
padding: 0;
}
#vertical-center {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
background: black;
padding: 0;
}
body {
background-color: black;
padding: 0;
}
<html>
<head>
<title>Tiled Canvas Engine Test 1</title>
<meta name="viewport" content="width=device-width, initial-scale=0.75">
<link rel="stylesheet" href="./index.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="engine.js"></script>
<script defer src="script.js"></script>
</head>
<body>
<div id="vertical-center">
<canvas id="game"></canvas>
</div>
</body>
</html>
Upvotes: 1