Javascript Canvas 绘制矩形或圆形

Javascript Canvas draw rectangles or circles

我正在寻找一种方法来 "live" 在 canvas 上绘制矩形或圆形。

我找到了多种使用 fillRect() 绘制矩形的方法,但不是实时的。我的意思是,能够在一个点上 mouseDown() 并将其移动到 canvas 中的另一个点,它定义了 canvas 的大小,就像 Microsoft Paint 中的例子一样, OneNote 等等

任何人都可以帮助我并就如何开始给我一些建议吗?我可能正在考虑如何做到这一点,而不会看到矩形(或圆形)大小发生变化,例如:

 $("canvas").mousedown(function(event){
     var ctx = this.getContext("2d");
     ctx.clearRect(0,0,$(this).width(),$(this).height());
     var initialX = event.clientX - this.getBoundingClientRect().left;
     var initialY = event.clientY - this.getBoundingClientRect().top;

     $(this).mousemove(function(evt) {
         ctx.strokeRect(initialX, initialY, evt.clientX - event.clientX, evt.clientY - event.clientY);
     });
 });

但我想现场观看,所以当用户移动鼠标时矩形大小如何变化。

https://jsfiddle.net/zb66mxra/2/

要做到这一点,您需要始终保持 Canvas 的形象。这很容易实现,方法是让你的 JavaScript.

一遍又一遍地绘制一组对象。
let drawArr = [];

示例对象包含开始绘制的 x 和 y 坐标、宽度和高度:

 { x: 100,
  y: 100,
  w: 10,
  h: 10  }

当您的鼠标移到 canvas 上时,您只希望它在鼠标按下时更改数组。这意味着您需要设置一个标志来查看这种情况是真还是假:

  let mousedown = false;
  canvas.addEventListener('mousedown', function(e) {
    mousedown = true;
  ...
  });
  canvas.addEventListener('mouseup', function(e) {
    mousedown = false;
  });

当您按下鼠标时,您想添加一个要绘制到数组的项目:

  canvas.addEventListener('mousedown', function(e) {
  mousedown = true;
  drawArr.push({
    x: e.pageX,
    y: e.pageY,
    w: 0,
    h: 0
  });
});

高度和宽度最初设置为 0。如果您可以想象,我们现在要做的是在将鼠标拖到 canvas 上时创建矩形的高度和宽度并且鼠标已关闭。我们想即时调整它,以便在重新渲染屏幕时可以看到它正在绘制。

操作高度和宽度很容易,因为只要您一次只能绘制一个,它就始终是添加到绘制数组的最新对象。

  canvas.addEventListener('mousemove', function(e) {
  if (mousedown) {
    let i = drawArr.length -1;

    let {
      x,
      y
    } = drawArr[i];
    drawArr[i].w = e.pageX - x;
    drawArr[i].h = e.pageY - y;
  }
});

最后我们使用requestAnimationFrame不断地绘制draw数组中的任何对象。我们通过在页面加载时调用它来做到这一点:

requestAnimationFrame(draw);

然后在绘图函数中递归:

function draw() {
...
requestAnimationFrame(draw);
}

然后我们只需要清除之前的屏幕渲染并遍历绘制数组并再次将所有内容绘制到屏幕上。

  function draw() {
    ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
    for (let obj of drawArr) {
    let {
      x,
      y,
      w,
      h
     } = obj;
      ctx.strokeRect(x, y, w, h);
    }
    requestAnimationFrame(draw);
  }

瞧。