gpt4 book ai didi

Javascript - 使用宽度和高度的百分比在 Canvas 上绘制

转载 作者:行者123 更新时间:2023-11-30 00:01:57 26 4
gpt4 key购买 nike

我有一张占据 Canvas 整个宽度和高度的背景图像,我希望能够引用图像上的不同位置,所以我在图像中的那些点放置了一些圆圈,以便我可以直观地看到确认我有正确的位置。

我通过在我想画点的地方单击鼠标来完成此操作,在我的鼠标单击监听器事件中使用以下代码:

var rectCanvas = canvas.getBoundingClientRect();
var positionX = Math.round(((e.clientX - rectCanvas.left) / canvas.width * 100) * 1000) / 1000;
var positionY = Math.round(((e.clientY - rectCanvas.top) / canvas.height * 100) * 1000) / 1000;

//alert(positionX + ", " + positionY);

alert("Width\nPosition: " + (e.clientX - rectCanvas.left) + "\nPercentage Position: " + positionX + "\nBack to position: " + percentToPxHor(positionX));

我声明了以下例程:

function percentToPxHor(intPx) {
return intPx * canvas.width / 100;
}

function percentToPxVert(intPx) {
return intPx * canvas.height / 100;
}

点击背景图片的一个显着特征,我得到一个有意义的值。例如,单击图像的大约一半会提示我:

Width
Position: 532.5
Percentage Position: 53.091
Back to position: 532.50273

从这里我可以清楚地看出我将宽度的百分比转换回像素值的例程是有效的。但是,当我尝试将其付诸实践时,它不起作用。

当尝试绘制我之前提到的圆圈时,它会将它们正确地放置在 Y 轴上,但在 X 轴上太靠右了。我怀疑这与我考虑 Canvas 相对于窗口的位置的方式有关,但我不能完全确定。放置在图像左侧的圆圈稍微太右,那些放置在图像右侧的圆圈太右(几乎就好像无论问题是什么,它都应用了一个指数问题,该问题变得最糟糕涉及的数字越大。

当我添加这些圆圈时,我使用以下代码片段放置了四个,一个矩形的每个 Angular :

var topLeft = {x:percentToPxHor(17.275),y:percentToPxVert(59.691)};
var bottomLeft = {x:percentToPxHor(17.275),y:percentToPxVert(60.72)};
var topRight = {x:percentToPxHor(71.459),y:percentToPxVert(61.407)};
var bottomRight = {x:percentToPxHor(71.352),y:percentToPxVert(62.436)};

如有任何帮助,我们将不胜感激。

最佳答案

我制作了一个鼠标位置测试器,当有边框时显示偏移量。可能还有其他因素,但这表明 getBoundingClientRect 是不准确的。我在 FireFox 上测试过,你可以清楚地看到偏移量。

var canvas = document.getElementById('rect-canvas');
var check = document.getElementById('no-border-checkbox');
var ctx = canvas.getContext('2d');
var mouse = {p:{x:0, y:0}, frame:0, frames:30};
var topLeft = {x:percentToPxHor(17.275),y:percentToPxVert(59.691)};
var bottomLeft = {x:percentToPxHor(17.275),y:percentToPxVert(60.72)};
var topRight = {x:percentToPxHor(71.459),y:percentToPxVert(61.407)};
var bottomRight = {x:percentToPxHor(71.352),y:percentToPxVert(62.436)};

main();

function main() {
check.addEventListener('change', function(e) {
var className = check.checked ? 'border' : '';
canvas.setAttribute('class',className);
});

canvas.addEventListener('mousemove',function(e){
var rectCanvas = canvas.getBoundingClientRect();
var positionX = Math.round(((e.clientX - rectCanvas.left) / canvas.width * 100) * 1000) / 1000;
var positionY = Math.round(((e.clientY - rectCanvas.top) / canvas.height * 100) * 1000) / 1000;

//alert("Width\nPosition: " + (e.clientX - rectCanvas.left) + "\nPercentage Position: " + positionX + "\nBack to position: " + percentToPxHor(positionX));

mouse.p.x = percentToPxHor(positionX);
mouse.p.y = percentToPxVert(positionY);
render();
});
}


function render() {
// clear canvas
ctx.fillStyle='white';
ctx.fillRect(0,0,canvas.width,canvas.height);

// draw points and connect
drawCircle(topLeft, "blue");
drawCircle(bottomLeft, "green");
drawCircle(topRight, "red");
drawCircle(bottomRight, "orange");
drawPoly([topLeft, bottomLeft, bottomRight, topRight]);

// draw mouse circle
drawCircle(mouse.p, 'rgba(255,200,0,.75)', 10);

// draw mouse lines
var h1 = {x:0, y: mouse.p.y};
var h2 = {x:canvas.width, y: mouse.p.y};
var v1 = {x: mouse.p.x, y:0};
var v2 = {x: mouse.p.x, y:canvas.height};
drawPoly([h1, h2], "rgba(0,0,0,.25)");
drawPoly([v1, v2], "rgba(0,0,0,.25)");
}
function percentToPxHor(intPx) {
return intPx * canvas.width / 100;
}

function percentToPxVert(intPx) {
return intPx * canvas.height / 100;
}

function drawCircle(p, color, radius) {
if (typeof radius == 'undefined') radius = 2;
if (typeof color == 'undefined') color = 'red';
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(p.x,p.y,radius,0,2*Math.PI);
ctx.fill();
}

function drawPoly(points, color) {
ctx.strokeStyle = color ? color : 'red';
ctx.beginPath();
var p = points[points.length-1];
ctx.moveTo(p.x, p.y);
for(var i = 0; i < points.length; i++) {
var p = points[i];
ctx.lineTo(p.x, p.y);
}
ctx.stroke();
}
#rect-canvas {

}

.border {
border:5px solid red;
}

body {
background-color:#cccccc;
}
<canvas id='rect-canvas' class='border' width="300" height="150"></canvas>

<p>
Border
<input type='checkbox' id='no-border-checkbox' value='on' checked>
</p>

关于Javascript - 使用宽度和高度的百分比在 Canvas 上绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40121481/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com