Reputation: 5964
An HTML canvas element can be automatically resized by the dynamics of a HTML page: Maybe because its style properties are set to a percentage value, or maybe because it is inside a flex container. Thereby the content of the canvas gets resized as well: Because of the interpolation the canvas content looks blurred (loss of resolution).
In order to keep the resolution to the maximum, one must render the canvas content based on the current pixel size of the element.
This fiddle shows how this can be done with the help of the function getComputedStyle: https://jsfiddle.net/fx98gmu2/1/
setInterval(function() {
var computed = getComputedStyle(canvas);
var w = parseInt(computed.getPropertyValue("width"), 10);
var h = parseInt(computed.getPropertyValue("height"), 10);
canvas.width = w;
canvas.height = h;
// re-rendering of canvas content...
}, 2000); // intentionally long to see the effect
With a setTimeout function I'm updating the width and height of the canvas to the computed values of these properties.
As the fiddle shows, this works only when increasing the size of the window. Whenever the window size gets decreased, the canvas (item of the flexbox) stays fixed.
Upvotes: 4
Views: 2306
Reputation: 288700
Set its flex-basis
to 0, allow it to shrink with flex-shrink
, and don't force any minimum width:
#canvas {
flex: 1 1 0;
min-width: 0;
}
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
setInterval(function() {
var computed = getComputedStyle(canvas),
w = parseInt(computed.width, 10),
h = parseInt(computed.height, 10);
canvas.width = w;
canvas.height = h;
ctx.clearRect(0, 0, w, h);
ctx.beginPath();
ctx.arc(w/2, h/2, h/2, 0, Math.PI*2, true);
ctx.stroke();
}, 2000); // intentionally long to see the effect
#container {
border: 1px solid blue;
width: 100%;
display: flex;
}
#canvas {
border: 1px solid red;
flex: 1 1 0;
min-width: 0;
height: 150px;
}
<div id="container">
<canvas id="canvas"></canvas>
<div>something else...</div>
</div>
Upvotes: 5
Reputation: 27480
You need to place the canvas into a container with overflow:hidden
and set canvas dimensions to dimensions of that container:
window.setTimeout( function() {
var div = $("div");
div.find("canvas").attr( { width:div.width(), height:div.height()} );
})
canvas { background:gold; display:block; }
div { width:50%; height:50%; border:1px solid; overflow:hidden; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<canvas width="200" height="100" />
</div>
Upvotes: 1