Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove a previous stroke (make a temporary line) - Javascript / HTML5

I am trying to make a simple paint application and I want the lines to sort of preview the line after you specify a lines start point. The corresponding Javascript is like this:

var Edges = new Array();
var Vertecies = new Array();
var Mouse = {x:0, y:0}


function findPos(obj) {
    var curleft = 0, curtop = 0;
    if (obj.offsetParent) {
        do {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
        } while (obj = obj.offsetParent);
        return { x: curleft, y: curtop };
    }
    return undefined;
}

function addEdge() {
    var c=document.getElementById("myCanvas");
    var ctx=c.getContext("2d");

    var i=0;
    var Start = { x:0, y:0}
    var End = { x:0, y:0}
    var Line = (Start, End);
    var temp = new Array();
    $("#myCanvas").mousemove(function(e){
        console.log("mouse is movin!");
        if(i==1)
        {
          var pos = findPos(this);
          console.log("I = 1 AHHHH")
          ctx.moveTo(Start.x, Start.y);
          ctx.lineTo(e.clientX-pos.x, e.clientY-pos.y);

          ctx.stroke();

        }
        else{

        }
    })


    $("#myCanvas").click(function(event){
        var pos = findPos(this);
        var x = event.pageX - pos.x;
        var y = event.pageY - pos.y;
        if (i==0)
        {
            Start = {x:x,y:y}
            i++;
        }
        else if(i==1) {
            End = {x:x,y:y}
            ctx.moveTo(Start.x , Start.y);
            ctx.lineTo(End.x , End.y);
            ctx.stroke();
            Line = (Start, End);
            Edges.push(Line);
            i++;
        }

        while(i==2) {
            Start = {x:0, y:0};
            End = {x:0, y:0};
            i=0;
        }
    });
};  

Apart from that, I have a related canvas called myCanvas.

Basically what it does is it makes lines going from that point to my cursor until I click again, then it will stop and now I'm left with just this mound of lines.

How can I get a "temporary" line after I've clicked once going from that clicked location to my cursor and then place a permanent line where my second click is.

like image 522
Funkyguy Avatar asked May 08 '13 01:05

Funkyguy


1 Answers

You were very close with your code. Here’s some adjustments that fill in the gaps.

[Edited to show a single canvas solution]

To avoid drawing “a mound of lines” when the user drags their new line, you must clear the canvas during each mousemove and draw just their latest dragging line.

Clearing the canvas will also clear any lines previously drawn by the user, so you must redraw the previous lines with every drag. To do that, you must store enough info about each line to redraw it.

For each line you will need the starting and ending points (x1/y1 and x2/y2). You can put these starting and ending points in an object and store the line-objects in an array:

// an array to store previous lines
var storedLines=[];

// to store a new line
storedLines.push( { x1:10, y1:20, x2:50, y2:35 } );

This function redraws all the previously drawn lines

    function redrawStoredLines(){

        ctx.clearRect(0,0,canvas.width,canvas.height);

        if(storedLines.length==0){ return; }

        // redraw each stored line
        for(var i=0;i<storedLines.length;i++){
            ctx.beginPath();
            ctx.moveTo(storedLines[i].x1,storedLines[i].y1);
            ctx.lineTo(storedLines[i].x2,storedLines[i].y2);
            ctx.stroke();
        }
    }

Now displaying the user’s dragging line is much easier like this:

function handleMouseMove(e){

  if(!isDown){ return; }

  redrawStoredLines();

  var mouseX=parseInt(e.clientX-offsetX);
  var mouseY=parseInt(e.clientY-offsetY);

  // draw the current line
  ctx.beginPath();
  ctx.moveTo(startX,startY);
  ctx.lineTo(mouseX,mouseY);
  ctx.stroke()

}

Here is code and a Fiddle: http://jsfiddle.net/m1erickson/NnZ7a/

<!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; padding:10px; }
    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 storedLines=[];
    var startX=0;
    var startY=0;
    var isDown;

    ctx.strokeStyle="orange";
    ctx.lineWidth=3;

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

    $("#clear").click(function(){ storedLines.length=0; redrawStoredLines(); });

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

      isDown=true;
      startX=mouseX;
      startY=mouseY;

    }

    function handleMouseMove(e){

      if(!isDown){ return; }

      redrawStoredLines();

      var mouseX=parseInt(e.clientX-offsetX);
      var mouseY=parseInt(e.clientY-offsetY);

      // draw the current line
      ctx.beginPath();
      ctx.moveTo(startX,startY);
      ctx.lineTo(mouseX,mouseY);
      ctx.stroke()

    }


    function handleMouseUp(e){

      isDown=false;

      var mouseX=parseInt(e.clientX-offsetX);
      var mouseY=parseInt(e.clientY-offsetY);

      storedLines.push({x1:startX, y1:startY, x2:mouseX, y2:mouseY});

      redrawStoredLines();

    }


    function redrawStoredLines(){

        ctx.clearRect(0,0,canvas.width,canvas.height);

        if(storedLines.length==0){ return; }

        // redraw each stored line
        for(var i=0;i<storedLines.length;i++){
            ctx.beginPath();
            ctx.moveTo(storedLines[i].x1,storedLines[i].y1);
            ctx.lineTo(storedLines[i].x2,storedLines[i].y2);
            ctx.stroke();
        }
    }

}); // end $(function(){});
</script>

</head>

<body>
    <p>Drag to draw lines</p>
    <canvas id="canvas" width=300 height=300></canvas><br/>
    <button id="clear">Clear Canvas</button>
</body>
</html>
like image 109
markE Avatar answered Oct 22 '22 13:10

markE