HTML5 Canvas定位鼠标单击损坏

时间:2018-12-13 20:52:44

标签: javascript html5 canvas

我有一个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内时,不再注册单击。 **

2 个答案:

答案 0 :(得分:0)

您可以使用offsetLeftoffsetTop进行操作。这是一个演示:

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>