2010-11-14
HTML5 Canvas and globalCompositeOperation
"+" is drawImage()
with globalCompositeOperation
set to
'source-over'
(the default).
⊙ is drawImage()
with globalCompositeOperation
set to
'source-atop'
.
[Loading canvas images...]
Your browser doesn't support HTML canvas. Get a modern browser such as Chrome, Firefox, Opera, or IE9. And then, only then, will you be able to see this demo. Sorry!
(Here's the JS source. I took this lizard photo at the Arizona-Senora Desert Museum.)
I haven't had much time to post lately, but I saw a cool little "scratch
off" app go by on Hacker News that I
thought could be improved upon by using something in HTML5 canvas known
as the
globalCompositeOperation
.
So I coded up a demo to show it off.
The globalCompositeOperation
affects how canvas drawing routines
interact with the data that's being drawn upon. There are many different
operations, but the default is "source-over"
, which the spec says:
"Display the source image wherever the source image is opaque. Display
the destination image elsewhere", which makes a certain kind of sense
for what you usually want to do.
Another common mode is "copy"
, which ignores transparency. As the
spec says for "copy": "Display the source image instead of the
destination image."
But, in fact, there are plenty of
modes.
And some of them are better-supported than others. For this demo, for
example, I wanted to use "source-out"
. Chrome and Safari seemed to be
OK with it, but Firefox just left the canvas blank—not too useful. So
instead I fell back on using "source-atop"
, which I also made to work.
(A completely different approach to this entire problem might be to
record the path you've drawn and use the clip()
method to mask out the
image, but I have doubts that would be faster.)
This is supposed to be demo code, not production code. Nevertheless, several people have asked me how to remove the thumbnails. The answer: delete every line in the JS and HTML that mentions "thumb".
Finally, after user requests, I've added a page that shows how to refactor this demo code to make it work with multiple canvases on the same page.
Howdy. Your getLocalCoords function can be a bit simpler. I'm looking at the initialization. I think, if <body onload="..."> is used, the loading can be simplified. I'll get back. Ciao - Mark Filipak.
function getLocalCoords(elem, event)
{
var ox = elem.offsetLeft, oy = elem.offsetTop;
while ((elem = elem.offsetParent) != null)
{
ox += elem.offsetLeft;
oy += elem.offsetTop;
}
return {'x' : event.pageX - ox, 'y' : event.pageY - oy};
}
Hi
I've been looking for an html5 solution to replace Flash for our promotional scratchcards (no gambling!). Looks like you've cracked the main part of the problem. Are you still doing any work on it? If not would you be willing to share your source files?
Best wishes
Pete
@Peter Jones Just "View Source" on the page. Everything's uncompressed in the index.html for ease of demonstration. Feel free to steal as you see fit.