Canevas à PPP élevé

Introduction

Les écrans HiDPI sont beaux, ils rendent tout plus fluide et plus propre. Mais ils présentent également un nouvel ensemble de défis pour les développeurs. Dans cet article, nous allons examiner les défis uniques que pose le dessin d'images dans le canevas dans le contexte des écrans HiDPI.

Propriété devicePixelRatio

Commençons par le commencement. Avant les écrans HiDPI, un pixel était un pixel (si nous ignorons un peu le zoom et la mise à l'échelle) et c'est bon, vous n'aviez pas vraiment à changer quoi que ce soit. Si vous définissez un élément sur 100 pixels de large, c'est tout. Puis les premiers téléphones mobiles HiDPI ont commencé à apparaître, avec la propriété devicePixelRatio légèrement énigmatique sur l'objet window, qui pouvait être utilisée dans les requêtes multimédias. Cette propriété nous a permis de comprendre le ratio entre les valeurs de pixel (que nous appelons valeur de pixel logique) dans, disons, CSS et le nombre réel de pixels que l'appareil utiliserait pour le rendu. Dans le cas d'un iPhone 4S avec un devicePixelRatio de 2, vous verrez qu'une valeur logique de 100 pixels équivaut à une valeur de 200 pixels pour l'appareil.

C'est intéressant, mais qu'est-ce que cela signifie pour nous, les développeurs ? Eh bien, au début, nous avons tous commencé à remarquer que nos images étaient améliorées par ces appareils. Nous créions des images à la largeur logique en pixels de nos éléments. Lorsqu'ils étaient dessinés, ils étaient mis à l'échelle par devicePixelRatio et étaient flous.

Image en cours d'amélioration et floutée en raison du devicePixelRatio
Figure 1 : Image en train d'être améliorée et floutée en raison de l'élément devicePixelRatio

La solution de facto a consisté à créer des images agrandies par devicePixelRatio, puis à les réduire de la même quantité à l'aide de CSS. Il en va de même pour le canevas.

function setupCanvas(canvas) {
  // Get the device pixel ratio, falling back to 1.
  var dpr = window.devicePixelRatio || 1;
  // Get the size of the canvas in CSS pixels.
  var rect = canvas.getBoundingClientRect();
  // Give the canvas pixel dimensions of their CSS
  // size * the device pixel ratio.
  canvas.width = rect.width * dpr;
  canvas.height = rect.height * dpr;
  var ctx = canvas.getContext('2d');
  // Scale all drawing operations by the dpr, so you
  // don't have to worry about the difference.
  ctx.scale(dpr, dpr);
  return ctx;
}

// Now this line will be the same size on the page
// but will look sharper on high-DPI devices!
var ctx = setupCanvas(document.querySelector('.my-canvas'));
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.lineTo(200, 200);
ctx.stroke();