Introdução
As telas HiDPI são ótimas, elas deixam tudo mais suave e limpo. Mas eles também apresentam um novo conjunto de desafios para os desenvolvedores. Neste artigo, vamos analisar os desafios únicos de exibir imagens na tela no contexto de telas HiDPI.
A propriedade devicePixelRatio
Vamos começar do início. Antes de termos telas HiDPI, um pixel era um pixel (se ignorarmos o zoom e a escala por um tempo) e era isso. Não era preciso mudar nada. Se você definir algo como 100 px de largura, é só isso que vai existir. Em seguida, os primeiros aparelhos móveis HiDPI começaram a aparecer com a propriedade devicePixelRatio um pouco enigmática no objeto de janela e disponível para uso em consultas de mídia. Essa propriedade nos permitiu entender a proporção de como os valores em pixels (que chamamos de valor lógico de pixel) em, digamos, o CSS seria convertido para o número real de pixels que o dispositivo usaria na renderização. No caso de um iPhone 4S, que tem um devicePixelRatio de 2, um valor lógico de 100 px equivale a um valor de dispositivo de 200 px.
Isso é interessante, mas o que isso significa para nós, desenvolvedores? No início, percebemos que nossas imagens estavam sendo aprimoradas por esses dispositivos. Estávamos criando imagens com a largura lógica de pixel de nossos elementos e, quando desenhadas, elas eram aprimoradas pelo devicePixelRatio e ficavam desfocadas.
A solução real para isso tem sido criar imagens escalonadas verticalmente pelo devicePixelRatio e usar CSS para reduzi-las na mesma quantidade, e o mesmo vale para o 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();