技术就餐

导航

利用canvas手动绘制图形,点位可拖拽,整体可拖动

 

 

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>DEMO演示</title>
</head>
<style>

</style>

<body>
  <canvas id="demo" width="800" height="400" ></canvas>
</body>

</html>
<script>
  var canvas = document.getElementById('demo')
  var context = canvas.getContext('2d')
  //线段的点的集合
  var points = [];
  //可拖动圆圈的点的集合
  var circles = [];
  //整体移动点位
  var allpoints = []
  var isDragging = false
  //是否在绘制区域内
  var isInOut = false
  //记录鼠标点击位置
  var downx = 0
  var downy = 0
  //每一个点的对象
  function Point(x, y) {
    this.x = x;
    this.y = y;
  }
  //圆圈对象
  function Circle(x, y) {
    this.x = x;
    this.y = y;
    this.radius = 10;
    this.color = "blue";
    //拖拽点的标记
    this.isSelected = false;
  }
  canvas.onmousedown = function (e) {
    var clickX = e.pageX - canvas.offsetLeft;
    var clickY = e.pageY - canvas.offsetTop;
    downx = clickX
    downy = clickY
    if (isInt(clickX, clickY)) {
      isInOut = true
      return
    } else {
      isInOut = false
    }
    //判断当前点击点是否在已经绘制的圆圈上,如果是执行相关操作,并return,不进入画线的代码
    for (var i = 0; i < circles.length; i++) {
      var circle = circles[i];
      //使用勾股定理计算这个点与圆心之间的距离
      var distanceFromCenter = Math.sqrt(Math.pow(circle.x - clickX, 2)
        + Math.pow(circle.y - clickY, 2));

      // 如果是其他的点,则设置可以拖动
      if (distanceFromCenter <= circle.radius) {
        // 清除之前选择的圆圈
        index = i;
        isDragging = true;
        //停止搜索
        return;
      }
    }
    //如果点击新的位置,则进入下面的代码,绘制点
    context.clearRect(0, 0, canvas.width, canvas.height);
    //遍历数组画圆
    var circle = new Circle(clickX, clickY);
    circles.push(circle);
    allpoints = JSON.parse(JSON.stringify(circles))
    circles[0].color = "green";
    for (var i = 0; i < circles.length; i++) {
      var circle = circles[i];
      // 绘制圆圈
      context.globalAlpha = 0.85;
      context.beginPath();
      context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
      context.fillStyle = circle.color;
      context.strokeStyle = "black";
      context.fill();
      context.stroke();
    }
    // 画线
    var point = new Point(clickX, clickY);
    points.push(point);
    context.beginPath();
    context.lineWidth = 4;
    //从起始点开始绘制
    context.moveTo(points[0].x, points[0].y);
    for (var i = 0; i < points.length; i++) {
      context.lineTo(points[i].x, points[i].y);
    }
    context.closePath()
    context.fillStyle = "rgb(2,100,30)";
    context.fill();
    context.strokeStyle = "#9d4dca";
    context.stroke();
  };
  canvas.onmousemove = function (e) {
    // 取得鼠标位置
    var x1 = e.pageX - canvas.offsetLeft;
    var y1 = e.pageY - canvas.offsetTop;
    //判断是否在区域内整体拖动
    if (isInOut && !isDragging) {
      var x2 = x1 - downx
      var y2 = y1 - downy
      context.clearRect(0, 0, canvas.width, canvas.height);
      for (var j = 0; j < allpoints.length; j++) {
        circles[j].x = allpoints[j].x + x2
        circles[j].y = allpoints[j].y + y2
      }
      points = JSON.parse(JSON.stringify(circles))
      for (var i = 0; i < circles.length; i++) {
        var circle = circles[i];
        // 绘制圆圈
        context.globalAlpha = 0.85;
        context.beginPath();
        context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
        context.fillStyle = circle.color;
        context.strokeStyle = "black";
        context.fill();
        context.stroke();
      }
      context.beginPath();
      context.moveTo(points[0].x, points[0].y);
      for (var i = 0; i < points.length; i++) {
        context.lineTo(points[i].x, points[i].y);
      }
      // context.lineTo(points[0].x, points[0].y);
      // context.fillStyle="#831f68";
      context.closePath()
      context.fillStyle = "rgb(2,100,30)";
      context.fill();
      context.strokeStyle = "#9d4dca";
      context.stroke();

    }
    // 判断圆圈是否开始拖拽
    if (isDragging == true) {
      // 判断拖拽对象是否存在
      context.clearRect(0, 0, canvas.width, canvas.height);
      //根据上文得到的index设置index点位置随鼠标改变
      circles[index].x = x1;
      circles[index].y = y1;
      points[index].x = x1;
      points[index].y = y1;
      allpoints = JSON.parse(JSON.stringify(points))
      for (var i = 0; i < circles.length; i++) {
        var circle = circles[i];
        // 绘制圆圈
        context.globalAlpha = 0.85;
        context.beginPath();
        context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
        context.fillStyle = circle.color;
        context.strokeStyle = "black";
        context.fill();
        context.stroke();
      }
      context.beginPath();
      context.moveTo(points[0].x, points[0].y);
      for (var i = 0; i < points.length; i++) {
        context.lineTo(points[i].x, points[i].y);
      }
      // context.lineTo(points[0].x, points[0].y);
      // context.fillStyle="#831f68";
      context.closePath()
      context.fillStyle = "rgb(2,100,30)";
      context.fill();
      context.strokeStyle = "#9d4dca";
      context.stroke();
    }
  };
  //判断点位是否在图形区域内
  function isInt(x, y) {
    if (!points[2]) {
      return
    }
    var pt = {
      x: x,
      y: y
    }
    var poly = points
    return PointInPoly(pt, poly)
  }
  //射线法判断点位
  function PointInPoly(pt, poly) {
    for (var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
      ((poly[i].y <= pt.y && pt.y < poly[j].y) || (poly[j].y <= pt.y && pt.y < poly[i].y))
        && (pt.x < (poly[j].x - poly[i].x) * (pt.y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x)
        && (c = !c);
    return c;
  }
  canvas.onmouseup = function () {
    isDragging = false;
    isInOut = false
    allpoints = JSON.parse(JSON.stringify(circles))
  };

  canvas.onmouseout = function () {
    isDragging = false;
    isInOut = false
  };

</script>

posted on 2021-12-14 18:34  技术就餐  阅读(1575)  评论(0编辑  收藏  举报