How can I test whether a canvas area has finished rendering?
April 27, 2010 3:43 AM   Subscribe

My JavaScript rough edges are showing. How can I test whether my html5 canvas area has finished rendering so I can use it for other purposes?

My sad little web app right now does this:

1) Users can choose a color via a picker
2) When they click the button indicating they picker is displaying the right color, an object in the photo they're looking at changes to that color.

I'm using this as an opportunity to learn a bit about the "canvas" area in html5, in the past I've done similar things server-side in PHP but really don't want that to be the case here.

To preserve the shading, texture and highlight details of the object, I need to apply a couple of filters to their chosen color (which is now a rectangle on the canvas)--I'm using the pixtastic library.

The workflow is:

1) Drawing a rectangle in a canvas area and shading it the color they chose when the user clicks the "go" button.
2) The canvas area is then targeted by pixtastic, and the pixtastic blend filter blends the canvas area with some transparent png graphics which contain the shading/texture info.

The filtered canvas area lives behind another png with a cutout in it to allow the textured color to show through.

This works pretty well, surprisingly, especially for this JavaScript hack's work--except that occasionally the canvas hasn't finished drawing before the function calls pixtastic, and the filters are not applied.

How can I determine that my canvas area has finished drawing before applying the pixtastic filters?
posted by maxwelton to Computers & Internet (9 answers total) 1 user marked this as a favorite
 
Could you use getImageData to grab the colour of a particular pixel that gets set last?
posted by Artw at 10:33 AM on April 27, 2010


I'd have to look at your code. My gut instinct says there is somewhere where you want some sequential execution but you have code hanging out in a callback so things aren't happening in the order you think they should.

There are so many ways to write Javascript that I have no idea though...
posted by dubitable at 12:42 PM on April 27, 2010


Response by poster: My code is crude at the moment:
function paintColor(specColor,amt) {
	var amt = (amt == null) ? 1 : amt;
	var img = document.getElementById("colorcanvas");
	if (img && img.getContext) {
		var contxt = img.getContext('2d');
		if (contxt) {
			contxt.fillStyle = specColor;
			contxt.fillRect(0, 0, 600, 400);
		}
		// this is where I need to test the above is done...
		paintTexture(img,amt);
	}
}
Art, I guess you're suggesting concocting some sort of listener that looks to see if pixel 599,399 is colored the same as SpecColor, and if so, then call the paintTexture function? That makes sense, I'll see if I can figure that out.
posted by maxwelton at 2:45 PM on April 27, 2010


Response by poster: Art, thanks, I think that worked. I modified my code as below (and this still may be quite inelegant, be happy to learn how to do this better, perhaps combining the functions into one?):
function paintColor(specColor,amt) {
	var amt = (amt == null) ? 1 : amt;
	var img = document.getElementById("colorcanvas");
	if (img && img.getContext) {
		var contxt = img.getContext('2d');
		if (contxt) {
			contxt.fillStyle = specColor;
			contxt.fillRect(0, 0, 600, 400);
		}
		getCanvasColor("colorcanvas",599,399)
	}
}

function getCanvasColor(canvasID,xpixel,ypixel) {
	var ele = document.getElementById(canvasID);
	if (ele && ele.getContext) {
		var contxt = ele.getContext('2d');
		if (contxt) {
			data = contxt.getImageData(xpixel, ypixel, 1, 1).data;
			color = "#" + RGBtoHex(data[0],data[1],data[2]);
			paintTexture(ele,1);
			return true;
		} else {
			getCanvasColor(ele,xpixel,ypixel);
		}
	} else {
		return false;
	}
}

posted by maxwelton at 3:28 PM on April 27, 2010


Neat. I've no idea if that's the recommended solution, BTW, just the first thing that came to mind.
posted by Artw at 3:30 PM on April 27, 2010


Response by poster: Damn, that's not right. Sorry.
posted by maxwelton at 3:30 PM on April 27, 2010


Are you sure rendering time is the issue? could it be one of your conditional statements returning false occasionally for some reason?
posted by Artw at 3:37 PM on April 27, 2010


Response by poster: OK, I fixed it, but you were right, my code was R-O-N-G wrong. Fixed it now. I'll clean it up a bit and post if for posterity later, if anyone's interested.
posted by maxwelton at 3:49 PM on April 27, 2010


Response by poster: That's an interesting point, I guess there could potentially be an exception within the pixtastic code or similar.I guess the solution there would be to do another check of the pixel color to make sure it's different after the filter is applied.

(My goal is to have a silly little program which totally pegs the CPU before crashing the browser--I'm probably well on my way.)
posted by maxwelton at 3:53 PM on April 27, 2010


« Older Et in Arcadia me go   |   What's this song? Newer »
This thread is closed to new comments.