【问题标题】:Drawing on a HTML5 Canvas: how to draw at tip of mouse cursor在 HTML5 画布上绘图:如何在鼠标光标尖端绘图
【发布时间】:2018-09-08 03:18:23
【问题描述】:

我有以下代码可以让我在画布上绘制图片,类似于 MS Paint。因此,一旦用户按下鼠标左键,他/她就可以在画布上移动鼠标来绘制图片。一旦用户将手指从鼠标按钮上移开,绘图就会停止。

var colors = document.querySelectorAll('#colors div');
var link = document.getElementById('download');
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var drawing = false;
var prev;
document.getElementById('current').style.backgroundColor = context.strokeStyle;
for (var i = 0; i < colors.length; i++) {
  colors[i].addEventListener('click', function(e) {
    var src = e.srcElement;
    var color = src.style.backgroundColor;
    context.strokeStyle = color;
    document.getElementById('current').style.backgroundColor = color;
  });
  colors[i].style.height = 100 / colors.length + '%';
  colors[i].style.backgroundColor = colors[i].id;
}
function clearCanvas() {
  context.clearRect(0, 0, canvas.width, canvas.height);
}
link.addEventListener('click', function() {
  link.href = canvas.toDataURL();
  link.download = 'image.png';
});
canvas.addEventListener('mousedown', function(e) {
  drawing = true;
});
canvas.addEventListener('mousemove', function(e) {
  if (drawing) {
    var coord = {
      'x': e.clientX - this.offsetLeft,
      'y': e.clientY - this.offsetTop
    };
    if (prev !== undefined) {
      context.beginPath();
      context.moveTo(prev.x, prev.y);
      context.lineTo(coord.x, coord.y);
      context.stroke();
    }
    prev = coord;
  }
});
canvas.addEventListener('mouseup', function() {
  drawing = false;
  prev = undefined;
});
#draw {
  border: 2px outset black;
  border-radius: 5px;
  display: inline-block;
  margin: 5px;
  padding: 10px;
}
#container {
  border: 2px solid black;
  width: 300px;
  height: 300px;
  position: relative;
}
#canvas {
  background-color: lightgrey;
}
#colors {
  float: right;
  position: relative;
  width: 20%;
  height: 100%;
}
#colors div {
  width: 100%
}
#buttons {
  width: 100%;
  height: auto;
}
#buttons * {
  width: 33%;
  background-color: lightgrey;
  margin-top: 5px;
  margin-left: 5px;
  display: inline;
}
#download {
  text-align: center;
  border-radius: 2px;
  padding-left: 5px;
  padding-right: 5px;
  border: 2px outset lightgrey;
  font-family: 'Arial';
  background-color: lightgrey;
  font-size: 10pt;
  cursor: context-menu;
}
#download:link {
  text-decoration: none;
  color: black;
}
#download:active {
  border: 2px inset #00acff;
  border-radius: 2px;
}
#current {
  height: 100%;
  width: 10%;
  border: 1px solid black;
  display: inline;
  position: relative;
  margin-left: 25px;
}
<div id='draw'>
  <div id='container'>
    <canvas id='canvas' width='240' height='300'></canvas>
    <div id='colors'>
      <div id='red'></div>
      <div id='blue'></div>
      <div id='green'></div>
      <div id='black'></div>
      <div id='yellow'></div>
      <div id='cyan'></div>
      <div id='magenta'></div>
    </div>
    <div id='currentColor'></div>
  </div>
  <div id='buttons'>
    <input type='button' id='clear' value='Clear Canvas' onclick='clearCanvas()' />
    <a id='download'>Download Image</a>
    <input type='button' id='current' />
  </div>
</div>

http://jsfiddle.net/SirToadstool/eywraw8t/341261/

虽然这段代码可以在 JSFiddle 中运行,但在外部对其进行测试时,用户绘制的线条与鼠标指针的坐标不同。

我感觉我包含在代码中的 CSS 可能会弄乱 Javascript 中坐标的计算方式,但我不确定要更改什么来补偿,并尝试使用 clientX/Y 和 @ 987654327@ 用于坐标,而不仅仅是event.x/event.y

关于如何在绘图时更正计算坐标的任何建议?

【问题讨论】:

  • 有趣的是,在 sn-p 中,它有错误的行为。你的代码看起来很简单,如果没有人回答,我有时间会研究一下。
  • 这个答案可以帮助stackoverflow.com/a/8398189/1309377特别是findxy函数。
  • 在我的笔记本电脑上,分辨率为 1920 x 1080,我可以通过将 coord 修改为以下内容来解决这个问题:var coord = { 'x': event.clientX - this.offsetLeft - 25, 'y': event.clientY - this.offsetTop - 25,尽管我不完全确定 @ 是什么987654332@ 相关,因为我确定它与某事有关!

标签: javascript html css canvas


【解决方案1】:

this.offsetLeft 等于 0。这就是为什么减去它什么都不做,因为在函数的范围内,“this”就是画布本身。而不是clientX\Y,你要使用鼠标事件offsetX\Y,那么简单,这样:

var coord = { 'x': e.offsetX, 'y': e.offsetY };

working example

【讨论】:

  • 在这种情况下offset 到底是什么意思?
  • @Delfino quote from link: "提供了鼠标指针的 X 坐标在该事件和目标节点的填充边缘之间的偏移量。".
【解决方案2】:

canvas.width 是绘图画布的宽度,这不一定是画布元素的宽度。这意味着画布上下文可以具有与屏幕不同的分辨率。所以你需要相应地调整你的坐标。即

var coord = {
  'x': (e.clientX - this.offsetLeft)*this.width/this.clientWidth,
  'y': (e.clientY - this.offsetTop)*this.height/this.clientHeight
};

【讨论】:

    猜你喜欢
    • 2021-09-22
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    相关资源
    最近更新 更多