我有一个canvas元素,当它与css一起放置时,无法注册鼠标单击并移动在canvas内绘制的元素。如果您不放置画布,则单击鼠标单击寄存器,所选元素将被移动,但是我需要能够将该画布层的顶部和左侧放置,以便可以在下面放置另一个画布,同时保持鼠标单击和移动的能力。>
这就是我用来获取x / y点击坐标的
var br = canvas.getBoundingClientRect(); //bounding rectangle
var mousex = parseInt(e.clientX-br.left);
var mousey = parseInt(e.clientY-br.top);
我已经将clientX和clientY更改为使用pageX和pageY,正如其他人建议的那样,但是即使将画布放在另一个div中并据此定位,问题仍然存在。我还从mousex中减去了要移动容器的数量,但没有成功。即使使用flex定位也会破坏功能。
这仅仅是画布的限制吗?
**澄清一下,如果以前不清楚,因为检测鼠标单击不是问题,问题在于当我将画布放置在DOM内时,不再注册单击。 **
答案 0 :(得分:0)
您可以使用offsetLeft
和offsetTop
进行操作。这是一个演示:
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
targetPos = {x: 150, y: 50};
// Initial render
render();
// Whenever the user clicks on the canvas, update the position
canvas.addEventListener('click', updateTargetPos);
function updateTargetPos(e) {
targetPos = {
x: e.pageX - canvas.offsetLeft,
y: e.pageY - canvas.offsetTop
};
render();
}
function render() {
renderBackground();
renderTarget();
}
function renderBackground() {
ctx.fillStyle = "#333";
ctx.fillRect(0, 0, 300, 200);
}
function renderTarget() {
var size = 10;
ctx.fillStyle = "#f00";
ctx.fillRect(targetPos.x - size/2, targetPos.y - size/2, size, size);
}
body {
font-family: Arial, Helvetica, sans-serif;
}
#canvas {
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -150px;
}
<p>Click on this absolutely positioned canvas:</p>
<canvas id="canvas" width="300" height="100"></canvas>
答案 1 :(得分:0)
我当时正在devtools中进行即时编辑,这导致了画布问题,并且能够获得正确的鼠标单击x / y。当我要在开发工具中调整位置然后尝试移动正方形时,它将不起作用。在这种情况下,在加载到dom之前修改样式表会产生正确的结果,因为在操纵画布的位置后需要再次运行计算。
对于那些需要视觉效果的人,下面是一些代码。要重现该问题,您可以尝试将justify-content:中心添加到.flex类,然后尝试移动绿色正方形以查看您是否可以移动正方形,或者找不到定义为可点击的位置在盒子上。
var canvas = document.getElementById("canvasArea");
var ctx = canvas.getContext("2d");
var canvas2 = document.getElementById("canvas2");
var ctx2 = canvas2.getContext("2d");
var x = canvas.width/2;
var y = canvas.height-10;
var dx = 2;
var dy = -2;
var boundingRectangle = canvas.getBoundingClientRect();
var moveBox = false;
var selectedBox;
function box(x, y) {
this.color = "green";
this.xPos = x;
this.yPos = y;
this.width = 50;
this.height = 50;
}
box.prototype.drawBox = function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.xPos, this.yPos, this.width, this.height);
};
var abox = new box(x, 30);
canvas.addEventListener("mousedown", function(e) {
e.preventDefault();
e.stopPropagation();
var mousex = parseInt(e.clientX-boundingRectangle.left);
var mousey = parseInt(e.clientY-boundingRectangle.top);
if(mousex > abox.xPos && mousex < abox.xPos + abox.width && mousey > abox.yPos && mousey < abox.yPos + abox.height) {
moveBox = true;
selectedBox = "abox"
}
}, true);
canvas.addEventListener("mousemove", function(e) {
e.preventDefault();
e.stopPropagation();
if(moveBox) {
if(selectedBox == "abox") {
abox.xPos = e.offsetX;
abox.yPos = e.offsetY;
}
}
})
canvas.addEventListener("mouseup", function(e) {
e.preventDefault();
e.stopPropagation();
moveBox = false;
})
function bg(ctx2) {
var alpha = ctx2.globalAlpha;
ctx2.save();
ctx2.beginPath();
ctx2.moveTo(142.5, 23.7);
ctx2.lineTo(85.9, 0.0);
ctx2.lineTo(0.0, 204.8);
ctx2.lineTo(56.6, 228.5);
ctx2.lineTo(142.5, 23.7);
ctx2.closePath();
ctx2.fillStyle = "rgb(31, 155, 215)";
ctx2.fill();
ctx2.beginPath();
ctx2.moveTo(235.1, 23.7);
ctx2.lineTo(178.5, 0.0);
ctx2.lineTo(92.6, 204.8);
ctx2.lineTo(149.2, 228.5);
ctx2.lineTo(235.1, 23.7);
ctx2.closePath();
ctx2.fillStyle = "rgb(77, 75, 159)";
ctx2.fill();
ctx2.beginPath();
ctx2.moveTo(330.5, 23.7);
ctx2.lineTo(273.9, 0.0);
ctx2.lineTo(188.0, 204.8);
ctx2.lineTo(244.6, 228.5);
ctx2.lineTo(330.5, 23.7);
ctx2.closePath();
ctx2.fillStyle = "rgb(176, 67, 152)";
ctx2.fill();
ctx2.beginPath();
ctx2.moveTo(435.4, 23.7);
ctx2.lineTo(378.8, 0.0);
ctx2.lineTo(292.9, 204.8);
ctx2.lineTo(349.5, 228.5);
ctx2.lineTo(435.4, 23.7);
ctx2.closePath();
ctx2.fillStyle = "rgb(69, 174, 77)";
ctx2.fill();
ctx2.beginPath();
ctx2.moveTo(541.4, 23.7);
ctx2.lineTo(484.7, 0.0);
ctx2.lineTo(398.9, 204.8);
ctx2.lineTo(455.5, 228.5);
ctx2.lineTo(541.4, 23.7);
ctx2.closePath();
ctx2.fillStyle = "rgb(237, 127, 34)";
ctx2.fill();
ctx2.restore();
}
function render() {
requestAnimationFrame(render);
ctx.clearRect(0, 0, canvas.width, canvas.height);
abox.drawBox();
}
render();
bg(ctx2)
.flex {
width: 100%;
height: 100%;
display: flex;
}
canvas#canvasArea {
position: absolute;
display: inline-block;
}
.container {
position: relative;
left: 150px;
top: -20px;
z-index: 999999;
}
.container {
position: relative;
}
.canvasbg {
position: absolute;
width: 200px;
height: 150px;
margin: 20px 0;
border: none;
background: #000000;
}
<div class="flex">
<div class="container">
<div class="canvasbg">
<canvas id="canvasArea" width="220" height="150">
Your browser does not support HTML5 canvas.
</canvas>
</div>
</div>
<canvas id="canvas2" width="540" height="177"></canvas>