Reputation: 1499
I have a div containing a canvas:
<div class="canvas-wrapper">
<canvas height="30px"></canvas>
</div>
The CSS for the "canvas-wrapper" class:
.canvas-wrapper{
width: 100%;
overflow: hidden;
}
Whenever the width of the div changes, the canvas width is updated (Angular directive):
link: function(scope, element, attr){
var canvas = element.find('canvas')[0];
var div = element.find('div')[0];
scope.$watch(function(){
return div.offsetWidth;
}, function(newVal, oldVal){
canvas.width = newVal;
});
}
I've tested this by resizing the browser width. It works fine when I increase the window, but when I decrease the window the div will not resize.
I guess that's because it contains the canvas, but how can I get around this? The canvas is supposed to follow the div width, not block resizing.
Any ideas?
Upvotes: 1
Views: 3796
Reputation: 550
Thanks to the answer from Spencer Evans.
I was able to add (in the resize event) the 1x1 px and it works.
$(self.canvas).attr('width', 1)
$(self.canvas).attr('height', 1);
self.dimension = (self.el.width() >= self.el.height() ? self.el.height() : self.el.width());
Upvotes: 1
Reputation: 489
You're correct when you said: "[the div doesn't decrease] I guess that's because it contains the canvas"
The accepted answer suggests using the css width property with a caveat that the canvas will stretch. This is also completely correct; the canvas will stretch.
You might want the canvas to stretch, but this is usually not desirable. For completeness, here is an answer to actually resize the canvas.
For best results, you need to use the following logic:
Steps
The last step, redrawing graphics, is really important. A detailed explanation on how to redraw graphics with the correct scaling can be found here: html5 canvas redraw on resize
Demo
A demo of this logic working can be found here: http://spencer-evans.com/share/github/canvas-resizer/
JavaScript Solution
In JavaScript, a solution is:
// Call this every time the canvas resizes
function resizeCanvas()
{
// Grab the canvas and it's parent div
var canvas = document.getElementById("myCanvasId");
var parent = canvas.parentNode;
// Hide the canvas so we can get the parent's responsive bounds
var displayBackup = canvas.style.display;
canvas.style.display = "none";
// Measure parent without the canvas
var w = parent.clientWidth;
var h = parent.clientHeight;
// Set the new canvas dimensions
canvas.width = w;
canvas.height = h;
// Restore the canvas display property
canvas.style.display = displayBackup;
// IMPORTANT: Call code here to redraw canvas graphics!
}
Library Solution
This can be cumbersome and I've ran into it time and time again. I've written a small JS / typescript library to handle this. You can find the library here: https://github.com/swevans/canvas-resizer
The library also has the benefit of re-sizing the canvas to match high resolution displays where devicePixelRatio is not equal to 1 (ie Retina displays).
Upvotes: 4
Reputation: 46323
You could add a CSS width of 100% to the canvas element.
While resizing a canvas via CSS is usually not a good practice as it stretches / shrinks the "image inside the canvas", if it's in sync with the canvas width & height properties there's nothing wrong with it.
You can solve that inline:
<div class="canvas-wrapper">
<canvas height="30px" style="width: 100%;"></canvas>
</div>
Or use whatever CSS selection method you prefer instead.
Upvotes: 5