我的问题是关于使用 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" />