Skip to main content
ExodeUI

EXODEUI DESKTOP

A little space for good ideas.

Choose your platform to get the official ExodeUI installer.

Looking for Intel Mac or other builds? Explore the web studio or check all download options.

Prefer the browser? Try for free in your browser →
บทช่วยสอน · เว็บอ่าน 6 นาที·Updated ตุลาคม 2026·โดยทีม ExodeUI

การเรนเดอร์ Canvas ที่คมชัดบนหน้าจอ High-DPI และ Retina

เหตุใดกราฟิกแคนวาสจึงดูพร่ามัวบนหน้าจอ Retina และหน้าจอ DPI สูง และวิธีแก้ไขด้วย devicePixelRatio รวมถึงการปรับขนาดการจัดการและการจำกัดประสิทธิภาพ

สรุปโดยตรงและคำจำกัดความ

หลัก Takeaway

ผืนผ้าใบดูไม่ชัดเจนบนหน้าจอที่มีความหนาแน่นสูงเมื่อขนาดพิกเซลตรงกับขนาด CSS เนื่องจากแต่ละพิกเซลของผืนผ้าใบถูกขยายออกไปบนพิกเซลทางกายภาพหลายพิกเซล แก้ไขโดยตั้งค่าความกว้างและความสูงของผืนผ้าใบเป็นขนาด CSS คูณด้วย window.devicePixelRatio ทำให้ขนาด CSS ไม่เปลี่ยนแปลง และปรับขนาดบริบทการวาดภาพด้วยอัตราส่วนเดียวกัน อัปเดตเมื่อปรับขนาดและซูม

เหตุใดผืนผ้าใบจึงเบลอ

MDN อธิบาย devicePixelRatio ว่าเป็นอัตราส่วนของพิกเซลจริงต่อพิกเซล CSS บนจอแสดงผลปัจจุบัน โดย 1 บนหน้าจอ 96 DPI แบบคลาสสิก และ 2 บนหน้าจอ HiDPI หรือ Retina ทั่วไป แคนวาสมีบัฟเฟอร์พิกเซลของตัวเอง หากบัฟเฟอร์นั้นมีขนาด 300 x 150 พิกเซล แต่แสดงเป็น 300 x 150 CSS พิกเซลบนหน้าจอที่มีอัตราส่วน 2 เบราว์เซอร์จะขยายเกิน 600 x 300 พิกเซลจริง ซึ่งดูนุ่มนวล

ไดอะแกรมแสดงขนาดแคนวาส CSS คูณด้วย devicePixelRatio เพื่อรับขนาดที่จัดเก็บสำรอง
คูณขนาด CSS ด้วย devicePixelRatio สำหรับบัฟเฟอร์แคนวาส จากนั้นปรับขนาดบริบท

การแก้ไข

แนวทางที่แนะนำของ MDN คือการใช้ devicePixelRatio เพื่อเพิ่มความหนาแน่นของพิกเซลเพิ่มเติม: ตั้งค่าบัฟเฟอร์แคนวาสเป็นขนาด CSS คูณด้วยอัตราส่วน รักษาขนาด CSS ให้เท่าเดิม และปรับขนาดบริบท 2D เพื่อให้โค้ดรูปวาดของคุณสามารถใช้พิกเซล CSS ต่อไปได้ ดูรหัสด้านล่าง

จัดการการปรับขนาดและซูม

อัตราส่วนจะเปลี่ยนไปเมื่อหน้าต่างย้ายไปยังจอภาพอื่นหรือผู้ใช้ซูมหน้า คำนวณการปรับขนาดอีกครั้ง และรับฟังการเปลี่ยนแปลงในแบบสอบถามสื่อความละเอียด เพื่อให้คุณสามารถวาดใหม่ด้วยความหนาแน่นใหม่ ResizeObserver บนองค์ประกอบ Canvas เป็นวิธีที่เชื่อถือได้ในการรักษาขนาดให้ซิงค์กับเค้าโครง

ขีดจำกัดประสิทธิภาพ

การเพิ่มอัตราส่วนเป็นสองเท่าจะทำให้พิกเซลที่จะวาดเพิ่มขึ้นสี่เท่า บนผืนผ้าใบขนาดใหญ่มากหรืออุปกรณ์ระดับล่าง ให้จำกัดอัตราส่วน เช่น 2 และวัดเวลาของเฟรม รันไทม์ของแอนิเมชันที่วาดไปยังแคนวาส เช่น ตัวเรนเดอร์แคนวาสของ Lottie, Rive และ ExodeUI จัดการการปรับขนาดนี้ให้กับคุณ แต่จะมีข้อดีข้อเสียเหมือนกัน

ตัวอย่างการใช้งานการผลิต

การใช้งานส่วนประกอบแบบโต้ตอบ
function setupCanvas(canvas) {
  const ctx = canvas.getContext('2d');

  function resize() {
    const ratio = Math.min(window.devicePixelRatio || 1, 2); // cap for performance
    const { width, height } = canvas.getBoundingClientRect(); // CSS size

    canvas.width = Math.round(width * ratio);   // backing store in device pixels
    canvas.height = Math.round(height * ratio);
    ctx.setTransform(ratio, 0, 0, ratio, 0, 0); // draw in CSS pixels
    draw(ctx, width, height);
  }

  new ResizeObserver(resize).observe(canvas);
  resize();
}

function draw(ctx, width, height) {
  ctx.clearRect(0, 0, width, height);
  ctx.lineWidth = 1;
  ctx.strokeRect(0.5, 0.5, width - 1, height - 1); // crisp 1px border
}

คีย์ Principles ที่ต้องจำ

  • devicePixelRatio = พิกเซลจริงต่อ CSS พิกเซล (2 บนหน้าจอ Retina ทั่วไป)
  • ตั้งค่า canvas.width/height เป็น CSS ขนาด × อัตราส่วน คงขนาด CSS เอาไว้
  • ปรับขนาดบริบทเพื่อให้โค้ดการวาดใช้พิกเซล CSS
  • คำนวณใหม่เมื่อปรับขนาด ตรวจสอบการเปลี่ยนแปลง และการซูม
  • กำหนดอัตราส่วนบนผืนผ้าใบขนาดใหญ่เพื่อประสิทธิภาพ

คำถามที่พบบ่อย

แหล่งที่มา

  1. Window: devicePixelRatio property — MDN เว็บเอกสาร

คำแนะนำและตัวอย่างที่เกี่ยวข้อง

UI ผืนผ้าใบเชิงโต้ตอบที่คมชัด

เปิดตัวอย่าง ExodeUI ที่เรนเดอร์บนผืนผ้าใบด้วยความละเอียดของอุปกรณ์เต็มรูปแบบ และตรวจสอบวิธีการสร้างตัวอย่างเหล่านั้น

เปิดตัวอย่าง
ลองฟรี