2016-04-26 60 views
-2

我正在嘗試實現具有撤消和重做功能的繪畫桶工具。問題是撤消和重做第一次正常工作,但是當我多次撤銷重做時,代碼失敗。任何人都可以幫我解決這個問題嗎?這是我完整的代碼。你可以複製粘貼,它會在你的最後工作。畫布上的縮放和撤消重做操作不正確

<!DOCTYPE html> 
<html> 
    <head> 
     <title>Painitng</title> 
     <style> 
      body { 
       width: 100%; 
       height: auto; 
       text-align: center; 
      } 
      .colorpick { 
       widh: 100%; 
       height: atuo; 
      } 
      .pick { 
       display: inline-block; 
       width: 30px; 
       height: 30px; 
       margin: 5px; 
       cursor: pointer; 
      } 
      canvas { 
       border: 2px solid silver; 
      } 
     </style> 
    </head> 
    <body> 
     <button id="zoomin">Zoom In</button> 
     <button id="zoomout">Zoom Out</button> 
     <button onclick="undo()">Undo</button> 
     <button onclick="redo()">Redo</button> 
     <div id="canvasDiv"></div> 
     <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script> 
     <script type="text/javascript"> 
      var colorYellow = { 
       r: 255, 
       g: 207, 
       b: 51 
      }; 
      var context; 
      var canvasWidth = 500; 
      var canvasHeight = 500; 
      var myColor = colorYellow; 
      var curColor = myColor; 
      var outlineImage = new Image(); 
      var backgroundImage = new Image(); 
      var drawingAreaX = 0; 
      var drawingAreaY = 0; 
      var drawingAreaWidth = 500; 
      var drawingAreaHeight = 500; 
      var colorLayerData; 
      var outlineLayerData; 
      var totalLoadResources = 2; 
      var curLoadResNum = 0; 
      var undoarr = new Array(); 
      var redoarr = new Array(); 
      var uc = 0; 
      var rc = 0; 

      // Clears the canvas. 
      function clearCanvas() { 
       context.clearRect(0, 0, context.canvas.width, context.canvas.height); 
      } 

      function undo() { 
       if (undoarr.length <= 0) 
        return; 

       if (uc==0) { 
        redoarr.push(undoarr.pop()); 
        uc = 1; 
       } 
       var a = undoarr.pop(); 
       colorLayerData = a; 
       redoarr.push(a); 
       clearCanvas(); 
       context.putImageData(a, 0, 0); 
       context.drawImage(backgroundImage, 0, 0, canvasWidth, canvasHeight); 
       context.drawImage(outlineImage, 0, 0, drawingAreaWidth, drawingAreaHeight); 
       console.log(undoarr); 
      } 

      function redo() { 
       if (redoarr.length <= 0) 
        return; 
       if (rc==0) { 
        undoarr.push(redoarr.pop()); 
        rc = 1; 
       } 
       var a = redoarr.pop(); 
       colorLayerData = a; 
       undoarr.push(a); 
       clearCanvas(); 
       context.putImageData(a, 0, 0); 
       context.drawImage(backgroundImage, 0, 0, canvasWidth, canvasHeight); 
       context.drawImage(outlineImage, 0, 0, drawingAreaWidth, drawingAreaHeight); 
       console.log(redoarr); 
      } 
      // Draw the elements on the canvas 
      function redraw() { 
       uc = 0; 
       rc = 0; 
       var locX, 
         locY; 

       // Make sure required resources are loaded before redrawing 
       if (curLoadResNum < totalLoadResources) { 
        return; // To check if images are loaded successfully or not. 
       } 

       clearCanvas(); 
       // Draw the current state of the color layer to the canvas 
       context.putImageData(colorLayerData, 0, 0); 

       undoarr.push(context.getImageData(0, 0, canvasWidth, canvasHeight)); 
       console.log(undoarr); 
       redoarr = new Array(); 
       // Draw the background 
       context.drawImage(backgroundImage, 0, 0, canvasWidth, canvasHeight); 

       // Draw the outline image on top of everything. We could move this to a separate 
       // canvas so we did not have to redraw this everyime. 
       context.drawImage(outlineImage, 0, 0, drawingAreaWidth, drawingAreaHeight); 


      } 
      ; 

      function matchOutlineColor(r, g, b, a) { 

       return (r + g + b < 100 && a === 255); 
      } 
      ; 

      function matchStartColor(pixelPos, startR, startG, startB) { 

       var r = outlineLayerData.data[pixelPos], 
         g = outlineLayerData.data[pixelPos + 1], 
         b = outlineLayerData.data[pixelPos + 2], 
         a = outlineLayerData.data[pixelPos + 3]; 

       // If current pixel of the outline image is black 
       if (matchOutlineColor(r, g, b, a)) { 
        return false; 
       } 

       r = colorLayerData.data[pixelPos]; 
       g = colorLayerData.data[pixelPos + 1]; 
       b = colorLayerData.data[pixelPos + 2]; 

       // If the current pixel matches the clicked color 
       if (r === startR && g === startG && b === startB) { 
        return true; 
       } 

       // If current pixel matches the new color 
       if (r === curColor.r && g === curColor.g && b === curColor.b) { 
        return false; 
       } 

       return true; 
      } 
      ; 

      function colorPixel(pixelPos, r, g, b, a) { 
       colorLayerData.data[pixelPos] = r; 
       colorLayerData.data[pixelPos + 1] = g; 
       colorLayerData.data[pixelPos + 2] = b; 
       colorLayerData.data[pixelPos + 3] = a !== undefined ? a : 255; 
      } 
      ; 

      function floodFill(startX, startY, startR, startG, startB) { 
       var newPos, 
         x, 
         y, 
         pixelPos, 
         reachLeft, 
         reachRight, 
         drawingBoundLeft = drawingAreaX, 
         drawingBoundTop = drawingAreaY, 
         drawingBoundRight = drawingAreaX + drawingAreaWidth - 1, 
         drawingBoundBottom = drawingAreaY + drawingAreaHeight - 1, 
         pixelStack = [[startX, startY]]; 

       while (pixelStack.length) { 

        newPos = pixelStack.pop(); 
        x = newPos[0]; 
        y = newPos[1]; 

        // Get current pixel position 
        pixelPos = (y * canvasWidth + x) * 4; 

        // Go up as long as the color matches and are inside the canvas 
        while (y >= drawingBoundTop && matchStartColor(pixelPos, startR, startG, startB)) { 
         y -= 1; 
         pixelPos -= canvasWidth * 4; 
        } 

        pixelPos += canvasWidth * 4; 
        y += 1; 
        reachLeft = false; 
        reachRight = false; 

        // Go down as long as the color matches and in inside the canvas 
        while (y <= drawingBoundBottom && matchStartColor(pixelPos, startR, startG, startB)) { 
         y += 1; 

         colorPixel(pixelPos, curColor.r, curColor.g, curColor.b); 

         if (x > drawingBoundLeft) { 
          if (matchStartColor(pixelPos - 4, startR, startG, startB)) { 
           if (!reachLeft) { 
            // Add pixel to stack 
            pixelStack.push([x - 1, y]); 
            reachLeft = true; 
           } 

          } else if (reachLeft) { 
           reachLeft = false; 
          } 
         } 

         if (x < drawingBoundRight) { 
          if (matchStartColor(pixelPos + 4, startR, startG, startB)) { 
           if (!reachRight) { 
            // Add pixel to stack 
            pixelStack.push([x + 1, y]); 
            reachRight = true; 
           } 
          } else if (reachRight) { 
           reachRight = false; 
          } 
         } 

         pixelPos += canvasWidth * 4; 
        } 
       } 
      } 
      ; 

      // Start painting with paint bucket tool starting from pixel specified by startX and startY 
      function paintAt(startX, startY) { 

       var pixelPos = (startY * canvasWidth + startX) * 4, 
         r = colorLayerData.data[pixelPos], 
         g = colorLayerData.data[pixelPos + 1], 
         b = colorLayerData.data[pixelPos + 2], 
         a = colorLayerData.data[pixelPos + 3]; 

       if (r === curColor.r && g === curColor.g && b === curColor.b) { 
        // Return because trying to fill with the same color 
        return; 
       } 

       if (matchOutlineColor(r, g, b, a)) { 
        // Return because clicked outline 
        return; 
       } 

       floodFill(startX, startY, r, g, b); 

       redraw(); 
      } 
      ; 

      // Add mouse event listeners to the canvas 
      function createMouseEvents() { 

       $('#canvas').mousedown(function (e) { 
        // Mouse down location 
        var mouseX = e.pageX - this.offsetLeft, 
          mouseY = e.pageY - this.offsetTop; 

        if ((mouseY > drawingAreaY && mouseY < drawingAreaY + drawingAreaHeight) && (mouseX <= drawingAreaX + drawingAreaWidth)) { 
         paintAt(mouseX, mouseY); 
        } 
       }); 
      } 
      ; 

      resourceLoaded = function() { 

       curLoadResNum += 1; 
       //if (curLoadResNum === totalLoadResources) { 
       createMouseEvents(); 
       redraw(); 
       //} 
      }; 

      function start() { 

       var canvas = document.createElement('canvas'); 
       canvas.setAttribute('width', canvasWidth); 
       canvas.setAttribute('height', canvasHeight); 
       canvas.setAttribute('id', 'canvas'); 
       document.getElementById('canvasDiv').appendChild(canvas); 

       if (typeof G_vmlCanvasManager !== "undefined") { 
        canvas = G_vmlCanvasManager.initElement(canvas); 
       } 
       context = canvas.getContext("2d"); 
       backgroundImage.onload = resourceLoaded(); 
       backgroundImage.src = "images/t1.png"; 

       outlineImage.onload = function() { 
        context.drawImage(outlineImage, drawingAreaX, drawingAreaY, drawingAreaWidth, drawingAreaHeight); 

        try { 
         outlineLayerData = context.getImageData(0, 0, canvasWidth, canvasHeight); 
        } catch (ex) { 
         window.alert("Application cannot be run locally. Please run on a server."); 
         return; 
        } 
        clearCanvas(); 
        colorLayerData = context.getImageData(0, 0, canvasWidth, canvasHeight); 
        resourceLoaded(); 
       }; 
       outlineImage.src = "images/d.png"; 
      } 
      ; 

      getColor = function() { 

      }; 

     </script> 
     <script type="text/javascript"> $(document).ready(function() { 
       start(); 
      });</script> 
     <script language="javascript"> 
      $('#zoomin').click(function() { 
       if ($("#canvas").width()==500){ 
       $("#canvas").width(750); 
       $("#canvas").height(750); 
       var ctx = canvas.getContext("2d"); 
       ctx.drawImage(backgroundImage, 0, 0, 749, 749); 
       ctx.drawImage(outlineImage, 0, 0, 749, 749); 
       redraw(); 
       } else if ($("#canvas").width()==750){ 

       $("#canvas").width(1000); 
       $("#canvas").height(1000); 
       var ctx = canvas.getContext("2d"); 
       ctx.drawImage(backgroundImage, 0, 0, 999, 999); 
       ctx.drawImage(outlineImage, 0, 0, 999, 999); 
       redraw(); 
       } 
      }); 
      $('#zoomout').click(function() { 
       if ($("#canvas").width() == 1000) { 

       $("#canvas").width(750); 
       $("#canvas").height(750); 
       var ctx = canvas.getContext("2d"); 
       ctx.drawImage(backgroundImage, 0, 0, 749, 749); 
       ctx.drawImage(outlineImage, 0, 0, 749, 749); 
       redraw(); 
       } else if ($("#canvas").width() == 750) { 

       $("#canvas").width(500); 
       $("#canvas").height(500); 
       var ctx = canvas.getContext("2d"); 
       ctx.drawImage(backgroundImage, 0, 0, 499, 499); 
       ctx.drawImage(outlineImage, 0, 0, 499, 499); 
       redraw(); 
       } 
      }); 
     </script> 
     <div class="colorpick"> 
      <div class="pick" style="background-color:rgb(150, 0, 0);" onclick="hello(this.style.backgroundColor);"></div> 
      <div class="pick" style="background-color:rgb(0, 0, 152);" onclick="hello(this.style.backgroundColor);"></div> 
      <div class="pick" style="background-color:rgb(0, 151, 0);" onclick="hello(this.style.backgroundColor);"></div> 
      <div class="pick" style="background-color:rgb(255, 0, 5);" onclick="hello(this.style.backgroundColor);"></div> 
      <div class="pick" style="background-color:rgb(255, 255, 0);" onclick="hello(this.style.backgroundColor);"></div> 
      <div class="pick" style="background-color:rgb(0, 255, 255);" onclick="hello(this.style.backgroundColor);"></div> 
      <div class="pick" style="background-color:rgb(255, 0, 255);" onclick="hello(this.style.backgroundColor);"></div> 
      <div class="pick" style="background-color:rgb(255, 150, 0);" onclick="hello(this.style.backgroundColor);"></div> 
      <div class="pick" style="background-color:rgb(255, 0, 150);" onclick="hello(this.style.backgroundColor);"></div> 
      <div class="pick" style="background-color:rgb(0, 255, 150);" onclick="hello(this.style.backgroundColor);"></div> 
      <div class="pick" style="background-color:rgb(150, 0, 255);" onclick="hello(this.style.backgroundColor);"></div> 
      <div class="pick" style="background-color:rgb(0, 150, 255);" onclick="hello(this.style.backgroundColor);"></div> 
     </div> 
     <script> 
      function hello(e) { 
       var rgb = e.replace(/^(rgb|rgba)\(/, '').replace(/\)$/, '').replace(/\s/g, '').split(','); 
       myColor.r = parseInt(rgb[0]); 
       myColor.g = parseInt(rgb[1]); 
       myColor.b = parseInt(rgb[2]); 
       curColor = myColor; 
       console.log(curColor); 
      } 
     </script> 
    </body> 
