问题描述
我先给出我的代码:
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.pageX
和 e.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>
请注意,通过这种方式,您无法免费调整大小。如果调整窗口大小,您需要从代码中再次更改画布,我在此处省略了该代码。