Справка HTML Canvas для сенсорного экрана

#javascript #html #css #canvas #touch

#javascript #HTML #css #холст #коснитесь

Вопрос:

Привет, я работаю над веб-сайтом для мобильных устройств, который предполагает, что пользователи рисуют фигуры и узоры на своих мобильных устройствах. У меня возникли проблемы с реализацией этого для мобильных устройств. Рисование canvas отлично работает с настольными компьютерами, но совсем не с устройствами с сенсорным экраном. Я пытался использовать события касания, но, похоже, они вообще не работают. Ниже приведен мой код. Любая помощь была бы высоко оценена

 <!DOCTYPE html>
<html>
<head>
<title>Page Title</title>


<style>
canvas { border: 5px solid blue }

</style>

</head>
<body>
<canvas id="c" width="500" height="300"></canvas>
<h1>This is a Heading</h1>
<p>This is a paragraph.</p>


<script>
function midPointBtw(p1, p2) {
  return {
    x: p1.x   (p2.x - p1.x) / 2,
    y: p1.y   (p2.y - p1.y) / 2
  };
 }

function getPattern() {
  return ctx.createPattern(img, 'repeat');
 }


var el = document.getElementById('c');
var ctx = el.getContext('2d');

ctx.lineWidth = 50;
ctx.lineJoin = ctx.lineCap = 'round';

var img = new Image;
img.onload = function() {
  ctx.strokeStyle = getPattern();
};
img.src = "dick2.png";

var isDrawing, points = [ ];

el.ontouchstart = function(e) {
  isDrawing = true;
  points.push({ x: e.clientX, y: e.clientY });

};

el.ontouchmove = function(e) {
  if (!isDrawing) return;

  points.push({ x: e.clientX, y: e.clientY });
  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

  var p1 = points[0];
  var p2 = points[1];

  ctx.beginPath();
  ctx.moveTo(p1.x, p1.y);

  for (var i = 1, len = points.length; i < len; i  ) {
    var midPoint = midPointBtw(p1, p2);
    ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);
    p1 = points[i];
    p2 = points[i 1];
  }
  ctx.lineTo(p1.x, p1.y);
  ctx.stroke();
};

el.onmouseup = function() {
  isDrawing = false;
  points.length = 0;
};




function showInput() {
document.getElementById('display').innerHTML = 
document.getElementById("user_input").value;
    }







</script>


<form id ="search">
<input type = "text" name="message" id="user_input">
<input type = "button" value= "Submit" onclick="showInput();">
</form>



<p><span id='display'></span></p>

</body>
</html>
  

Ответ №1:

События касания работают иначе, чем события мыши. Вместо того, чтобы просто clientX и clientY присутствовать на самом мероприятии, благодаря тому, что сенсорные экраны могут поддерживать несколько точек касания с различной чувствительностью, они доступны в другом месте, под touches . Если вас интересует только первое касание в списке, вы можете довольно легко сделать свой код совместимым как с настольными, так и с мобильными устройствами с минимальными изменениями:

 function midPointBtw(p1, p2) {
  return {
    x: p1.x   (p2.x - p1.x) / 2,
    y: p1.y   (p2.y - p1.y) / 2
  };
}

function getPattern() {
  return ctx.createPattern(img, 'repeat');
}


var el = document.getElementById('c');
var ctx = el.getContext('2d');

ctx.lineWidth = 50;
ctx.lineJoin = ctx.lineCap = 'round';

var img = new Image;
img.onload = function() {
  ctx.strokeStyle = getPattern();
};
img.src = "https://placekitten.com/200";

var isDrawing, points = [];

var getXY = function(e) {
  var source = e.touches ? e.touches[0] : e;

  return {
    x: source.clientX,
    y: source.clientY
  };
};

var startDrawing = function(e) {
  isDrawing = true;
  points.push(getXY(e));
};
var keepDrawing = function(e) {
  if (!isDrawing) return;

  points.push(getXY(e));
  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

  var p1 = points[0];
  var p2 = points[1];

  ctx.beginPath();
  ctx.moveTo(p1.x, p1.y);

  for (var i = 1, len = points.length; i < len; i  ) {
    var midPoint = midPointBtw(p1, p2);
    ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);
    p1 = points[i];
    p2 = points[i   1];
  }
  ctx.lineTo(p1.x, p1.y);
  ctx.stroke();
};
var stopDrawing = function() {
  isDrawing = false;
  points = [];
};

el.addEventListener('touchstart', startDrawing);
el.addEventListener('mousedown', startDrawing);

el.addEventListener('touchmove', keepDrawing);
el.addEventListener('mousemove', keepDrawing);

el.addEventListener('touchend', stopDrawing);
el.addEventListener('mouseup', stopDrawing);  
 canvas {
  border: 5px solid blue
}  
 <canvas id="c" width="500" height="300"></canvas>  

Комментарии:

1. Спасибо, чувак, ценю помощь, у меня просто есть еще несколько вопросов. У меня возникли проблемы с подключением моего исходного изображения к моему мобильному устройству, но когда я попробовал ваш код с изображением держателя для размещения, он сработал отлично. Есть ли где-нибудь в Интернете, где я мог бы загружать изображения в качестве заполнителей? (как у вас с котенком) и просто ввести ссылку в мой код? чтобы я мог использовать эти изображения в качестве штрихов для рисования, это просто кажется проще. Спасибо

2. Кроме того, когда я рисую на холсте, это всего лишь один непрерывный штрих. возможно ли сделать это таким образом, чтобы вы рисовали, затем останавливались, затем снова рисовали и так далее. Т.Е. просто рисуйте несколько раз, а не только одним непрерывным штрихом?

3. Я бы посоветовал вам задать их как отдельный вопрос, предварительно осмотревшись и посмотрев, нет ли уже вопроса, охватывающего это.