Javascript Canvas clear/ redraw

后端 未结 2 1262
天命终不由人
天命终不由人 2020-12-19 17:02

I\'ve tried googling the answer to this but i\'m just going around in circles.... If I clear the rect (using clearRect) then the image doesn\'t redraw after. However, if I d

相关标签:
2条回答
  • 2020-12-19 17:13

    Canvas workflow goes like this:

    1. Draw some things on the canvas.
    2. Calculate changes to the position of those things.
    3. Clear the canvas.
    4. Redraw all the things in their new positions.

    Canvas does not "remember" where it drew your things so you cannot directly order your things to move.

    But you can save the definition of your things in javascript object:

    var myCircle={
        centerX:50,
        centerY:50,
        radius:25,
        fill:'blue'
    }
    

    Then you can "move" your things using the javascript objects:

    myCircle.centerX += 5;
    

    And then redraw the things at their new positions. Putting the redraw code in a function makes redrawing easier:

    function redraw(){
    
        // clear the canvas
        ctx.clearRect(0,0,canvas.width,canvas.height);
    
        // redraw one or more things based on their javascript objects
        ctx.beginPath();
        ctx.arc( myCircle.centerX, myCircle.centerY, myCircle.radius, 0, Math.PI*2 );
        ctx.closePath();
        ctx.fillStyle=myCircle.fill;
        ctx.fill();
    }
    

    Putting it all together:

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    
    var myCircle={
      centerX:50,
      centerY:50,
      radius:25,
      fill:'blue'
    }
    
    redraw();
    
    document.getElementById('move').addEventListener('click',function(){
      myCircle.centerX+=5;
      redraw();
    });
    
    function redraw(){
      ctx.clearRect(0,0,canvas.width,canvas.height);
      ctx.beginPath();
      ctx.arc( myCircle.centerX, myCircle.centerY, myCircle.radius, 0, Math.PI*2 );
      ctx.closePath();
      ctx.fillStyle=myCircle.fill;
      ctx.fill();
    }
    body{ background-color: ivory; }
    #canvas{border:1px solid red; margin:0 auto; }
    <button id=move>Move</button>
    <br>
    <canvas id="canvas" width=300 height=300></canvas>

    0 讨论(0)
  • 2020-12-19 17:19

    You need to add a beginPath() in there. rect() will accumulate rectangles to the path, clearRect() won't clear those. Also reset comp. mode and alpha as they are sticky.

    You could avoid beginPath() if you use fillRect() instead of rect() + fill() (added example below) as fillRect() does not add to the path.

    function fill(imgSection,currentcolor){
    
        // these should really be initialized outside the loop    
        canvas = document.getElementById(imgSection);
        ctx = canvas.getContext("2d");
    
        // clear canvas
        ctx.clearRect(0, 0, canvas.width, canvas.height);
    
        // clear path
        ctx.beginPath();
    
        // use default comp. mode
        ctx.globalCompositeOperation = "source-over";
    
        // reset alpha
        ctx.globalAlpha = 1;
    
        ctx.drawImage(imgToBeFilled, 0, 0);
        ctx.globalCompositeOperation = "source-atop";
    
        if (isItColorOrPattern === "color"){
    
            // rect() accumulates on path
            ctx.rect(0, 0, canvas.width, canvas.height);
            ctx.fillStyle = getColor(currentcolor);
            ctx.fill();
    
           // instead of rect() + fill() you could have used:
           // fillRect() does not accumulate on path
           // fillRect(0, 0, canvas.width, canvas.height);
        }
        else {
            var pattern = ctx.createPattern(imgFill, 'repeat');
            ctx.rect(0, 0, canvas.width, canvas.height);
            ctx.fillStyle = pattern;
            ctx.fill();
        }
    
        ctx.globalAlpha = .1;
        ctx.drawImage(imgToBeFilled, 0, 0);
        ctx.drawImage(imgToBeFilled, 0, 0);
        ctx.drawImage(imgToBeFilled, 0, 0);
    
        oldcolor = currentcolor;
        oldxImgToBeFilled = xImgToBeFilled;    
    }
    
    0 讨论(0)
提交回复
热议问题