Pengantar
Layar HiDPI sangat bagus, karena membuat semuanya terlihat lebih halus dan lebih bersih. Namun, hal ini juga menghadirkan serangkaian tantangan baru bagi developer. Dalam artikel ini, kita akan melihat tantangan unik saat menggambar gambar di kanvas dalam konteks layar HiDPI.
Properti devicePixelRatio
Mari kita mulai dari awal. Sebelum kita memiliki layar HiDPI, piksel adalah piksel (jika kita mengabaikan zoom dan penskalaan untuk sementara) dan itu saja, Anda tidak perlu mengubah apa pun. Jika Anda menetapkan sesuatu dengan lebar 100 piksel, itu saja yang ada. Kemudian, beberapa ponsel seluler HiDPI pertama mulai muncul dengan properti devicePixelRatio yang sedikit misterius pada objek jendela dan tersedia untuk digunakan dalam kueri media. Dengan properti ini, kami dapat memahami rasio nilai piksel (yang kami sebut sebagai nilai piksel logis) - misalnya - CSS akan diterjemahkan ke jumlah sebenarnya piksel yang akan digunakan perangkat saat melakukan rendering. Untuk iPhone 4S, yang memiliki devicePixelRatio 2, Anda akan melihat bahwa nilai logis 100 piksel sama dengan nilai perangkat 200 piksel.
Menarik, tetapi apa artinya bagi kita para developer? Pada awalnya, kita semua mulai memperhatikan bahwa kualitas gambar kita sedang ditingkatkan oleh perangkat ini. Kita membuat gambar pada lebar piksel logis elemen kita dan, saat digambar, gambar akan ditingkatkan skalanya oleh devicePixelRatio dan akan menjadi buram.
Solusi de facto untuk hal ini adalah membuat gambar yang diskalakan oleh devicePixelRatio, lalu menggunakan CSS untuk menskalakannya ke bawah dengan jumlah yang sama, dan hal yang sama berlaku untuk kanvas.
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();