Нарисуйте прямую линию между двумя точками, выбранными в событии мыши вниз - PullRequest
0 голосов
/ 05 ноября 2019

У меня есть код, который рисует линию, когда я двигаю мышь, щелкая мышью (событие mousedown и mousemove).

Я также хочу, чтобы прямая линия проводилась от начала точки (гдеСначала я щелкнул точку (событие mousedown) до конца (где я поднимаю событие мыши, событие mouseup).

(function() {
      var canvas = document.querySelector('#paint');
      var ctx = canvas.getContext('2d');

      var sketch = document.querySelector('#sketch');
      var sketch_style = getComputedStyle(sketch);
      canvas.width = parseInt(sketch_style.getPropertyValue('width'));
      canvas.height = parseInt(sketch_style.getPropertyValue('height'));

      var mouse = {
        x: 0,
        y: 0
      };
      
      var last_mouse = {
        x: 0,
        y: 0
      };

      /* Mouse Capturing Work */
      canvas.addEventListener('mousemove', function(e) {
        last_mouse.x = mouse.x;
        last_mouse.y = mouse.y;

        mouse.x = e.pageX - this.offsetLeft;
        mouse.y = e.pageY - this.offsetTop;
      }, false);


      /* Drawing on Paint App */
      ctx.lineWidth = 5;
      ctx.lineJoin = 'round';
      ctx.lineCap = 'round';
      ctx.strokeStyle = 'black';

      canvas.addEventListener('mousedown', function(e) {
        canvas.addEventListener('mousemove', onPaint, false);
      }, false);

      canvas.addEventListener('mouseup', function() {
        canvas.removeEventListener('mousemove', onPaint, false);
      }, false);

      var onPaint = function() {
        ctx.beginPath();
        ctx.moveTo(last_mouse.x, last_mouse.y);
        ctx.lineTo(mouse.x, mouse.y);
        ctx.closePath();
        ctx.stroke();
      };
    }());
#sketch{
  width: 100%;
  height: 200px;
  background-color: #CCCCCC;
}
<div id="sketch">
  <canvas id="paint">
  </canvas>
</div>

Ответы [ 2 ]

2 голосов
/ 05 ноября 2019

Вы хотите сохранить координаты события mouseDown, а затем использовать их, чтобы нарисовать одну линию с координатами события mouseUp. Я изменил ваш код, чтобы показать, как это можно сделать:

(function() {
      var canvas = document.querySelector('#paint');
      var ctx = canvas.getContext('2d');

      var sketch = document.querySelector('#sketch');
      var sketch_style = getComputedStyle(sketch);
      canvas.width = parseInt(sketch_style.getPropertyValue('width'));
      canvas.height = parseInt(sketch_style.getPropertyValue('height'));

      var mouse = {
        x: 0,
        y: 0
      };
      
      var last_mouse = {
        x: 0,
        y: 0
      };

      /* Mouse Capturing Work */
      canvas.addEventListener('mousemove', function(e) {
        last_mouse.x = mouse.x;
        last_mouse.y = mouse.y;

        mouse.x = e.pageX - this.offsetLeft;
        mouse.y = e.pageY - this.offsetTop;
      }, false);


      /* Drawing on Paint App */
      ctx.lineWidth = 5;
      ctx.lineJoin = 'round';
      ctx.lineCap = 'round';
      ctx.strokeStyle = 'black';
      canvas.addEventListener('mousedown', function(e) {
        initialPoint = {x:mouse.x, y:mouse.y}
        canvas.addEventListener('mousemove', onPaint, false);
      }, false);

      canvas.addEventListener('mouseup', function() {
        drawStraightLine()
        canvas.removeEventListener('mousemove', onPaint, false);
      }, false);

      var onPaint = function() {
        ctx.beginPath();
        ctx.moveTo(last_mouse.x, last_mouse.y);
        ctx.lineTo(mouse.x, mouse.y);
        ctx.strokeStyle = "#000000";
        ctx.closePath();
        ctx.stroke();
      };
      
      let initialPoint
      const drawStraightLine = function() {
        ctx.beginPath();
        ctx.moveTo(initialPoint.x, initialPoint.y);
        ctx.lineTo(mouse.x, mouse.y);
        ctx.strokeStyle = "#FF000077";
        ctx.stroke();
      }
    }());
#sketch{
  width: 100%;
  height: 180px;
  background-color: #DDDDDD;
}
<div id="sketch">
  <canvas id="paint" />
</div>

initialPoint - позиция мыши при нажатии кнопки, а drawStarightLine() - метод, выполняемый при отпускании указанной кнопки. Также добавлены различные цвета к линиям, чтобы сделать это очевидным.

1 голос
/ 05 ноября 2019

Просто добавьте еще один объект позиции, например

  const mouseDownAt = {x: 0, y: 0};

Затем, когда произойдет событие нажатия мыши, запишите эту позицию

  canvas.addEventListener('mousedown', function(e) {

    mouseDownAt.x = e.pageX - this.offsetLeft;
    mouseDownAt.y = e.pageY - this.offsetTop;

    canvas.addEventListener('mousemove', onPaint, false);
  }, false);

При событии мыши вверх нарисуйте линию закрытия

  canvas.addEventListener('mouseup', function() {
    lastMouse.x = mouse.x;
    lastMouse.y = mouse.y;
    mouse.x = e.pageX - this.offsetLeft;
    mouse.y = e.pageY - this.offsetTop;

    // if mouse has moved?? draw the last little bit
    if (mouse.x !== last_mouse.x || mouse.y !== last_mouse.y) {
         onPaint();
    }

    // set the end position
    lastMouse.x = mouse.x;
    lastMouse.y = mouse.y;

    // use the mouse down at pos as the new position
    mouse.x = mouseDownAt.x;
    mouse.y = mouseDownAt.y;

    // draw the line
    onPaint();

    canvas.removeEventListener('mousemove', onPaint, false);
  }, false);

Кстати, я не уверен, знаете ли вы, что использование closePath, как вы делаете, отрендерит сегмент пути в два раза и снизит качество линии (слишком сильные альфы на сглаживании). closePath похоже на lineTo (рисует отрезок линии) и не связано с ctx.beginPath

  function onPaint () {
    ctx.beginPath();
    ctx.lineTo(lastMouse.x, lastMouse.y);  // after beginPath lineTo is the same
                                             // moveTo
    ctx.lineTo(mouse.x, mouse.y);
    ctx.stroke();
  };
...