05 December 2010
Canvas Composite Operations Tutorial & Demo
Composite operations let you change how new content is drawn on an HTML5 <canvas>
element. Normally new things appears over whatever has already been drawn.
By changing the global composite operation, you can draw new shapes behind existing ones,
perform boolean operations, and do some other neat things too.
var context = document.getElementById('myCanvas').getContext('2d'); context.globalCompositeOperation = 'source-over';
The two main players in a compositing operation are the destination and the source. The destination is what is already on the canvas, and the source is what is getting drawn onto the canvas.
The examples below conveniently show you the destination and source separately,
and then the source composited onto the destination.
Click on different options to the change how the circles are composited with the text (my favorites are xor
and source-atop
).
Destination:
Source:
Composite:
composite operation: source-over | destination-over | source-in | destination-in | source-out | destination-out | source-atop | destination-atop | lighter | darker | xor | copy | reddit
For more explanation of these types as well as the clip()
feature, check out the
mozilla dev network compositing tutorial
and their live example,
but… if you like psuedo-mathematical syntax, then read on to my explanations below. Each operation
can be thought of as starting with a transparent canvas and then combining the destination and source
as described (think boolean logic and having things to the right appear above things to the left).
Commposite operation short-hand:
source-over | destination + source |
---|---|
destination-over | source + destination |
source-in | destination & source |
destination-in | source & destination |
source-out | source - destination |
destination-out | destination - source |
source-atop | destination + (source & destination) |
destination-atop | source + (destination & source) |
lighter | destination + source + lighter(source & destination) |
darker | destination + source + darker(source & destination) |
xor | source ^ destination |
copy | source |
Bonus - Compounding Composites:
The above example cleared the canvas and drew everything fresh in each frame of the
animation. Furthermore all of the circles were drawn together with the
source-over
operation in a separate canvas and the custom composite operation was only used
when the image of the circles was drawn onto the text.
The animation below does not clear the canvas between steps and it draws just the circles (one-by-one) on a blue background using the selected composite operation for each circle. Play around with the different types and other settings to see what how things get drawn. For your convenience, I clear the canvas each time you change the composite operation.
draw: one circle | all circles
composite operation: source-over | destination-over | source-in | destination-in | source-out | destination-out | source-atop | destination-atop | lighter | darker | xor | copy
Bugs?
You may have noticed some unexpected results from this last example versus the original example.
I think the original example works pretty well since the source and destination are the same size
(I generate the source in a separate canvas and draw the entire image onto the destination),
and this makes all the clipping operations—like source-out
—work reliably.
However, in the last example each circle is drawn directly onto the canvas and different browsers
seem to come up with different ways of interpreting some of the compositing operations and
some are just buggy. Regardless, you can generate some fun designs with this last example!