This question already has answers here:
Canvas is stretched when using CSS but normal with "width" / "height" properties
(10 answers)
Closed 3 years ago.
So my rectangle i want to draw on a canvas are, i think scaled to the size of the canvas. I i want them to be 8x8 they dont come out as 8x8.
Here's my code:
function draw() {
var canvas = document.getElementById('karte');
var ctx = canvas.getContext("2d");
Stuttgart = ctx.fillRect(10,10,8,8);
}
.map {
height: 799px;
width: 591px;
margin: auto;
margin-top: 50px;
background-image: url('../img/Karte_Deutschland.svg');
background-repeat: no-repeat;
background-size: contain;
background-position: center;
}
.map canvas {
height: 799px;
width: 591px;
}
<canvas id="karte">
</canvas>
Here's a screenshot how it looks like in the end: https://prnt.sc/r58bvl
For now you set the canvas width and height on the screen different then the canvas actual width and height (which is 300/150 by default) it is why anything scaled for you. so :
Eather add the height and width to the canvas:
<canvas id="karte" height="799" width="591"><canvas>
Or add it manually in the js:
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight
Related
PaperJS has documentation how to setup the canvas in to resize the canvas when the window changes dimensions. The same solution can be found in this SO answer.
The problem with this approach is that it will change the coordinates while drawing, and also it will be resizing the canvas, which can be less performant.
I would like to scale the canvas without changing the width of the element. The problem I found is that PaperJS adds a width and height to the canvas element in runtime, and I could not find a way to stop this behaviour, this will result the calculated value when the setup is done, and could be for instance:
width="817" height="817"
Here is an example of a HTML Canvas that behaves the way I intend, and also the PaperJS version which does not scale. Resize the browser window to see how the example in the bottom will stretch the canvas content, but keeping the circle in the center of the canvas.
I would like to find a way to configure PaperJS that would work in the same way, without having to change the draw coordinates inside a onResize handler.
Is this possible?
const SIZE = 150;
window.onload = () => {
// --- Paperjs ---
const canvas = document.getElementById('paper');
paper.setup(canvas);
// draw circle in the center of the view
const c = new paper.Path.Circle(new paper.Point(SIZE, SIZE), SIZE);
c.strokeColor = 'white';
c.strokeWidth = 3;
// --- END Paperjs ---
// --- Canvas ---
const ctx = document.querySelector("#canvas").getContext("2d");
ctx.strokeStyle = "#FFFFFF";
ctx.fillStyle = "white";
ctx.lineWidth = 3;
ctx.beginPath();
// x, y, width
ctx.arc(SIZE, SIZE, SIZE, 0, 2 * Math.PI);
ctx.stroke();
// --- END Canvas ---
}
.wrapper {
margin-left: 10vw;
width: 80vw;
border: 1px solid cyan;
}
.responsive-canvas {
background-color: silver;
max-width: inherit;
max-height: inherit;
height: inherit !important;
width: inherit !important;
object-fit: contain;
}
* {
margin: 0;
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.17/paper-full.min.js"></script>
<h2>PaperJS</h2>
<div class="wrapper">
<canvas id="paper" class="responsive-canvas" width="300px" height="300px"></canvas>
</div>
<h2>Canvas</h2>
<div class="wrapper">
<canvas class="responsive-canvas" id="canvas" width="300px" height="300px"></canvas>
</div>
This question already has answers here:
Canvas is stretched when using CSS but normal with "width" / "height" properties
(10 answers)
Closed 6 months ago.
I specified the image dimensions to be 50px by 50px but it is stretched on the y axis like this.
Stretched Image
I think it may have something to do with the css styling so here is my css code.
canvas {
background-color: green;
padding: 0;
margin: auto;
display: block;
height: 700px;
width: 700px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
Please tell me why the image is stretched.
css width and height doesn't update the initial aspect ratio of canvas, which is introduced to the element by the attributes like this: <canvas width="X" height="Y">
If the size of your canvas is fixed, you should change the width and height of the canvas tag attributes.
If it's not constant, you may need to use Javascript to update it, like this:
const canvasDom = document.getElementById('mycanvas');
canvasDom.setAttribute('width', '700');
canvasDom.setAttribute('height', '700');
I am practicing javascript and I am trying to make a game. I want the canvas element to be fullscreen, so I used percentages for the height and width attribute, but when I do, it doesn't behave like it normally does. When I run my debug code, it is supposed to make a box that is 50px by 50px, but the graphics look bigger than normal.
I've tried getting the canvas height and width in pixels, but that did not work. It does not report any error messages, but it is still too big.
<!DOCTYPE html>
<html>
<head></head>
<body>
<canvas id="canvas" style="height: 100%; width:100%;"></canvas>
</body>
<style>
html, body {width: 100%;
margin: 0;
height: 100%;
overflow: hidden;
position:fixed;}
</style>
<script>
var canvas = document.getElementById("canvas")
var c = canvas.getContext("2d")
c.fillStyle = "#FFFF00"
c.fillRect(50,50,50,50)
</script>
There are no error messages none appearing, but it is not sized correctly, and I can't figure out why it's not working.
It makes a difference if canvas size is set in CSS or using element attributes.
The canvas element size is set by its width and height attributes (as numbers). This sets the number of addressable pixels used to store the canvas drawing in memory. In the absence of width and height attributes, canvas element dimensions are set to 300 by 150 (pixels) by default.
CSS applied to the canvas can scale its dimensions using software interpolation of the canvas treated as an image. Just as a small image looks bigger when scaled to full screen, both the 300 by 150 pixel canvas and objects drawn within it (using canvas pixel coordinates) appear larger when blown up.
To make canvas coordinates match the screen size in pixels, set its width and height attributes to pixel number values. E.G.
var canvas = document.getElementById("canvas")
var c = canvas.getContext("2d")
c.fillStyle = "#FFFF00"
c.fillRect(50,50,50,50)
console.log( canvas.width, canvas.height);
alert( "fix?" )
canvas.style=""; // remove CSS scaling
canvas.width = document.body.clientWidth;
canvas.height = document.body.clientHeight;
c.fillStyle = "#FFFF00"
c.fillRect(50,50,50,50)
body {
width: 100%;
margin: 0;
height: 100%;
background-color: honeydew;
overflow: hidden;
position:fixed;
}
canvas {
background-color: silver;
}
<canvas id="canvas" style="height: 100%; width:100%;"></canvas>
I can't seem to get my canvas to be perfectly responsive.
Using 100% or 100vmax for height and width makes it responsive but it looses clarity.
The center of the canvas seems to be at the bottom of the page as if the canvas stretches beyond the screen
canvas when width is set to 100% or 100vmax
Canvas when width is set through javaScript NOT RESPONSIVE
You'll need to know the aspect ratio of the canvas to do this. You can't simply apply 100% width and height as that will stretch to 100% width and 100% height of the body.
Example:
Lets say I have a Canvas with the dimensions of 864 x 576 and I want it to be responsive to the full body.
Find the percentage/ratio of the canvas. To do this you can do it manually or through JavaScript. In this example lets do it manually for a non-changing image.
ratio = width / height * 100
So here our ratio will be ratio = 864 / 576 * 100 that would be 150% (as in 1.5:1 or 3:2)
We now add the styles using the viewport height vh.
canvas
{
display: block;
margin: auto;
width: 150vh;
height: 100vh;
}
Now one problem remains. What if the window width is smaller than the canvas? Okay, we create a CSS media query and do the opposite of what we've done.
ratio = (height / width) * 100
So here our ratio will now be ratio = 576 / 864 * 100 that would be 66.66% (as in 0.66:1 or 7:10)
We need to use the viewport width now for the canvas width and height. width is always 100vh.
#media (max-width: 150vh)
{
canvas
{
width: 100vw;
height: 66.66vw;
}
}
The max-width media query needs to be equal to the canvas width, which is 150vh in this example.
Take a look at the code: https://codepen.io/StudioKonKon/pen/oQobaa
var image = "https://res.cloudinary.com/studiokonkon/image/upload/v1541450918/sample.jpg";
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
canvas.width = 864;
canvas.height = 576;
var background = new Image();
background.src = image;
// Make sure the image is loaded first otherwise nothing will draw.
background.onload = function()
{
ctx.drawImage(background,0,0);
}
body { margin: 0; padding: 0; background: #000; }
.mycanvas
{
display: block;
margin: auto;
width: 150vh;
height: 100vh;
}
#media (max-width: 150vh)
{
.mycanvas
{
width: 100vw;
height: 66.66vw;
}
}
<canvas id="canvas" class="mycanvas"></canvas>
Please be aware support of the vh and vw units are only supported in the latest browsers and assuming you don't care about Internet Explorer.
https://caniuse.com/#feat=viewport-units
This question already has answers here:
Canvas is stretched when using CSS but normal with "width" / "height" properties
(10 answers)
Closed 5 years ago.
I have a canvas tag without width and height attributes. The canvas has inline width and height. Now when I apply linearGradient over it, it doesn't cover whole canvas. Demo:
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var gradient1 = ctx.createLinearGradient(0, 0, 150, 0);
gradient1.addColorStop(0, "#123456");
gradient1.addColorStop(1, "#654321");
ctx.fillStyle = gradient1;
ctx.fillRect(0, 0, 150, 100);
canvas {
border: 1px dotted red;
}
<canvas id="canvas" style="width: 150px; height: 100px;"></canvas>
Question1: Why doesn't whole 150px of canvas get covered? And if I add width="150" and height="100" attributes on canvas tag, why does it then fill whole canvas?
Question 2: In below script c.width returns 300px not 150px, why?
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
console.log(c.width);
console.log(c.height);
canvas {
border: 1px dotted red;
}
<canvas id="canvas" style="width: 150px; height: 100px;"></canvas>
Question3: Is this behavior due to something similar to svg viewBox?
I'm not sure why the inline styling isn't working, but if you change your canvas element to this:
<canvas id="canvas" width="150px" height= "100px;"></canvas>
Then the console logs the correct value and the gradient fills the canvas. :) I don't know why you can't use the other method, but I do know that everywhere I've seen I think everyone who uses the html canvas specifies the width and height in this way. (unless they specify it in the javascript)
Here's a pen of your working code: https://codepen.io/Awesomennjawarrior/pen/zwmmPY