HTML5 Canvas позиционирование щелчка мыши не работает - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть один элемент canvas, который при позиционировании с помощью css не может регистрировать щелчки мыши и перемещать элементы, нарисованные в пределах canvas.Если вы не разместите холст, щелчки мыши регистрируются, и выбранные элементы будут перемещены, но мне нужно иметь возможность расположить этот слой холста слева и сверху, чтобы я мог поместить другой холст под ним, сохраняя при этом возможность щелчка мышью и перемещения.

Это то, что я использую для получения координат моего х / у клика

 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 голосов
/ 14 декабря 2018

Я редактировал это в devtools на лету, что вызывало проблемы с canvas и было в состоянии получить правильный х / у щелчка мыши.Когда я настраиваю позиционирование в инструментах разработчика, то пытаюсь переместить квадрат, это не сработает.Изменение моей таблицы стилей перед загрузкой в ​​dom в этом случае дало правильный результат, поскольку после манипуляции с позиционированием Canvas необходимо будет выполнить вычисления заново.

Для тех, кому требовался визуал, вот некоторый код.Чтобы воспроизвести проблему, вы можете попытаться добавить justify-content: center к классу .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>
0 голосов
/ 14 декабря 2018

Вы можете сделать это, используя 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...