My goal is to have an HTML/CSS layout that fills available space with a few elements, but having a 2d canvas element as large as possible in that space.
CSS flexbox provides the ability to get the desired layout. However, when the CSS size of the canvas changes the backing store of the canvas must be redrawn so that the canvas isn't simply distorted (either a low resolution image stretched too large, or a high resolution image squashed down and loosing details).
The following code (code on jsfiddle) nearly accomplishes this goal, but the canvas is not redrawn when the size of the canvas changes due to CSS3 animations.
HTML:
<button>I'm a button</button>
<canvas id="c"></canvas>
<p>text.</p>
CSS:
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
flex-direction: column;
}
canvas {
flex: auto;
align-self: stretch;
}
button {
align-self: center;
transition:padding 2s;
}
button:hover {
padding: 3em;
}
Javascript:
function redraw() {
var cc = c.getContext("2d");
c.width = c.clientWidth;
c.height = c.clientHeight;
cc.scale(c.width, c.height);
cc.beginPath();
cc.arc(0.5, 0.5, .5, 0, 2 * Math.PI);
cc.fill();
}
// update on any window size change.
window.addEventListener("resize", redraw);
// first draw
redraw();