Canevas à PPP élevé

Introduction

Les écrans HiDPI sont magnifiques. Ils rendent tout plus fluide et plus net. 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 que pose le dessin d'images dans le canevas dans le contexte des écrans HiDPI.

Propriété devicePixelRatio

Commençons par le commencement. Avant l'arrivée des écrans HiDPI, un pixel était un pixel (si nous ignorons le zoom et la mise à l'échelle pour un moment). Il n'était pas nécessaire de modifier 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, disponible pour 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, dont le devicePixelRatio est de 2, vous constaterez qu'une valeur logique de 100 px équivaut à une valeur d'appareil de 200 px.

C'est intéressant, mais qu'est-ce que cela signifie pour nous, les développeurs ? Au début, nous avons tous commencé à remarquer que nos images étaient redimensionnées par ces appareils. Nous créions des images à la largeur logique en pixels de nos éléments. Lorsqu'elles étaient dessinées, elles étaient mises à l'échelle par devicePixelRatio et étaient floues.

Image mise à l'échelle et floutée en raison de devicePixelRatio
Figure 1 : Image agrandie et floutée en raison de 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();