使用鼠标位置绘制圆形

4

我试图通过点击鼠标并拖动来绘制圆形。就像在PowerPoint或其他软件中所做的那样。但是圆心出现在奇怪的位置,我无法解释。

这是jsfiddle链接:https://jsfiddle.net/h8t3hfa2/2/

以下是获取起始和结束位置的方法:

$('#c').mousedown(function(event) {
  var parentOffset = $(this).offset();
  circle = new Circle();
  circle.start['x'] = event.pageX - parentOffset.left;
  circle.start['y'] = event.pageY - parentOffset.top;

});

$('#c').mouseup(function(event) {
  var parentOffset = $(this).offset();
  circle.end['x'] = event.pageX - parentOffset.left;
  circle.end['y'] = event.pageY - parentOffset.top;
  circle.draw(canvas[0]);

});

当我在控制台记录中间点时,它看起来是正确的,但圆圈出现在其他地方。有什么想法吗?

请查看这些之前在Stackoverflow上的问答:从开始拖动点向外绘制一圆 Drawing a circle outward from the starting drag point 在开始和结束拖动点之间绘制一圆 Drawing a circle between the starting & ending drag points: - markE
2个回答

6

这种情况通常是因为你使用CSS缩放了画布。请记住,画布的尺寸与画布CSS(样式)尺寸不同。

一个快速解决方法是将它们相等:

canvas.get(0).width = canvas.width();
canvas.get(0).height = canvas.height();

https://jsfiddle.net/h8t3hfa2/3/

var Circle = function() {
  this.start = [];
  this.end = [];
}
Circle.prototype.draw = function(canvas) {
  var me = this;

  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');
    var mid = me.getcenter();
    var rad = me.getradius();
    console.log(mid, rad);
    ctx.beginPath();
    console.log(mid['x'], mid['y']);
    ctx.arc(mid['x'], mid['y'], rad, 0, 360);
    ctx.stroke();
  }

};

Circle.prototype.getcenter = function() {
  var me = this;
  //Check the start and end are set
  var centerX = (me.start['x'] + me.end['x']) / 2;
  var centerY = (me.start['y'] + me.end['y']) / 2;

  return {
    'x': centerX,
    'y': centerY
  };
};

Circle.prototype.getradius = function() {
  var me = this;
  var distX = Math.abs(me.start['x'] - me.end['x']);
  var distY = Math.abs(me.start['y'] - me.end['y']);

  return distX / 2;
};

var circle;
var canvas = $('#c');

// added only these two lines
canvas.get(0).width = canvas.width();
canvas.get(0).height = canvas.height();

$('#c').mousedown(function(event) {
  var parentOffset = $(this).offset();
  circle = new Circle();
  circle.start['x'] = event.pageX - parentOffset.left;
  circle.start['y'] = event.pageY - parentOffset.top;

});

$('#c').mouseup(function(event) {
  var parentOffset = $(this).offset();
  circle.end['x'] = event.pageX - parentOffset.left;
  circle.end['y'] = event.pageY - parentOffset.top;
  circle.draw(canvas[0]);

});
canvas {background-color: white;height: 100%;width: 100%;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id='c'></canvas>

由于使用了流体布局,当窗口大小改变时,您应该添加一个onresize事件处理程序来重置画布的尺寸。但要小心,修改任何一个画布尺寸(即使是恢复原始大小)都会导致画布清除。


啊哈,这也解释了为什么我的圆形被扭曲了。非常感谢。 - Dan
是的,锯齿状的边缘明显表明CSS出现了一些扭曲。不用谢! - Shomz

0

从样式中删除height: 100%; width: 100%;可以避免问题。

离题了,但我建议编辑getradius以使用distXdistY的最小值(或最大值)(而不是硬编码distX),就像你提到的应用程序一样。

Circle.prototype.getradius = function() {
  var me = this;
  var distX = Math.abs(me.start['x'] - me.end['x'])/2;
  var distY = Math.abs(me.start['y'] - me.end['y'])/2;

  return Math.min(distX, distY);
};

100%的高度和宽度是有原因的,所以这并不能解决问题,而只是避免了它。 - Shomz
对此我很抱歉。我只是想通过指出问题的原因来帮助您。我更新了我的回答,说它“避免”了这个问题。希望这样可以接受。 :/ - sina
没关系,当然可以,我只是想让你改进一下你的答案,因为这个会修改网页的布局,而这不是 OP 想要的(我相信)。问题在于画布的宽度和高度与画布的 CSS 宽度和高度不同。 :) - Shomz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接