擦除图像画布上的线条而不影响背景

时间:2014-10-12 04:29:08

标签: javascript html5 canvas struts2

我正在编写一个Web应用程序,我需要在其中注释图像。为此我使用html5的画布。感谢网络,我发现许多相似的代码。但是在开发代码之后我遇到了一个问题。

context.clearRect(pos.x,pos.y,pos.x,pos.y);

这是我用来擦除画布中的线条的代码。我期待代码做的是擦除鼠标指针所在的位置。但是,即使鼠标指针靠近该线,代码正在擦除该行。

编辑:我发现了擦除的问题。 clearRect()的语法是

context.clearRect(x,y,width,height);

当我分别给出pos.x和pos.y作为宽度和高度时,它正在消除一个广阔的区域。现在我将这两个值更改为5,5并且我能够擦除指针所在的位置。

此外,我需要在完全注释后保存带注释的图像。我将图像保持为画布的背景。我在画布上绘制线条。点击查看图片时,我只能看到这些线条。请检查我的代码告诉我如何进行这两项操作。这是我的代码。

<%@ taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
    <title>Success: Upload User Image</title>   
    <style>
        canvas { background:url("images/<s:property value="userImageFileName"/>") ;
                 background-size: 100% 100%;
                 background-repeat: no-repeat;}
    </style>    
</head>

<body>

    <h2>utStruts2 File Upload Example</h2>
    <img id="result" src="images/<s:property value="userImageFileName"/>" width="565" height="584" class="annotatable"/>
    <canvas id="myCanvas" width="565" height="584" style="border:1px solid #d3d3d3;" >
        Please use a modern browser like Firefox, Chrome, Safari
    </canvas>
    <input type="button" value="draw" onClick="draw()">
    <input type="button" value="eraser" onClick="erase()">

    <canvas id="canvas2" width="565" height="584" hidden="true"></canvas>
    <script>
          var canvas = document.getElementById('myCanvas');           
          var coord = document.getElementById('coord');
          var context = canvas.getContext('2d');

          var canvas2 = document.getElementById('canvas2');
          var cantext2 = canvas2.getContext('2d');

        function draw(){
            mode="draw";    
            operate(mode);
        }

        function erase(){
            mode="erase";
            operate(mode);
        }

        function operate(mode)
        {
              var mousedown = false;
              context.strokeStyle = '#0000FF';
              context.lineWidth = 5;

              canvas.onmousedown = function(e) {
                  var pos = fixPosition(e, canvas);
                  mousedown = true;
                  context.beginPath();
                  context.moveTo(pos.x, pos.y);                       
                  //return false;
              };

              canvas.onmousemove = function(e) {
                  var pos = fixPosition(e, canvas);                 
                  if (mousedown) {
                      if(mode=="draw"){
                          context.lineTo(pos.x, pos.y);
                          context.stroke();
                      }
                      if(mode=="erase"){
                          context.clearRect(pos.x,pos.y,pos.x,pos.y);
                          context2.drawImage(canvas, 0, 0);
                          context.clearRect(0, 0, 565, 584);
                          context.drawImage("images/<s:property value="userImageFileName"/>", 0, 0);
                          context.drawImage(canvas2, 0, 0); 
                      }
                  }
              };

              canvas.onmouseup = function(e) {
                  mousedown = false;
              };

              function fixPosition(e, gCanvasElement) {
                    var x;
                    var y;

                    x = e.pageX;
                    y = e.pageY;

                    x -= gCanvasElement.offsetLeft;
                    y -= gCanvasElement.offsetTop;

                    return {x:x, y:y};
                }
        }  
    </script>
</body>
</html>

1 个答案:

答案 0 :(得分:1)

clearRect接受以下参数:(xpos, ypos, width, height)

问题(S):
canvas.onmousemove功能(模式“擦除”)中,您有:context.clearRect(pos.x,pos.y,pos.x,pos.y);

嗯,这不可能是正确的。

然后,根据鼠标位置删除区域大小后,将剩余的context复制到缓冲区 - context2context2.drawImage(canvas, 0, 0);

之后清除整个绘图画布:context.clearRect(0, 0, 565, 584);

将(S)
一旦修复了上述内容(以便鼠标指针作为橡皮擦),您需要添加一个函数来组合/导出/存储带注释的图像:

使用缓冲区context2首先绘制(原始)图像,然后在其上绘制注释图像(使用drawImage())(想想图层)。

最后,您使用.toDataURL()方法从context2缓冲区输出组合图像(并使用AJAX等发送结果(base64编码的数据网址,这是一个简单的字符串))。

另外:

  • 您可能想知道您不需要标记缓冲区,只需在内存中创建它: var canvas2=document.createElement('canvas');
  • 你的var mode正在泄漏到全局(我只会发布operate('draw')等并保存腰部操作,以获得更好的用户体验响应能力(“减少工作量”)。