How to draw a control on a canvas using a mobile touch with scroll on the screen

I am trying to create a mobile application in which the user can draw several controls (a rectangle) on the canvas.

It works great if the canvas fits on the screen, but the controls do not draw well when I increase the height and width of the canvas outside the screen (scrolling appears when the canvas is larger than the size of the mobile screen). How to fix it in scroll mode?

Use the Chrome Inspect mobile view (iPhone 6/7/8) to verify this code. Use drag and drop to draw controls

<html>
<body>
<canvas id="canvas_transparent" height="3000" width="1000" style="border: 1px solid black;"></canvas>
</body>
</html>

<script type="text/javascript">
var canvas = document.getElementById("canvas_transparent");
var ctx = canvas.getContext("2d");
var endX;
var startX;
var endY;
var startY;
var positions = [];
//--------------------------------------------------------
canvas.addEventListener("touchstart", function(e) {
  mousePos = getTouchPos(canvas, e);
  startX = mousePos.x;
  startY = mousePos.y;
  var touch = e.touches[0];
  var mouseEvent = new MouseEvent("mousedown", {
    clientX: touch.clientX,
    clientY: touch.clientY
  });
  canvas.dispatchEvent(mouseEvent);
}, false);
//---------------------------------------------------------
canvas.addEventListener("touchend", function(e) {
  positions.push({
    s_x: startX,
    s_y: startY,
    e_x: endX,
    e_y: endY
  });
  drawAllControls();
  console.log(positions);
  var mouseEvent = new MouseEvent("mouseup", {});
  canvas.dispatchEvent(mouseEvent);
}, false);
//---------------------------------------------------------
canvas.addEventListener("touchmove", function(e) {
  var touch = e.touches[0];
  endX = touch.clientX;
  endY = touch.clientY;
  drawSquare()
  var mouseEvent = new MouseEvent("mousemove", {
    clientX: touch.clientX,
    clientY: touch.clientY
  });
  canvas.dispatchEvent(mouseEvent);
}, false);
//--------------------------------------------------------
// Get the position of a touch relative to the canvas
function getTouchPos(canvasDom, touchEvent) {
  var rect = canvasDom.getBoundingClientRect();
  return {
    x: touchEvent.touches[0].clientX - rect.left,
    y: touchEvent.touches[0].clientY - rect.top
  };
}
//--------------------------------------------------------
function drawSquare() {
  // creating a square
  var w = endX - startX;
  var h = endY - startY;
  var offsetX = (w < 0) ? w : 0;
  var offsetY = (h < 0) ? h : 0;
  var width = Math.abs(w);
  var height = Math.abs(h);
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.beginPath();
  ctx.rect(startX + offsetX, startY + offsetY, width, height);
  ctx.fillStyle = "#222222";
  ctx.fill();
  ctx.lineWidth = 2;
  ctx.strokeStyle = 'black';
  ctx.stroke();
}
//----------------------------------------------------------
function drawAllControls() {
  for (var i = 0; i < positions.length; i++) {
    var w = positions[i].e_x - positions[i].s_x;
    var h = positions[i].e_y - positions[i].s_y;
    var offsetX = (w < 0) ? w : 0;
    var offsetY = (h < 0) ? h : 0;
    var width = Math.abs(w);
    var height = Math.abs(h);
    ctx.beginPath();
    ctx.rect(positions[i].s_x + offsetX, positions[i].s_y + offsetY, width, height);
    ctx.fillStyle = "#222222";
    ctx.fill();
    ctx.lineWidth = 2;
    ctx.strokeStyle = 'black';
    ctx.stroke();
  }
}
</script>

enter image description here enter image description here

+4
source share
2 answers

clientX/clientY . , pageX/pageY

https://developer.mozilla.org/en-US/docs/Web/API/Touch

// Get the position of a touch relative to the canvas
function getTouchPos(canvasDom, touchEvent) {
  var rect = canvasDom.getBoundingClientRect();
  return {
    x: touchEvent.touches[0].pageX - rect.left,
    y: touchEvent.touches[0].pageY - rect.top
  };
}
+1

, , .

<meta name="viewport" content="width=device-width, initial-scale=1.0"/>

enter image description here

0

Source: https://habr.com/ru/post/1693026/


All Articles