Canvas con DPI elevato

Paul Lewis

Introduzione

Gli schermi HiDPI sono meravigliosi, rendono tutto più fluido e pulito. ma presentano anche una nuova serie di sfide per gli sviluppatori. In questo articolo analizzeremo le sfide specifiche legate al disegno su tela nel contesto degli schermi HiDPI.

La proprietà Proporzioni del dispositivoPixel

Iniziamo dall'inizio. Prima che avevamo le schermate HiDPI, un pixel era un pixel (se ignoriamo lo zoom e il ridimensionamento per un po') e questo era davvero inutile cambiare nulla. Se hai impostato una larghezza di 100 px, non c'era altro. Poi, i primi smartphone HiDPI hanno iniziato ad apparire con la proprietà devicePixelProporzioni leggermente enigmatica sull'oggetto finestra, disponibile per l'uso nelle query supporti. Questa proprietà ci ha consentito di comprendere il rapporto tra i valori dei pixel (ovvero il valore logico dei pixel), ad esempio il CSS, che avrebbe tradotto nel numero effettivo di pixel che il dispositivo avrebbe utilizzato per il rendering. Nel caso di un iPhone 4S, che ha un rapporto pixel del dispositivo di 2, vedrai che un valore logico di 100 px equivale a un valore del dispositivo di 200 px.

È interessante, ma cosa significa per noi sviluppatori? All'inizio, tutti abbiamo notato che le nostre immagini venivano ottimizzate da questi dispositivi. Stavamo creando immagini con la larghezza logica in pixel dei nostri elementi e, una volta disegnate, sarebbero state ridimensionate dal rapporto pixel del dispositivo e sarebbero state sfocate.

Un'immagine in scala e sfocata a causa delle proporzioni di pixel del dispositivo
Figura 1 - Un'immagine ridimensionata e sfocata a causa delle proporzioni pixel del dispositivo

Di fatto, la soluzione a questo problema è stata creare immagini ingrandite in base al valore del fattore di pixel del dispositivo e quindi utilizzare CSS per ridurle dello stesso valore, e lo stesso vale per le canvas.

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();