为什么我在这个canvas上创建的矩形没有被放到正确的位置?

我正在尝试创建一个单击的简单页面,并可以在canvas上创建矩形。 它将用户的鼠标单击作为输入,然后从单击的x和y创建一个矩形。 但是,它将矩形放在一边一定量,我不知道为什么。

小提琴: https : //jsfiddle.net/2717s53h/

HTML

 

CSS

 #cnv{ width:99vw; height:98vh; background-color:#faefbd; } 

JAVASCRIPT

 $(function () { var canvas = $('#cnv'); var canvObj = document.getElementById('cnv'); var ctx = canvObj.getContext('2d'); var point1 = {}; var point2 = {}; canvas.click(function (e) { console.log(e); var x = e.pageX; var y = e.pageY; console.log(x); console.log(y); if (Object.keys(point1).length == 0) { point1.x = x; point1.y = y; } else if (Object.keys(point2).length == 0) { point2.x = x; point2.y = y; console.log(point1); console.log(point2); var width = point2.x - point1.x; var height = point2.y - point1.y; width = width < 0 ? width * -1 : width; height = height < 0 ? height * -1 : height; ctx.fillRect(x, y, 10, 10); point1 = {}; point2 = {}; } }); }); 

CSS高度/宽度与HTMLcanvas属性高度和宽度之间存在差异:前者定义canvas在页面中占据的空间; 后者定义了渲染表面 。 在concreto中,假设您有以下canvas:

  

使用1200×800大小的视口,canvas’CSS设置为width: 100%; height: 100%; width: 100%; height: 100%; ,然后你的canvas将被渲染为两倍大和高度和宽度模糊 (就像你的小提琴;显然这些矩形大于10px)。 因此, 页面坐标与canvas的坐标不同步

根据规范 ,你的小提琴的canvas渲染表面是300×150,因为你没有指定宽度/高度属性:

width属性默认为300,height属性默认为150。

看一下小提琴的略微“修正”版本。

因此,我的建议(作为HTML-canvas上的非专家)将始终指定这两个属性,而不是混淆不同的渲染表面与显示尺寸(当然不是相对的,如vw,vh,%,em, …)如果你不想要不可预知的结果; 虽然一些SO用户一直在寻找解决方案 。