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 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.
/
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);
}
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 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/
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);
}
Share
Improve this question
edited Jun 9, 2015 at 19:33
tree
asked Jun 9, 2015 at 17:18
treetree
7403 gold badges12 silver badges23 bronze badges
2
|
2 Answers
Reset to default 6You 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;
}
Canvas workflow goes like this:
- Draw some things on the canvas.
- Calculate changes to the position of those things.
- Clear the canvas.
- 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>
ctx.globalCompositeOperation = "source-over";
andctx.globalAlpha = 1;
of your linked fiddle and it should start working. – Niddro Commented Jun 10, 2015 at 8:31