Reputation: 10685
I'm working on a small webpage that generates a figure based on user input. I plan to place a canvas
in the html
code, and to use javascript
to create the image. The problem I have is that the canvas
size as defined in the css
file seems to only scale a small canvas
and not to actually create a bigger one. This is my html
code
function test() {
var canvas = document.getElementById("canvas");
if (null == canvas || !canvas.getContext) return;
ctx = canvas.getContext("2d");
for (var i = 0; i <= canvas.width; i += 50) {
for (var j = 0; j < canvas.height; j += 20) {
ctx.fillText(j, i, j);
}
}
}
body {
background-color: rgba(0, 100, 100, 0.2);
width: 100%;
}
canvas {
width: 100%;
}
<html>
<head>
<meta charset="utf-8">
<title>
Test
</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0,
maximum-scale=1.0, user-scalable=no" />
<link rel="stylesheet" href="css/styles.css">
<script language="javascript" type="text/javascript" src="js/worker.js">
</script>
</head>
<body onload="test()">
<canvas id="canvas"></canvas>
</body>
</html>
The output, looks like this (The same happens when I replace the width
of the canvas
in the css
file to 100%
)
why wouldn't I get smaller numbers that go up to 700?
Upvotes: 2
Views: 430
Reputation: 380
Use Javascript to set the canvas width and height using window.innerWidth
& window.innerHeight
.
This will match the viewport of the device.
function test() {
var canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
if (null == canvas || !canvas.getContext) return;
ctx = canvas.getContext("2d");
for (var i = 0; i <= canvas.width; i += 50) {
for (var j = 0; j < canvas.height; j += 20) {
ctx.fillText(j, i, j);
}
}
}
Upvotes: 0
Reputation: 78520
Your mystery width and height are coming from the canvas default values in the absence of width
and height
attributes. These default values are 300 for width and 150 for height. Read more on the HTMLCanvasElemnet here.
To correct this behaviour, you can either give it a static width and height using those attributes (not ideal), or you can set the width and height with javascript. I suggest using offsetWidth
and offsetHeight
properties. It will also be necessary to set these values whenever the window resizes. That can be done with an event listener. Here's a demo:
https://jsfiddle.net/f7btghdr/2/
var canvas = document.getElementById("canvas");
ctx=canvas.getContext("2d");
function test() {
for (var i=0; i <= canvas.offsetWidth; i += 50){
for (var j=0; j <= canvas.offsetHeight; j += 20){
ctx.fillText(i + 'x' + j,i,j);
}
}
}
function adjustCanvas() {
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.textBaseline="top";
test();
}
window.addEventListener('resize', adjustCanvas);
adjustCanvas();
html, body, canvas {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
display: block;
}
<canvas id="canvas"></canvas>
Per Kaiido's comments below, the following snippet is probably a better approach to this. Of note, the clearRect
call was superfluous, getBoundingClientRect
should give more precise values for the width and height of the canvas, and the canvas CSS is also unnecessary (it gets overridden with the width
and height
properties right away anyway). Below is a revised demo with these changes in place.
var canvas = document.getElementById("canvas");
ctx=canvas.getContext("2d");
function test() {
for (var i=0; i <= canvas.offsetWidth; i += 50){
for (var j=0; j <= canvas.offsetHeight; j += 20){
ctx.fillText(i + 'x' + j,i,j);
}
}
}
function adjustCanvas() {
var dimensions = canvas.parentNode.getBoundingClientRect();
canvas.width = dimensions.width;
canvas.height = dimensions.height;
ctx.textBaseline="top";
test();
}
window.addEventListener('resize', adjustCanvas);
adjustCanvas();
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
display: block;
}
.canvas-wrapper {
width: 100%;
height: 100%;
overflow: hidden;
}
canvas {
display: block;
}
<div class="canvas-wrapper">
<canvas id="canvas"></canvas>
</div>
Upvotes: 3