我在绘图程序中的 undoTheUndo 不能在圆上做,而是在线上做

My undoTheUndo in a drawing program can't do it on circles but on lines

我正在制作一个绘图程序,您可以在其中绘图,撤消上一个动作以及撤消上一个动作的撤消。例如: helo (drawing, action I) ---D hello (drawing action II) ---D helo (Undoing) ---D hello (Undoing the undo I did). 这是我的代码:Click here
这是我的 javascript :

var ctx = document.getElementById("canvasId").getContext("2d");
var DrawnSaves = new Array();
var Undo = new Array();
var FigureNumber = -1;
var deletingTimer;

function drawLine(startX, startY, destX, destY) {
  ctx.beginPath();
  ctx.moveTo(startX, startY);
  ctx.lineTo(destX, destY);
  ctx.stroke();
  var Para = new Array();
  Para["type"] = "line";
  Para["fromX"] = startX;
  Para["fromY"] = startY;
  Para["toX"] = destX;
  Para["toY"] = destY;
  DrawnSaves.push(Para);
  FigureNumber++;
}

function drawCircle(X, Y, radius) {
  ctx.beginPath();
  ctx.arc(X, Y, radius, 0, Math.PI * 2);
  ctx.stroke();
  var Para = new Array();
  Para["type"] = "circle";
  Para["x"] = X;
  Para["y"] = Y;
  Para["radius"] = radius;
  DrawnSaves.push(Para);
  FigureNumber++;
}

function undo() {
  ctx.beginPath();
  ctx.clearRect(0, 0, 500, 300);
  Undo[FigureNumber] = DrawnSaves[FigureNumber];
  DrawnSaves[FigureNumber] = "deleted";
  FigureNumber--;
  drawEverything();
  startTimeoutOfDeleting();
}

function undoTheUndo() {
  FigureNumber++;
  DrawnSaves[FigureNumber] = Undo[FigureNumber];
  drawEverything();
  clearTimeout(deletingTimer);
}

function drawEverything() {
  for (i = 0; i < DrawnSaves.length; i++) {
    if (DrawnSaves[i].type == "line") {
      ctx.beginPath();
      ctx.moveTo(DrawnSaves[i].fromX, DrawnSaves[i].fromY);
      ctx.lineTo(DrawnSaves[i].toX, DrawnSaves[i].toY);
      ctx.stroke();
    } else if (DrawnSaves[i].type == "circle") {
      ctx.beginPath();
      ctx.arc(DrawnSaves[i].x, DrawnSaves[i].y, DrawnSaves[i].radius, 0, Math.PI * 2);
    }
  }
}

function startTimeoutOfDeleting() {
  setTimeout(function() {
    Undo[FigureNumber] = "deleted";
  }, 5000);
}

您的代码没有问题,是测试行导致了问题。

setTimeout(function() {    
  drawCircle(100, 100, 25);
  setTimeout(function() {}, 1000);
  setTimeout(function() {
    undo(); // You forgot this undo() here
  }, 1000);
  setTimeout(function() {
    undoTheUndo();
  }, 2000);
}, 3000);

我建议添加一个未定义的检查,如下所示:

function undoTheUndo() {
  FigureNumber++;
  if (Undo[FigureNumber] !== undefined) {
    DrawnSaves[FigureNumber] = Undo[FigureNumber];
  }
  drawEverything();
  clearTimeout(deletingTimer);
}

另外,我在初始化圆圈和线条时抓住了这个机会。

FigureNumber++;
DrawnSaves[FigureNumber] = Para;

JSFiddle

您的 "circle" 案例中缺少 ctx.stroke(),画圆后缺少 undo()

我建议稍微重构您的 drawEverything 函数,以便在添加更多形状时减少前一个错误的可能性:

function drawEverything() {
  for (i = 0; i < DrawnSaves.length; i++) {
    var shape = DrawnSaves[i];
    ctx.beginPath();
    switch (shape.type) {
      case "line":
        ctx.moveTo(shape.fromX, shape.fromY);
        ctx.lineTo(shape.toX, shape.toY);
        break;
      case "circle":
        ctx.arc(shape.x, shape.y, shape.radius, 0, Math.PI * 2);
        break;
    }
    ctx.stroke();
  }
}