如何在html5 canvas中用它的连接线拖动点?

How to drag points with it's connecting line in html5 canvas?

以下是我的代码。拖动点时遇到问题。问题是每当我拖动点时,所有的线都连接到一个点。我需要在 html5 Canvas 中有可拖动的点。但是我有一个补充约束:这 2 个点必须用一条线连接起来。当我拖动一个点时,线必须是动态绘制的,并且仍然链接到2个点。

let points= [];
let drag_point= -1;
let pointSize= 6;
let canvas = document.querySelector("#myCanvas");
let w = canvas.width;
let h = canvas.height;

var ctx = canvas.getContext("2d");

            $("#myCanvas").mousedown(function (e) {
                var pos = getPosition(e);
                drag_point = getPointAt(pos.x, pos.y);
                console.log("pos", drag_point);
                if (drag_point == -1) {
                    // no point at that position, add new point
                    drawlines(pos.x, pos.y);
                    points.push(pos);
                }
            });
            $("#myCanvas").mousemove(function (e) {
                if (drag_point != -1) {
                    // if currently dragging a point...
                    var pos = getPosition(e);
                    //...update that.points position...
                    points[drag_point].x = pos.x;
                    points[drag_point].y = pos.y;
                    redraw(); // ... and redraw myCanvas
                }
            });
            $("#myCanvas").mouseup(function (e) {
                drag_point = -1;
            });
    function getPosition(event) {

                var rect = canvas.getBoundingClientRect();
                var x = event.clientX - rect.left;
                var y = event.clientY - rect.top;
                console.log(x, y);
                return { x: x, y: y };

            }
    function getPointAt(x, y) {
                for (var i = 0; i < points.length; i++) {
                    if (
                        Math.abs(points[i].x - x) < pointSize &&
                        Math.abs(points[i].y - y) < pointSize
                    )
                        // check if x,y is inside points bounding box. replace with pythagoras theorem if you like.
                        return i;
                }
                return -1; // no point at x,y
            }

        function    redraw() {

                ctx.clearRect(0, 0, canvas.width, canvas.height); // clear canvas

                for (var i = 0; i < points.length; i++) {
                    // draw all points again
                    drawlines(points[i].x, points[i].y);
                }
            }

function drawlines(x, y) {
        
                drawImages(x, y);

                if (points.length > 0) {
                    var last = points[points.length - 1];
                    ctx.beginPath();
                    ctx.moveTo(last.x, last.y);
                    ctx.lineTo(x, y);
                    ctx.strokeStyle = "blue";
                    ctx.stroke();
                }

            }
            function drawImages(x, y) {
                var ctx = document.getElementById("myCanvas").getContext("2d");
                ctx.beginPath();
                ctx.arc(x, y, pointSize, 0, Math.PI * 2, true);
                ctx.strokeStyle = "red";
                ctx.stroke();
            }
      
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas
            id="myCanvas"
            width="1000"
            height="1000"
            style="border: 1px solid #d3d3d3"
        ></canvas>

.

查看下面的代码...

我重构了你的 drawlinesdrawImages 以独立调用而不是在一个公共循环中,在我的代码中我们画了所有的线,然后我们画了所有的圆,这样我们就没有了一直来回改变颜色并防止圆圈上的线条重叠,鼠标按下还有另一个变化我称之为重绘而不是画线。

根据你的代码猜测问题出在你的:
var last = points[points.length - 1];
这看起来很不对劲,从技术上讲,这使得最后一个总是相同的

let points = [{x:10,y:10},{x:55,y:50},{x:100,y:10}];
let drag_point = -1;
let pointSize = 6;
let canvas = document.querySelector("#myCanvas");
var ctx = canvas.getContext("2d");

$("#myCanvas").mousedown(function(e) {
  var pos = getPosition(e);
  drag_point = getPointAt(pos.x, pos.y);
  if (drag_point == -1) {
    points.push(pos);
    redraw();
  }
});
$("#myCanvas").mousemove(function(e) {
  if (drag_point != -1) {
    var pos = getPosition(e);
    points[drag_point].x = pos.x;
    points[drag_point].y = pos.y;
    redraw(); 
  }
});
$("#myCanvas").mouseup(function(e) {
  drag_point = -1;
});

function getPosition(event) {
  var rect = canvas.getBoundingClientRect();
  var x = event.clientX - rect.left;
  var y = event.clientY - rect.top;
  return {x, y};
}

function getPointAt(x, y) {
  for (var i = 0; i < points.length; i++) {
    if (
      Math.abs(points[i].x - x) < pointSize &&
      Math.abs(points[i].y - y) < pointSize
    )
      return i;
  }
  return -1; 
}

function redraw() {
  if (points.length > 0) {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawLines()
    drawCircles()
  }
}

function drawLines() {
  ctx.beginPath();
  ctx.moveTo(points[0].x, points[0].y);
  ctx.strokeStyle = "blue";
  ctx.lineWidth = 2;
  points.forEach((p) => {
    ctx.lineTo(p.x, p.y);
  })
  ctx.stroke();
}

function drawCircles() {
  ctx.strokeStyle = "red";
  ctx.lineWidth = 4;
  points.forEach((p) => {
    ctx.beginPath();
    ctx.arc(p.x, p.y, pointSize, 0, Math.PI * 2, true);
    ctx.stroke();
  })
}

redraw()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="myCanvas" width="160" height="160" style="border: 1px solid #d3d3d3"></canvas>