</html> 
+0

這兩個放大和縮小功能不起作用! – nisar

+0

您問題中的鏈接指向廣告。 : - ((請添加一個[最小,完整和可驗證的示例](http://stackoverflow.com/help/mcve)錯誤的代碼,幷包含更好的描述代碼是如何行爲不端,以及你會怎麼做喜歡它的工作「...不能正常工作」和「...搞砸」是不足夠的描述 – markE

回答

0

我無法找到你的代碼添加if (rc==0)if (uc==0)部分的含義。如果你刪除它們,你的代碼工作正常。

function undo() 
{ 
    if (undoarr.length<=0) 
     return; 

    var a=undoarr.pop(); 
    colorLayerData=a; 
    redoarr.push(a); 
    clearCanvas(); 
    context.putImageData(a, 0, 0); 
    context.drawImage(backgroundImage, 0, 0, canvasWidth, canvasHeight); 
    context.drawImage(outlineImage, 0, 0, drawingAreaWidth, drawingAreaHeight); 
    console.log(undoarr); 
} 

function redo() 
{ 
    if (redoarr.length<=0) 
     return; 
    var a=redoarr.pop(); 
    colorLayerData=a; 
    undoarr.push(a); 
    clearCanvas(); 
    context.putImageData(a, 0, 0); 
    context.drawImage(backgroundImage, 0, 0, canvasWidth, canvasHeight); 
    context.drawImage(outlineImage, 0, 0, drawingAreaWidth, drawingAreaHeight); 
    console.log(redoarr); 
} 
+0

如果我刪除這些,撤消和重做工作,當我第二次點擊複製粘貼代碼。將會看到我的意思 –

+0

我試過你的代碼,我相信它可以正常工作,如果你刪除了這些,另外,即使沒有測試過,如果你刪除了這些塊,也不會工作。你在其他地方有錯誤,你認爲撤銷和重做是導致錯誤的原因,試着縮小可疑代碼的範圍 –

+0

我試過了,錯誤只是在撤消和重做功能中,你可以自己檢查。多次撤銷和重做,他們不會是正確的。 –