简体   繁体   English

Javascript Canvas清除/重绘

[英]Javascript Canvas clear/ redraw

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. 我已经尝试使用谷歌搜索这个答案,但我只是绕圈子......如果我清除了rect(使用clearRect),那么图像不会重绘。 However, if I don't clear the images just stack. 但是,如果我不清除图像只是堆栈。 What I want it to clear the current image and then draw with new one. 我希望它清除当前图像然后用新图像绘制。 What am I missing? 我错过了什么? Does it have something to do with the image Load ? 它与图像负载有关吗? Sorry if this is a question repeat, I couldn't find the exact answer to this- and I tried what others suggested but results were poor. 对不起,如果这是一个重复的问题,我找不到这个的确切答案 - 我尝试了别人的建议,但结果很差。

http://jsfiddle.net/bxeuhh4h/ http://jsfiddle.net/bxeuhh4h/

function clear() {
    var canvasTemp = document.getElementById(imgSection);
    var ctxTemp = canvasTemp.getContext("2d");
    ctxTemp.clearRect(0, 0, 500, 500);

}

function fillColorOrPattern(imgSection,currentcolor){
if ((oldcolor !== currentcolor) || (oldxImgToBeFilled !== xImgToBeFilled)){
    clear();
}
imgFill.onload = function () {
imgToBeFilled.onload = function () {
        if ((oldcolor !== currentcolor) || (oldxImgToBeFilled !== xImgToBeFilled)){

        fill(imgSection,currentcolor)

        }
  };
imgToBeFilled.src = xImgToBeFilled;
}
imgFill.src = xImgFill;
}


function fill(imgSection,currentcolor){
canvas = document.getElementById(imgSection);
ctx = canvas.getContext("2d");
ctx.drawImage(imgToBeFilled, 0, 0);
ctx.globalCompositeOperation = "source-atop";
console.log(isItColorOrPattern);
        if (isItColorOrPattern ==   "color"){
            ctx.rect(0, 0, canvas.width, canvas.height);
            console.log("currentcolor: " + currentcolor);
            ctx.fillStyle = getColor(currentcolor);
            console.log(getColor(currentcolor));
            ctx.fill();
        }else{
            var pattern = ctx.createPattern(imgFill, 'repeat');
            console.log("canvas.width: " + canvas.width);
            console.log("xImgFill: " + xImgFill);
            console.log(canvas.getContext);
            ctx.rect(0, 0, canvas.width, canvas.height);
            ctx.fillStyle = pattern;
            ctx.fill();
        }

        ctx.globalAlpha = .10;
        ctx.drawImage(imgToBeFilled, 0, 0);
        ctx.drawImage(imgToBeFilled, 0, 0);
        ctx.drawImage(imgToBeFilled, 0, 0);


    oldcolor = currentcolor;
    oldxImgToBeFilled = xImgToBeFilled;

}

$(window).load(function(){
imgToBeFilled = new Image();
imgFill = new Image();  
fillColorOrPattern(imgSection,currentcolor);
}

Canvas workflow goes like this: Canvas工作流程如下:

  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: 但是你可以在javascript对象中保存你的东西的定义:

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

Then you can "move" your things using the javascript objects: 然后你可以使用javascript对象“移动”你的东西:

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> 

You need to add a beginPath() in there. 你需要在那里添加一个beginPath() rect() will accumulate rectangles to the path, clearRect() won't clear those. rect()会将矩形累积到路径中, clearRect()不会清除那些。 Also reset comp. 还重置comp。 mode and alpha as they are sticky. 模式和alpha,因为它们很粘。

You could avoid beginPath() if you use fillRect() instead of rect() + fill() (added example below) as fillRect() does not add to the path. 如果使用fillRect()而不是rect() + fill() (下面添加示例beginPath()则可以避免使用beginPath() ,因为fillRect()不会添加到路径中。

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;    
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM