繁体   English   中英

在鼠标按下事件中选择的两点之间画一条直线

[英]Draw a straight line between two points selected in a mouse down event

我有一个代码,当我在单击鼠标时移动鼠标(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>

您想存储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是按下按钮时鼠标 position 和drawStarightLine()是释放所述按钮时执行的方法。 还在线条中添加了不同的 colors 以使其明显。

只需添加另一个 position object 例如

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

然后当鼠标按下事件发生时记录 position

  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会两次渲染路径段并降低线条的质量(抗锯齿上的 alpha 太强)。 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();
  };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM