Question

I have a canvas loaded with an image.
Now, I want to mark lines on some part of the image.
So, I wrote some code which draws a line on mouse drag.

function drawLine(x, y) {
    ctx.beginPath();
    ctx.moveTo(startX, startY);
    ctx.lineTo(x, y);
    ctx.closePath();
    ctx.stroke();
    ctx.restore();
}

canvas.onmousedown = function (e)  {
    ctx.save();
    e.preventDefault();
    e.stopPropagation();
    startX = parseInt(e.clientX - offsetX);
    startY = parseInt(e.clientY - offsetY);
    isDown = true;
}
canvas.onmousemove = function (e)  {
    if (!isDown) {
        return;
    }
    e.preventDefault();
    e.stopPropagation();
    mouseX = parseInt(e.clientX - offsetX);
    mouseY = parseInt(e.clientY - offsetY);
    drawLine(mouseX, mouseY);
}
canvas.onmouseup = function (e)  {
    if (!isDown) {
        return;
    }
    e.preventDefault();
    e.stopPropagation();
    isDown = false;
}

The issue now is that, the drag creates a series of lines instead of one.
I have tried to save the context before drawing and restore it after drawing, but didn't help.

Note that, I cannot clear the canvas using clearRect(), as my image data will be lost. Here, I have used a dummy image.

I have created a fiddle.

Any help would be appreciated.

Regards,
Rohith

Was it helpful?

Solution

One way of doing it is to save all your drag-lines in an array of drag-lines.

That way you can clear the canvas and redraw the image and redraw all the accumulated lines.

Example code and a Demo: http://jsfiddle.net/m1erickson/bH38a/

The green lines are my (totally non-medical !) additions.

BTW, this example reduces the opacity of the background image so the lines are more visible (a handy technique).

enter image description here

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    #canvas{
        border:1px solid red;
    }
</style>
<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var canvasOffset=$("#canvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;

    var startX,startY,mouseX,mouseY;
    var isDown=false;

    var lines=[];

    var imageOpacity=0.33;

    var img=new Image();
    img.crossOrigin="anonymous";
    img.onload=start;
    img.src="https://dl.dropboxusercontent.com/u/139992952/multple/heart.jpg";
    function start(){

        canvas.width=canvas.width=img.width;
        canvas.height=img.height;
        ctx.strokeStyle="green";
        ctx.lineWidth=3;

        $("#canvas").mousedown(function(e){handleMouseDown(e);});
        $("#canvas").mousemove(function(e){handleMouseMove(e);});
        $("#canvas").mouseup(function(e){handleMouseUp(e);});
        $("#canvas").mouseout(function(e){handleMouseUp(e);});

        // redraw the image
        drawTheImage(img,imageOpacity);

    }

    function drawLines(toX,toY){
        // clear the canvas
        ctx.clearRect(0,0,canvas.width,canvas.height);

        // redraw the image
        drawTheImage(img,imageOpacity);

        // redraw all previous lines
        for(var i=0;i<lines.length;i++){
            drawLine(lines[i]);
        }

        // draw the current line
        drawLine({x1:startX,y1:startY,x2:mouseX,y2:mouseY});
    }

    function drawTheImage(img,opacity){
        ctx.globalAlpha=opacity;
        ctx.drawImage(img,0,0);
        ctx.globalAlpha=1.00;
    }

    function drawLine(line){
        ctx.beginPath();
        ctx.moveTo(line.x1, line.y1);
        ctx.lineTo(line.x2, line.y2);
        ctx.stroke();
    }




    function handleMouseDown(e){
      e.stopPropagation();
      e.preventDefault();
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // Put your mousedown stuff here
      startX=mouseX;
      startY=mouseY;
      isDown=true;
    }

    function handleMouseUp(e){
      e.stopPropagation();
      e.preventDefault();

      // Put your mouseup stuff here
      isDown=false;
      lines.push({x1:startX,y1:startY,x2:mouseX,y2:mouseY});
    }

    function handleMouseMove(e){
      if(!isDown){return;}
      e.stopPropagation();
      e.preventDefault();
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // Put your mousemove stuff here
      drawLines(mouseX,mouseY);

    }


    $("#save").click(function(){
        var html="<p>Right-click on image below and Save-Picture-As</p>";
        html+="<img src='"+canvas.toDataURL()+"' alt='from canvas'/>";
        var tab=window.open();
        tab.document.write(html);
    });


}); // end $(function(){});
</script>
</head>
<body>
    <h4>Drag-draw lines.</h4>
    <button id="save">Export Image</button><br>
    <canvas id="canvas"></canvas>
</body>
</html>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top