Drawing to canvas like in paint

前端 未结 3 1576
小蘑菇
小蘑菇 2021-01-27 02:41

I have three arrys:

 clickX = [],
    clickY = [],
    clickDrag = [];

this is what happens when you click down:

$(\'#canvasCur         


        
相关标签:
3条回答
  • 2021-01-27 03:13

    Do not store painting to array
    It slows down drawing critically. Just draw the latest line without clearing canvas. That way lineWeight changes does not affect to before drawings. So remove ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); and for loop. You also might want to change context styles (lineWidth etc.) only when changes occur, not every time you run redraw() function.

    Undo support
    Making different canvas for every mouse down session and drawing them together you can easily make undo feature. By pressing undo it simply splices latest canvas out of canvases array. Google to learn more about drawing to temporary canvas.

    0 讨论(0)
  • 2021-01-27 03:20

    EDIT: Sorry, fixed some typos Edit 2: And again. It's a bit difficult to test.

    There's no reason to redraw each of the points each time. You could modify your listener to do this:

    var prevMouseX=null,prevMouseY=null;
    $('#canvasCursor').mousedown(function (e) {
        paint = true;
    
        console.log('down');
        //get current mouse coords
        mouseX = e.pageX - this.offsetLeft;
        mouseY = e.pageY - this.offsetTop;
    
        if (prevMouseX==null) {
            //store these coordinates for next time if they haven't been defined yet
            prevMouseX = mouseX;
            prevMouseY = mouseY;
        }
    });
    
    $('#canvasCursor').mousemove(function (e) {
        //get current mouse coords
        mouseX = e.pageX - this.offsetLeft;
        mouseY = e.pageY - this.offsetTop;
    
        if (prevMouseX==null) {
            //store these coordinates for next time if they haven't been defined yet
            prevMouseX = mouseX;
            prevMouseY = mouseY;
        }
    
        if (paint) {drawline(mouseX,mouseY,prevMouseX,prevMouseY);}
    
        //store these coordinates for next time
        prevMouseX = mouseX;
        prevMouseY = mouseY;
    });
    

    Where the function drawLine is defined as:

    function drawline(x1,y1,x2,y2) {
    ctx.strokeStyle = "green";
        ctx.lineJoin = "round";
        ctx.lineWidth = brushSize*2;
    
        ctx.beginPath();
        ctx.moveTo(x1,y1);
        ctx.lineTo(x2,y2);
        ctx.closePath();
        ctx.stroke();
    }
    
    0 讨论(0)
  • 2021-01-27 03:29

    Here’s how to use canvas to draw like Paint

    If you want an undo feature, your best option is to record all line segments drawn by the user.

    This is done with a point array that contains all points (polylines) drawn by the user.

    To track the brush size and brush color, you need to include this info in your array also.

    So each element of the the array will have this info about each line segment:

    • x: the ending x coordinate of this line segment
    • y: the ending y coordinate
    • size: the brush size (lineWidth)
    • color: the brush color (strokeStyle)
    • mode: “begin” indicates the beginning of a new line, “end” indicates the end of this line.

    How does it work?

    When the user is drag-drawing a line segment, each mousemove event is extending the current segment with context.lineTo and context.stroke.

    When the user selects a new BrushSize or BrushColor, context.beginPath starts context.beginPath.

    When the user holds down the Undo button, the last point in the last line segment is popped off the point array. Then all the surviving line segments are redrawn. The undo button fires every 1/10th of a second when held down.

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

    <!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>
    <!--[if lt IE 9]><script type="text/javascript" src="../excanvas.js"></script><![endif]-->
    
    <style>
        body{ background-color: ivory; }
        canvas{border:1px solid red;}
    </style>
    
    <script>
    $(function(){
    
        var canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");
        var lastX;
        var lastY;
        var mouseX;
        var mouseY;
        var canvasOffset=$("#canvas").offset();
        var offsetX=canvasOffset.left;
        var offsetY=canvasOffset.top;
        var isMouseDown=false;
        var brushSize=20;
        var brushColor="#ff0000";
        var points=[];
    
    
        function handleMouseDown(e){
          mouseX=parseInt(e.clientX-offsetX);
          mouseY=parseInt(e.clientY-offsetY);
    
          // Put your mousedown stuff here
          ctx.beginPath();
          if(ctx.lineWidth!=brushSize){ctx.lineWidth=brushSize;}
          if(ctx.strokeStyle!=brushColor){ctx.strokeStyle=brushColor;}
          ctx.moveTo(mouseX,mouseY);
          points.push({x:mouseX,y:mouseY,size:brushSize,color:brushColor,mode:"begin"});
          lastX=mouseX;
          lastY=mouseY;
          isMouseDown=true;
        }
    
        function handleMouseUp(e){
          mouseX=parseInt(e.clientX-offsetX);
          mouseY=parseInt(e.clientY-offsetY);
    
          // Put your mouseup stuff here
          isMouseDown=false;
          points.push({x:mouseX,y:mouseY,size:brushSize,color:brushColor,mode:"end"});
        }
    
    
        function handleMouseMove(e){
          mouseX=parseInt(e.clientX-offsetX);
          mouseY=parseInt(e.clientY-offsetY);
    
          // Put your mousemove stuff here
          if(isMouseDown){
              ctx.lineTo(mouseX,mouseY);
              ctx.stroke();     
              lastX=mouseX;
              lastY=mouseY;
              // command pattern stuff
              points.push({x:mouseX,y:mouseY,size:brushSize,color:brushColor,mode:"draw"});
          }
        }
    
    
        function redrawAll(){
    
            if(points.length==0){return;}
    
            ctx.clearRect(0,0,canvas.width,canvas.height);
    
            for(var i=0;i<points.length;i++){
    
              var pt=points[i];
    
              var begin=false;
    
              if(ctx.lineWidth!=pt.size){
                  ctx.lineWidth=pt.size;
                  begin=true;
              }
              if(ctx.strokeStyle!=pt.color){
                  ctx.strokeStyle=pt.color;
                  begin=true;
              }
              if(pt.mode=="begin" || begin){
                  ctx.beginPath();
                  ctx.moveTo(pt.x,pt.y);
              }
              ctx.lineTo(pt.x,pt.y);
              if(pt.mode=="end" || (i==points.length-1)){
                  ctx.stroke();
              }
            }
            ctx.stroke();
        }
    
        function undoLast(){
            points.pop();
            redrawAll();
        }
    
        ctx.lineJoin = "round";
        ctx.fillStyle=brushColor;
        ctx.lineWidth=brushSize;
    
        $("#brush5").click(function(){ brushSize=5; });
        $("#brush10").click(function(){ brushSize=10; });
        // Important!  Brush colors must be defined in 6-digit hex format only
        $("#brushRed").click(function(){ brushColor="#ff0000"; });
        $("#brushBlue").click(function(){ brushColor="#0000ff"; });
    
        $("#canvas").mousedown(function(e){handleMouseDown(e);});
        $("#canvas").mousemove(function(e){handleMouseMove(e);});
        $("#canvas").mouseup(function(e){handleMouseUp(e);});
    
        // hold down the undo button to erase the last line segment
        var interval;
        $("#undo").mousedown(function() {
          interval = setInterval(undoLast, 100);
        }).mouseup(function() {
          clearInterval(interval);
        });
    
    
    }); // end $(function(){});
    </script>
    
    </head>
    
    <body>
        <p>Drag to draw. Use buttons to change lineWidth/color</p>
        <canvas id="canvas" width=300 height=300></canvas><br>
        <button id="undo">Hold this button down to Undo</button><br><br>
        <button id="brush5">5px Brush</button>
        <button id="brush10">10px Brush</button>
        <button id="brushRed">Red Brush</button>
        <button id="brushBlue">Blue Brush</button>
    </body>
    </html>
    
    0 讨论(0)
提交回复
热议问题