javascript - 鼠标/触摸坐标在错误的位置 HTML Canvas

标签 javascript html css canvas responsive-design

我的 HTML Canvas 有问题,在实验阶段工作正常,但是一旦我将它带入我的适当开发中,鼠标坐标就变得完全不稳定,它确实绘制了,但是不在正确的位置,即我点击并拖动以绘制一条线,该线是在 Canvas 内进一步向下绘制的。我只是想修复其中的坐标,以便鼠标光标准确地绘制在它应该在的位置。

下面是我的代码,为了了解我在说什么,请务必调整浏览器窗口的大小,因为该网站是特定于移动设备的。谢谢您的帮助,我们将不胜感激

我试过使用 getXY 函数,但在那之后我已经有了一个变量名,但它没有用。我也尝试了各种造型技巧,但都无济于事

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 = 15;
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));
  e.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();
  e.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()
}

init();
@font-face {
  font-family: Geoma Regular Demo;
  src: url(Geoma Regular Demo.otf);
}

@font-face {
  font-family: Geoma Demo;
  src: url(Geoma Light demo.otf);
}

@media screen and (max-width: 425px) {
  html,
  body {
    overflow-x: hidden;
    width: 100%;
    margin: 0;
  }
}

canvas {
  border: 3px solid #0BF446;
  border-radius: 15px 0px 15px 0px;
  display: block;
  margin: 0 auto;
  margin-top: 35px;
}

#clearbutton {
  background-color: #04A12B;
  border-radius: 0 15px 0 15px;
  padding: 20px;
  margin: 0 auto;
  display: block;
  font-size: 14px;
  color: white;
  font-family: Geoma Demo;
  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: Geoma Demo;
}
<canvas id="c" width="350" height="500"></canvas>
<input type="submit" value="Clear Sketchpad" id="clearbutton" onclick="clearCanvas(canvas,ctx);">
<footer id="footer1">
  <a href="" id="about">About Elemental</a>
</footer>

最佳答案

您需要将点击事件本地化为相对于 Canvas 元素。您可以通过获取 top 来做到这一点和 left来自 el.getBoundingClientRect()并使用它们来调整 xy点击事件的值(value)。见下文,大部分工作是在 getXY 中完成的功能。

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 = 15;
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;
  const {
    clientX,
    clientY
  } = source;
  const {
    left,
    top
  } = el.getBoundingClientRect();

  const x = clientX - left;
  const y = clientY - top;

  return {
    x,
    y
  };
};

var startDrawing = function(e) {
  isDrawing = true;
  points.push(getXY(e));
  e.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();
  e.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()
}

init();
@font-face {
  font-family: Geoma Regular Demo;
  src: url(Geoma Regular Demo.otf);
}

@font-face {
  font-family: Geoma Demo;
  src: url(Geoma Light demo.otf);
}

@media screen and (max-width: 425px) {
  html,
  body {
    overflow-x: hidden;
    width: 100%;
    margin: 0;
  }
}

canvas {
  border: 3px solid #0BF446;
  border-radius: 15px 0px 15px 0px;
  display: block;
  margin: 0 auto;
  margin-top: 35px;
}

#clearbutton {
  background-color: #04A12B;
  border-radius: 0 15px 0 15px;
  padding: 20px;
  margin: 0 auto;
  display: block;
  font-size: 14px;
  color: white;
  font-family: Geoma Demo;
  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: Geoma Demo;
}
<canvas id="c" width="350" height="500"></canvas>
<input type="submit" value="Clear Sketchpad" id="clearbutton" onclick="clearCanvas(canvas,ctx);">
<footer id="footer1">
  <a href="" id="about">About Elemental</a>
</footer>

关于javascript - 鼠标/触摸坐标在错误的位置 HTML Canvas ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55306900/

相关文章:

javascript - 如何将 Observable 内部的值作为 Angular 2+ 中的函数返回

javascript - JQuery 处理事件,但不执行函数

jquery - 知道垂直滚动条何时到达 div 滚动条的底部

javascript - 下拉值填充输入框

javascript - 如何使用 html5 数据属性在 html 元素中存储 javascript 对象或 JSON?

javascript - Material-UI [Select] - 如何在外部点击时移除焦点?

html - 如何避免父级在使用overflow-y时显示滚动条: scroll on children

html - 如何让div列的高度相同?

CSS 通用同级选择器与标题

php - 如何显示带有动态 id 的 html 图像