Introducción
Las pantallas HiDPI son hermosas, hacen que todo se vea más fluido y nítido. Sin embargo, también presentan un nuevo conjunto de desafíos para los desarrolladores. En este artículo, analizaremos los desafíos únicos de dibujar imágenes en el lienzo en el contexto de las pantallas HiDPI.
La propiedad devicePixelRatio
Comencemos por el principio. Antes de que tuviéramos pantallas HiDPI, un píxel era un píxel (si ignoramos el zoom y el ajuste de escala por un tiempo), y eso era todo, en realidad no era necesario cambiar nada. Si configuras algo para que tenga 100 px de ancho, eso es todo. Luego, comenzaron a aparecer los primeros teléfonos celulares HiDPI con la propiedad devicePixelRatio ligeramente enigmática en el objeto window y disponible para usar en consultas de medios. Lo que esta propiedad nos permitió hacer fue comprender la proporción de cómo los valores de píxeles (que llamamos el valor de píxeles lógico) en, digamos, CSS se traducirían a la cantidad real de píxeles que usaría el dispositivo cuando se trata de renderización. En el caso de un iPhone 4S, que tiene un devicePixelRatio de 2, verás que un valor lógico de 100 px equivale a un valor de dispositivo de 200 px.
Es interesante, pero ¿qué significa eso para nosotros, los desarrolladores? Bueno, en los primeros días, empezamos a notar que estos dispositivos aumentaban el tamaño de nuestras imágenes. Creábamos imágenes con el ancho de píxeles lógico de nuestros elementos y, cuando se dibujaban, el devicePixelRatio las aumentaba de tamaño y se volvían borrosas.
La solución de facto para esto ha sido crear imágenes aumentadas por devicePixelRatio y, luego, usar CSS para reducirlas en la misma cantidad, y lo mismo sucede con el lienzo.
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();