【问题标题】:Why does it draw far away from the cursor on a canvas?为什么它在画布上远离光标?
【发布时间】:2021-04-17 00:09:21
【问题描述】:

我先给出我的代码:

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,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 拉伸画布可能会导致这种情况
  • @ASDFGerte:嗯……在测试时似乎是真的。但是,如何让画布在整个屏幕上伸展呢?
  • 您可以通过一些小数学来补偿拉伸,或者根据视口的大小修改画布的widthheight。 PS:用css拉伸画布意味着它会放大你的图像,画布仍然以低分辨率渲染,但生成的图像会被拉伸。
  • @ASDFGerte:所以你建议 JavaScript 应该设置宽度和高度?好的。添加问题的答案,我会接受。感谢您的帮助!

标签: javascript html css canvas mouse-position


【解决方案1】:

使用 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,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>

请注意,这样您就不会免费调整大小。如果调整窗口大小,您需要从代码中再次更改画布,我在这里省略了。

【讨论】:

  • 感谢您的帮助!我知道这个 CSS 调整大小问题,但很难记住问题何时出现 :)
猜你喜欢
  • 1970-01-01
  • 2018-01-17
  • 2015-02-20
  • 2019-06-26
  • 1970-01-01
  • 2016-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多