Redimensionnement dynamique d'un canvas

Propriété resize de css

La propriété css: resize permet de spécifier si un élément est redimensionnable interactivement par l'utilisateur. Les options de resize, voir par exemple sur w3schools, sont none, l'utilisateur ne peut pas interagir avec les dimensions de l'élément visé, horizontal, vertical ou both, l'utilisateur peut redimensionner l'élément dans la direction précisée, ou les deux, et enfin initial ou inherit, la valeur est celle par défaut ou celle de son élément parent. par exemple le cadre suivant


obtenu simplement via:
<div id="ex" style="width:300px;height:50px;border:2px solid blue;overflow:auto;resize:horizontal"></div>

Resize et canvas

Maintenant, il est intéressant aussi, et c'est ce dont traite la suite de cette page,
  • interagir avec ce redimsensionnement, via javascript, par exemple sur le contenu qui pourrait devoir s'adapter à son nouveau cadre (image par exemple),
  • appliquer ce redimensionnement à un canvas: en effet cette propriété ne s'applique pas directement à un tel élément, il faut ruser un peu.
La méthode proposée est la suivante:
  • encapsulé le canvas dans un autre élément, div par exemple, qui a des dimensions initiales renseignées et à qui on peut appliquer la propriété css: resize;
  • dans cet élément encapsulant, on définit aussi les événements onmousedown et onmouseup qui vont définir l'interaction d'avec l'utilisateur
  • à l'intérieur, donc, le canvas, sans propriété particulière
  • tout se passe ensuite en javascript: on récupère les dimensions au fur et à mesure de l'élément extérieur: ici via la fonction newSize, qu'on exécute ici toutes les 50 ms (avec un setInterval) tant que l'utilsateur maintient le click de sa souris.
    On propage ensuite ces dimensions au canvas, pour lequel on redessine le contenu (fonction ReDraw).
    Enfin, en relâchant le click de la souris, on cesse l'écoute (avec clearInterval) en fond des dimensions.

Le résultat:

Et le code html/css/javascript

<div id="Overcnv" 
  style="width:400px;height:300px;border:1px solid red;overflow:hidden;resize:both" 
  onmousedown="sI=setInterval('newSize()',50);" 
  onmouseup="clearInterval(sI);">
  <canvas id="cnv" style="border:1px solid black"></canvas>
</div>
et pour le javascript, gestion des dimensions et du dessin:
<script>
Width=document.getElementById("Overcnv").clientWidth;
Height=document.getElementById("Overcnv").clientHeight;
document.getElementById("cnv").width=Width-2;
document.getElementById("cnv").height=Height-2;
cnv = document.getElementById("cnv");
ctx = cnv.getContext("2d"); 

function newSize() {
  Width=document.getElementById("Overcnv").clientWidth;
  Height=document.getElementById("Overcnv").clientHeight;
  document.getElementById("cnv").width=Width-2;
  document.getElementById("cnv").height=Height-2;
  ReDraw(Width,Height);
}

function ReDraw(Width,Height) {
 ctx.fillStyle = "blue";ctx.strokeStyle = "blue";ctx.lineWidth=3;
 ctx.beginPath();ctx.moveTo(3,3);ctx.lineTo(Width-50,Height/2);ctx.stroke();
}

ReDraw(Width,Height);
</script>