Tailles de canvas et WebGL

Dans cet exemple, on observe l'effet obtenu quand on définit (ou non) la taille du canevas HTML avec sa taille CSS (exprimée en pixels CSS), tel qu'il apparaît dans la fenêtre du navigateur.

Les effets liés à la taille du canevas sur le rendu avec WebGL

Grâce aux méthodes scissor() et clear() on peut démontrer que le tampon (buffer) de dessin WebGL est affecté par la taille du canevas (l'élément HTML canvas).

La taille du premier canevas est définie avec la taille de l'élément, mis en forme, qui est déterminée par CSS. Pour cela, on affecte respectivement les valeurs clientWidth and clientHeight aux propriétés width et height.

Pour le deuxième canevas, on n'applique pas ce traitement, c'est donc les dimensions internes du canevas : width et height qui sont prises en compte. Celles-ci sont différentes des dimensions de l'élément canvas affiché dans le fenêtre du navigateur.

L'effet devient visible quand on utilise les méthodes scissor() et clear() pour dessiner un carré au centre du canevas en définissant sa position et sa taille en pixels. Dans le premier canevas, on obtient bien le bon résultat et dans le deuxième, on a la mauvaise forme, la mauvaise taille et la mauvaise position.

html
<p>On compare les deux canevas.</p>
<canvas
  >Votre navigateur ne semble pas supporter l'élément HTML5 canvas.</canvas
>
<canvas
  >Votre navigateur ne semble pas supporter l'élément HTML5 canvas.</canvas
>
css
body {
  text-align: center;
}
canvas {
  width: 120px;
  height: 80px;
  margin: auto;
  padding: 0;
  border: none;
  background-color: black;
}
js
window.addEventListener(
  "load",
  function () {
    "use strict";
    var firstCanvas = document.getElementsByTagName("canvas")[0],
      secondCanvas = document.getElementsByTagName("canvas")[1];

    // Ici on applique le traitement spécifique au premier
    // canevas
    firstCanvas.width = firstCanvas.clientWidth;
    firstCanvas.height = firstCanvas.clientHeight;

    // Ensuite on traite les deux canevas de la même façon
    [firstCanvas, secondCanvas].forEach(function (canvas) {
      var gl =
        canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
      if (!gl) {
        document.querySelector("p").innerHTML =
          "Échec de l'obtention du contexte WebGL. " +
          "Votre navigateur peut ne pas supporter WebGL.";
        return;
      }
      gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
      gl.enable(gl.SCISSOR_TEST);
      gl.scissor(30, 10, 60, 60);
      gl.clearColor(1.0, 1.0, 0.0, 1.0);
      gl.clear(gl.COLOR_BUFFER_BIT);
    });
  },
  false,
);

Le code source de cet exemple est également disponible sur GitHub.