我的問題是關於使用 devicePixelRatio。 考慮以下範例:
const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); const size = 5; canvas.style.width = `${size}px`; canvas.style.height = `${size}px`; const scale = window.devicePixelRatio; canvas.width = Math.floor(size * scale); canvas.height = Math.floor(size * scale); canvas.style.backgroundColor="red"; ctx.fillStyle = "black"; ctx.fillRect( 3, 3, 1,1 );
我想要的是這樣的:
我的畫面的 devicePixelRatio 等於 2。
我的目標是在尺寸為 5x5 的畫布中顯示尺寸為 1x1 的點。
我應用了我所理解的,與顯示緩衝區的大小相比,我將繪圖緩衝區的大小加倍。
對於點大小:1x1,結果很好。
但畫布的尺寸仍然是原來的兩倍。 10x10 為了什麼? 解釋當然是顯而易見的......
#我的畫面回傳的 window.devicePixelRatio 值等於 2
# 我的目標是編寫在正方形中顯示像素的程式碼。
正方形的大小為 5x5 像素。
我嘗試使用以下程式碼:
const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); const size = 5; canvas.style.width = `${size}px`; canvas.style.height = `${size}px`; const scale = window.devicePixelRatio; canvas.width = Math.floor(size * scale); canvas.height = Math.floor(size * scale); canvas.style.backgroundColor="red"; ctx.fillStyle = "black"; ctx.fillRect( 3, 3, 1,1 );
這是結果:我複製並貼上了螢幕截圖
它在Gimp下,我放大並添加了一個網格
黑點,ctx.fillRect( 3, 3, 1,1 ) 的結果正是我想要的大小。
但是紅色背景的大小為 10 x 10。我希望它是 5x5
P粉5292450502024-01-11 14:01:10
根據我的理解,OP想要的是畫布的物理像素為5x5px,點為1x1px,這是在不使用.scale
的情況下進行的另一種嘗試:
const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); const size = 5; const scale = window.devicePixelRatio; canvas.style.width = `${size}px`; canvas.style.height = `${size}px`; canvas.style.transform = `scale(${1 / scale })`; canvas.style.transformOrigin = 'top left'; canvas.width = size; canvas.height = size; canvas.style.backgroundColor = 'red'; ctx.fillStyle = 'black'; ctx.fillRect(3, 3, 1, 1);
<canvas id="canvas" />
預設情況下,上下文和畫布保持兩種不同的邏輯,上下文是繪圖緩衝區,而畫布只是負責將繪圖緩衝區的結果縮放到正確的大小。
為了在畫布上為高裝置像素比裝置繪圖,同時確保畫布保持相同的繪圖緩衝區,您可以使用ctx.scale
方法,該方法應根據您傳入的值(例如 devicePixelRatio
):
const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); const size = 5; canvas.style.width = `${size}px`; canvas.style.height = `${size}px`; const scale = window.devicePixelRatio; canvas.width = Math.floor(size * scale); canvas.height = Math.floor(size * scale); canvas.style.backgroundColor = 'red'; ctx.scale(scale, scale); ctx.fillStyle = 'black'; ctx.fillRect(3, 3, 1, 1);
<canvas id="canvas" />