Kanvas DPI Tinggi

Pengantar

Layar HiDPI sangat bagus karena membuat semuanya terlihat lebih halus dan bersih. Namun, project ini juga menghadirkan serangkaian tantangan baru bagi developer. Dalam artikel ini, kita akan melihat tantangan unik dalam 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 sebentar) dan hanya itu, Anda tidak benar-benar perlu mengubah apa pun. Jika Anda menetapkan lebar selebar 100 piksel, itu saja yang ada. Kemudian beberapa handset seluler HiDPI pertama mulai bermunculan dengan properti devicePixelRatio yang sedikit membingungkan pada objek jendela dan tersedia untuk digunakan dalam kueri media. Properti ini memungkinkan kami untuk memahami rasio nilai piksel (yang kami sebut nilai piksel logis) dalam - misalnya - CSS akan diterjemahkan ke jumlah piksel sebenarnya yang akan digunakan perangkat saat berhubungan dengan rendering. Dalam kasus iPhone 4S, yang memiliki devicePixelRatio 2, Anda akan melihat bahwa nilai logis 100px sama dengan nilai perangkat 200px.

Hal itu menarik, tetapi apa artinya bagi kita para developer? Pada masa-masa awal, kita semua mulai menyadari bahwa gambar kita sedang ditingkatkan kualitasnya oleh perangkat-perangkat ini. Kami membuat gambar pada lebar piksel logis elemen kami dan, ketika digambar, gambar tersebut akan ditingkatkan kualitasnya oleh devicePixelRatio dan menjadi buram.

Gambar sedang ditingkatkan kualitasnya dan diburamkan karena devicePixelRatio
Gambar 1 - Gambar yang kualitasnya ditingkatkan dan diburamkan karena devicePixelRatio

Solusi de facto untuk hal ini adalah membuat gambar yang ditingkatkan skalanya oleh devicePixelRatio lalu menggunakan CSS untuk memperkecil skalanya 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();