0

I'm writing a drawing app (MS Paint clone) in JavaScript for educational purposes. To be brief, I set a onMouseMove handler on the canvas element, and inside it, if the mouse is down, I plot whatever pixel the mouse is over. Problem is that unless I move the mouse very, very, VERY slowly, it'll skip several points. It's almost as if the browser isn't firing the mouse event callback fast enough.

How can I overcome this?

I even tried making the canvas really small (100x100), but the same behavior is manifested. I'm on a brand new Mac Book Pro (2016), so I'm not sure that the problem is with my hardware.

enter image description here

canvas.el.addEventListener('mousemove', function (event) {
  if (!mouseDown) {
    return;
  }

  var x = event.offsetX;
  var y = event.offsetY;
  plot(tools.selected, canvas, x, y);
});

function plot(tool, canvas, x, y) {
  var kernel = [];

  if (tool === 'pencil') {
    kernel.push([x, y]);
  } else if (tool === 'brush') {
    for (var w = -5; w < 5; w++) {
      for (var h = -5; h < 5; h++) {
        kernel.push([x - w, y - h]);
      }
    }
  }

  if (kernel.length > 0) {
    kernel.map(function (pt) {
      canvas.ctx.fillRect(pt[0], pt[1], 1, 1);
    });
  }
}

// Setting mouseDown
canvas.el.addEventListener('mousedown', function (event) {
  mouseDown = true;
  var x = event.offsetX;
  var y = event.offsetY;
  plot(tools.selected, canvas, x, y);
});

canvas.el.addEventListener('mouseup', function () {
  mouseDown = false;
});
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
rodrigo-silveira
  • 12,607
  • 11
  • 69
  • 123
  • I suggest using debounce in your code https://css-tricks.com/debouncing-throttling-explained-examples/ – Gino Llerena Feb 21 '17 at 03:36
  • Didn't solve the issue – rodrigo-silveira Feb 21 '17 at 03:49
  • 1
    Draw a line instead of a "dot", between the previous point and current. You can also interpolate along that line if you need to support special brushes. You can find the basis in my answer [here](https://stackoverflow.com/questions/30631032/continuous-gradient-along-a-html5-canvas-path/30632301#30632301). –  Feb 21 '17 at 05:02
  • 1
    That's what I ended up doing. Also, instead of plotting multiple pixels around the client target when trying to do a thicker brush, I just set the `ctx.lineWidth` when a thicker brush is selected. Thanks for the feedback. – rodrigo-silveira Feb 21 '17 at 05:06

0 Answers0