Canevas à PPP élevé

Introduction

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

Propriété devicePixelRatio

Commençons par le début. Avant les écrans HiDPI, un pixel était un pixel (si nous ignorons le zoom et la mise à l'échelle pendant un peu), et c'est tout, vous n'avez pas vraiment besoin de changer quoi que ce soit. Si vous choisissez une largeur de 100 pixels, c'est tout ce dont vous avez besoin. Ensuite, les premiers téléphones mobiles HiDPI ont commencé à apparaître avec la propriété devicePixelRatio légèrement énigmatique sur l'objet de fenêtre et disponible pour une utilisation dans les requêtes média. Cette propriété nous a permis de comprendre le rapport entre la façon dont les valeurs de pixels (appelées valeurs logiques des pixels) en CSS se traduisaient par le nombre réel de pixels que l'appareil utiliserait pour le rendu. Dans le cas d'un iPhone 4S, dont le devicePixelRatio est de 2, vous constaterez qu'une valeur logique de 100 pixels équivaut à une valeur d'appareil de 200 pixels.

C'est intéressant, mais qu'est-ce que cela signifie pour nous, développeurs ? Eh bien, dès le 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 et, lorsqu'elles étaient dessinées, elles étaient améliorées par le paramètre devicePixelRatio et elles seraient floues.

Image en cours d'amélioration et de floutage en raison du paramètre devicePixelRatio
Figure 1 : Image mise à l'échelle et floutée en raison du paramètre devicePixelRatio

La solution de facto consistait à créer des images mises à l'échelle à l'aide d'un devicePixelRatio, puis à utiliser du code CSS pour les réduire dans les mêmes proportions. Il en va de même pour les 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();