为什么它在画布上远离光标绘制?

问题描述

我先给出我的代码

document.documentElement.style.backgroundImage='url(\'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20"><rect width="20" height="20" style="fill-opacity:0;stroke-width:1;stroke:rgb(0,255)"/></svg>\')';
var c=document.getElementById("paper").getContext("2d");
c.fillStyle="#000000";
document.documentElement.onmousemove=function(e){
    if((e.buttons||e.which)===1){
        var x=e.pageX,y=e.pageY;
        c.fillRect(x,y,1,1);
    }
};
html{width:100vw;height:100vh;overflow:hidden;background-repeat:repeat;cursor:crosshair}
body{margin:0}
#paper{position:absolute;left:0;top:0;width:100vw;height:100vh;z-index:1}
<!DOCTYPE html>
<html>
    <head>
        <Meta charset="UTF-8"/>
        <title>Graph Paper</title>
    </head>
    <body>
        <canvas id="paper"></canvas>
    </body>
</html>

我正在尝试制作一张可以用光标绘制的虚拟方格纸。问题是,如果您运行它并(使用鼠标)绘制一些东西,您会注意到它绘制的位置实际上并不是您所在的位置 - 随着您离 (0,0 ).

我的代码有点简单,所以我不知道为什么要这样做。例如,如果您从中间开始,向 (0,0) 移动,您会看到它从您身后开始,但与您同时到达。如果您从中间开始向右下方移动,那么当您到达时,它会比您 远得多。

我怀疑这与画布位置错误e.pageXe.pageY 在某些方面不正确有关。

为什么这个看似简单的代码不起作用?

解决方法

使用 css 拉伸画布不会改变画布的底层分辨率,而只是获取结果图像并对其进行缩放(通常也很糟糕)。

如果画布是例如由于 css 被拉伸了两倍,你的像素计数相应地被该因子关闭:画布向内渲染与你的鼠标坐标一样多的像素,但结果随后被 css 拉伸。

您可以通过一些计算来弥补这一点,但通常最好使画布本身具有正确的大小:

const canvas = document.getElementById("paper");
const ctx = canvas.getContext("2d");
document.documentElement.style.backgroundImage = 'url(\'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20"><rect width="20" height="20" style="fill-opacity:0;stroke-width:1;stroke:rgb(0,255)"/></svg>\')';
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
ctx.fillStyle = "#000000";
document.documentElement.onmousemove=function(e){
    if ((e.buttons || e.which) === 1) {
        const x = e.pageX,y = e.pageY;
        ctx.fillRect(x,y,1,1);
    }
};
html {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background-repeat: repeat;
  cursor: crosshair
}
body { margin: 0 }
#paper {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1
}
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8"/>
        <title>Graph Paper</title>
    </head>
    <body>
        <canvas id="paper"></canvas>
    </body>
</html>

请注意,通过这种方式,您无法免费调整大小。如果调整窗口大小,您需要从代码中再次更改画布,我在此处省略了该代码。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...