如何在图像上拖放绘制的多边形

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在图像上拖放绘制的多边形相关的知识,希望对你有一定的参考价值。

如何在图像上拖放绘制的多边形

  1. 目前通过鼠标点击在图像上绘制多边形,我可以对最新绘制的多边形执行撤消操作,但是如何对所选多边形执行拖放操作 并在位置变更时更新坐标 保存数组中的坐标(目前我在做)

//radius of click around the first point to close the draw
var END_CLICK_RADIUS = 15;
//the max number of points of your polygon
var MAX_POINTS = 4;

var mouseX = 0;
var mouseY = 0;
var isStarted = false;
var polygons = [];

var canvas = null;
var ctx;
var image;

window.onload = function() {
  var background = document.getElementById('justanimage');
  //initializing canvas and draw color
  canvas = document.getElementById("canvas");
  ctx = canvas.getContext("2d");
  image = new Image();
  image.onload = function() {
    ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
  };
  image.src = 'https://images.freeimages.com/images/large-previews/2fe/butterfly-1390152.jpg';
  canvas.addEventListener("click", function(e) {
    var x = e.clientX - canvas.offsetLeft;
    var y = e.clientY - canvas.offsetTop;
    if (isStarted) {
      //drawing the next line, and closing the polygon if needed
      if (Math.abs(x - polygons[polygons.length - 1][0].x) < END_CLICK_RADIUS && Math.abs(y - polygons[polygons.length - 1][0].y) < END_CLICK_RADIUS) {
        isStarted = false;
      } else {
        polygons[polygons.length - 1].push(new Point(x, y));
        if (polygons[polygons.length - 1].length >= MAX_POINTS) {
          isStarted = false;
        }
      }
    } else {
      //opening the polygon
      polygons.push([new Point(x, y)]);
      isStarted = true;
    }
  }, false);

  //we just save the location of the mouse
  canvas.addEventListener("mousemove", function(e) {
    mouseX = e.clientX - canvas.offsetLeft;
    mouseY = e.clientY - canvas.offsetTop;
  }, false);

  //refresh time
  setInterval("draw();", 5);
}

//object representing a point
function Point(x, y) {
  this.x = x;
  this.y = y;
}

//resets the application
function reset() {
  isStarted = false;
  points = null;
  document.getElementById("coordinates").innerhtml = " ";
}

//draws the current shape
function draw() {
  ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
  ctx.lineWidth = 2;
  ctx.strokeStyle = '#ff0000';
  polygons.forEach(function(points, i) {
    ctx.beginPath();
    points.forEach(function(p, j) {
      if (j) {
        ctx.lineTo(p.x, p.y);
      } else {
        ctx.moveTo(p.x, p.y);
      }
    });
    if (i + 1 === polygons.length && isStarted) { // just the last one
      ctx.lineTo(mouseX, mouseY);
    } else {
      ctx.lineTo(points[0].x, points[0].y);
    }
    ctx.stroke();
  });

}

function undoLastPoint() {
  // remove the last drawn point from the drawing array
  polygons.pop();
}
<canvas id="canvas" width="500" height="500"></canvas>
<button type="button" onclick="undoLastPoint()">Undo</button>
<img id="justanimage" />
答案

canvas元素以“立即模式”呈现,这意味着画布不跟踪已绘制的形状。它“忘记了”绘制后立即绘制的所有内容。因此,没有内置的方法来选择形状或路径并拖动它,因为画布不再知道形状。你必须自己构建它。

  1. 选择路径:在绘制时,您可以使用CanvasRenderingContext2D.isPointInPath(),如果鼠标单击坐标之类的坐标在当前路径内,则返回true。 “当前”表示在绘制路径之后和从上下文堆栈中删除路径之前,需要立即调用此函数。 (见https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/isPointInPath
  2. 拖动:为了能够在使用isPointInPath()检测到已经单击的路径之后拖动路径,您需要存储坐标(可能是颜色)并将旧坐标转换为鼠标的新位置并重绘路径。为了做到动画这样,用户可以看到路径如何随鼠标移动,您需要尽可能多地重绘整个图像。这可以使用window.requestAnimationFrame()完成(参见https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_animations

以上是关于如何在图像上拖放绘制的多边形的主要内容,如果未能解决你的问题,请参考以下文章

如何在散点图上拖放

如何在 Objective-C 中的地图上拖放和拖动图钉

C# 在 Canvas 中拖放图像

解释如何在 GTK+3.0 上拖放

如何在 OSX 上拖放期间检测 META 按键

在触摸屏上拖放