如何在HTML画布中获取正确的鼠标坐标

时间:2019-04-02 23:10:31

标签: javascript html css canvas mouse

自从我为响应式设计设置HTML画布样式以来,我的鼠标坐标就变得异常复杂。当它没有样式并且恰好在屏幕的左上方时,它可以完美地工作。但是现在缩小浏览窗口或在移动设备上使用时,光标将不会在应该绘制的位置进行绘制,即恰好在绘制路径上,而不是在其上方或下方几个像素。下面是我的代码,任何帮助将不胜感激

function init() {
  // Get the specific canvas element from the HTML document
  canvas = document.getElementById('c');

}

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 = 30;
ctx.lineJoin = ctx.lineCap = 'round';

var img = new Image;
img.onload = function() {
  ctx.strokeStyle = getPattern();
};
img.src = "https://i.postimg.cc/rF2R0GRY/dick2.png";

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));
  event.preventDefault();


};

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.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();
  event.preventDefault();
};

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);

function clearCanvas(canvas, ctx) {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.beginPath()
}
@import url('https://fonts.googleapis.com/css?family=Montserrat+Alternates');
@media screen and (max-width: 425px) {
  html,
  body {
    overflow-x: hidden;
    width: 100%;
    margin: 0;
  }
  #logo {
    margin: 0 auto;
    display: block;
    margin-bottom: 15px;
    margin-top: 15px;
  }
  .container1 {
    background-color: #313131;
    border-radius: 20px;
    border: 3px solid #0BF446;
    height: 250px;
  }
  #grphc1 {
    margin: 0 auto;
    display: block;
    margin-top: 35px;
  }
  #canvasintro {
    border-radius: 20px 0px 20px 0px;
    border: 3px solid #0BF446;
    color: white;
    background-color: #0BF446;
    font-size: 16px;
    text-align: left;
    font-family: 'Montserrat Alternates', sans-serif;
    margin-left: 15px;
    margin-right: 15px;
    margin-top: 35px;
    padding: 20px;
  }
  canvas {
    border: 3px solid #0BF446;
    border-radius: 15px 0px 15px 0px;
    display: block;
    margin: 0 auto;
    margin-top: 35px;
    background-color: #313131;
    position: relative;
  }
  #download {
    background-color: #04A12B;
    border-radius: 0 15px 0 15px;
    padding: 20px 40px;
    margin: 0 auto;
    display: block;
    font-size: 14px;
    margin-top: 35px;
    color: white;
    font-family: 'Montserrat Alternates', sans-serif;
  }
  #clearbutton {
    background-color: #04A12B;
    border-radius: 0 15px 0 15px;
    padding: 20px;
    margin: 0 auto;
    display: block;
    font-size: 14px;
    color: white;
    font-family: 'Montserrat Alternates', sans-serif;
    margin-top: 35px;
  }
  #footer1 {
    background-color: #00671A;
    border-radius: 30px 30px 0px 0px;
    text-align: center;
    padding: 30px;
    margin-top: 35px;
  }
  #about {
    color: white;
    font-size: 16px;
    font-family: 'Montserrat Alternates', sans-serif;
  }
}
<!DOCTYPE html>
<html>

<head>
  <title>Elemental</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body onload="init()">
  <a href="../homepage.html"><img src="minilogo.png" id="logo"></a>

  <div class="container1">
    <img src="leaf.png" id="grphc1">
  </div>

  <div id="canvasintro">Feel free to draw or doodle down below with this natural element of design</div>

  <canvas id="c" width="350px" height="350px"></canvas>

  <button id="download">Download</button>

  <input type="submit" value="Clear Sketchpad" id="clearbutton" onclick="clearCanvas(canvas,ctx);">

  <footer id="footer1">
    <a href="../about.html" id="about">About Elemental</a>
  </footer>

</body>

</html>

1 个答案:

答案 0 :(得分:2)

首先,您的新图片构造函数缺少要调用的括号:

var img = new Img();

但是在您的getXY()函数中,返回offsetXoffsetY而不是clientXclientY

var getXY = function(e) {
  var source = e.touches ? e.touches[0] : e;
  return {
    x: source.offsetX,
    y: source.offsetY
  };
};

在这里,“客户端”是指视口,而“偏移”是对padding edge of the target node或画布本身的引用。

您还应该添加mouseouttouchcancel事件处理程序:

el.addEventListener('mouseout', stopDrawing);
el.addEventListener('touchcancel', stopDrawing);