Javascript 画布点打印不';调整大小后的t比例

Javascript 画布点打印不';调整大小后的t比例,javascript,jquery,html,css,canvas,Javascript,Jquery,Html,Css,Canvas,在使用javascript动态调整画布大小后,绘制在画布上的点不再与它们的放置位置对齐,而且圆弧也从它们的渲染方式开始拉伸 下面的可运行示例演示了这个问题,因为您单击光标的位置会变成一个大的未成形椭圆,它位于错误的位置 var TargetWidth=400; var画布=$(“.hotspot画布”) 对于(i=0;i{ sum[side]=Object.values($(canvas.css)([ `边框-${side}-宽度`, `填充-${side}` ])).减少((a,b)=>a+

在使用javascript动态调整画布大小后,绘制在画布上的点不再与它们的放置位置对齐,而且圆弧也从它们的渲染方式开始拉伸

下面的可运行示例演示了这个问题,因为您单击光标的位置会变成一个大的未成形椭圆,它位于错误的位置

var TargetWidth=400;
var画布=$(“.hotspot画布”)
对于(i=0;i
.hotspot画布{
-webkit用户选择:无;
-moz用户选择:无;
用户选择:无;
光标:十字线;
边框:1px纯黑;
背景重复:无重复;
背景位置:中心;
背景剪辑:边框框;
背景来源:填充框;
-moz背景尺寸:封面;
背景尺寸:封面;
}

显示大小和画布分辨率 显示大小和画布分辨率是两个不同的实体

设置画布样式的宽度和高度时,需要设置显示大小

canvas.style.width = "100px";
canvas.style.height = "100px";
var bounds = jcanvas.getBoundingClientRect();
jcanvas.width = bounds.width;
jcanvas.height = bounds.height; 
设置画布宽度和高度时,您可以设置分辨率

canvas.width = 100;
canvas.height = 100;
您已经设置了显示大小,但忽略了将分辨率与显示大小匹配

您只需将分辨率设置为与显示大小匹配即可解决此问题

canvas.style.width = "100px";
canvas.style.height = "100px";
var bounds = jcanvas.getBoundingClientRect();
jcanvas.width = bounds.width;
jcanvas.height = bounds.height; 
var TargetWidth=400;
var画布=$(“.hotspot画布”)
对于(i=0;i
.hotspot画布{
-webkit用户选择:无;
-moz用户选择:无;
用户选择:无;
光标:十字线;
边框:1px纯黑;
背景重复:无重复;
背景位置:中心;
背景剪辑:边框框;
背景来源:填充框;
-moz背景尺寸:封面;
背景尺寸:封面;
}

正如我在评论中提到的,我最近遇到了同样的问题,所以我想与大家分享我的解决方案。基本上,您的画布元素的维度是缩放的,其来源是由于CSS转换的,但画布的内部分辨率仍然是相同的。此外,画布的边框和填充也会影响
getBoundingClientRect
返回的
DOMRect
属性

您需要从一些
MouseEvent
TouchEvent
中获取
clientX
clientY
值、画布的内部分辨率以及显示的画布元素的尺寸和偏移量,包括边框和填充,并使用它们计算与画布内部坐标系相关的xy坐标。这段代码需要JQuery和ES6支持,但如果您担心浏览器兼容性,可以使用Babel或其他工具进行编译

//将视口中的坐标转换为画布的内部坐标
const translateCoords=({clientX,clientY})=>{
//画布元素的尺寸(相对于边框框的左上角)
const bcr=canvas.getBoundingClientRect();
//从边框和填充的偏移量
const sideWidth=[“顶部”、“右侧”、“底部”、“左侧”]。减少((总和、侧边)=>{
sum[side]=Object.values($(canvas.css)([
`边框-${side}-宽度`,
`填充-${side}`
])).减少((a,b)=>a+b,0);
回报金额;
}, {});
//内部画布分辨率与画布显示尺寸的比率
const scaleX=canvas.width/(bcr.width-(sideWidth.left+sideWidth.right));
const scaleY=canvas.height/(bcr.height-(sideWidth.top+sideWidth.bottom));
//将屏幕坐标转换并缩放为画布内部坐标
常量x=(clientX-(bcr.left+sideWidth.left))*scaleX;
consty=(clientY-(bcr.top+sideWidth.top))*scaleY;
重新