Éles vászonmegjelenítés nagy DPI-s és retina képernyőkön
Miért tűnnek homályosnak a vászongrafikák a Retina és a nagy DPI-s képernyőkön, és hogyan lehet ezt kijavítani a devicePixelRatio segítségével, beleértve az átméretezés kezelését és a teljesítménykorlátokat.
Core Takeaway
A vászon homályosnak tűnik a nagy sűrűségű képernyőkön, ha pixelmérete megegyezik a CSS méretével, mivel minden vászonpixel több fizikai képpontra van kifeszítve. Javítsa ki: állítsa a vászon szélességét és magasságát a CSS méret szorozva a window.devicePixelRatio értékre, a CSS mérete változatlan marad, és a rajzkörnyezet méretezésével azonos arányban. Frissítse átméretezéssel és nagyítással.
Miért homályosodnak el a vásznak?
A MDN az eszközPixelarányt a fizikai képpontok és a CSS képpontok arányaként írja le az aktuális kijelzőn: 1 a klasszikus 96 DPI-s képernyőn és 2 a tipikus HiDPI vagy Retina képernyőkön. A vászonnak saját pixelpuffere van. Ha ez a puffer 300 x 150 pixel, de 300 x 150 CSS pixel jelenik meg egy 2-es arányú képernyőn, akkor a böngésző 600 x 300 fizikai képpont fölé terjeszti, ami lágynak tűnik.
A javítás
A MDN javasolt megközelítése az eszközPixelRatio használata az extra pixelsűrűség hozzáadásához: állítsa be a vászonpuffert a CSS méret szorozva az arányra, a CSS mérete maradjon változatlan, és méretezze át a 2D környezetet, hogy a rajzkód továbbra is CSS képpontokat használhasson. Lásd az alábbi kódot.
Fogantyú átméretezés és nagyítás
Az arány megváltozik, ha egy ablak egy másik monitorra lép, vagy a felhasználó nagyítja az oldalt. Számítsa újra az átméretezéskor, és figyelje a felbontási médialekérdezés változásait, hogy az új sűrűséggel újrarajzolhassa. A vászonelemen található ResizeObserver megbízható módja annak, hogy a méretet szinkronban tartsa az elrendezéssel.
Teljesítménykorlátok
Az arány megkétszerezése megnégyszerezi a rajzolni kívánt képpontokat. Nagyon nagy vásznakon vagy alacsony kategóriás eszközökön korlátozza az arányt, például 2-re, és mérje meg a képkockaidőket. A vászonra rajzoló animációs futtatókörnyezetek, mint például a Lottie vászonmegjelenítője, a Rive és a ExodeUI, kezelik ezt a méretezést, de ugyanez a kompromisszum érvényes.
Gyártási megvalósítási részlet
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
}Kulcs Principle, amit meg kell jegyezni
- devicePixelRatio = fizikai pixel/CSS pixel (2 tipikus Retina képernyőkön)
- A canvas.width/height beállítása CSS méret × arányra; tartsa meg a CSS méretet
- Méretezze a környezetet úgy, hogy a rajzkód CSS képpontokat használjon
- Számítsa újra az átméretezést, figyelje a változást és a nagyítást
- Nagy vásznakon korlátozza az arányt a teljesítmény érdekében
Gyakran Ismételt Kérdések
Források
- Window: devicePixelRatio property — MDN webdokumentumok