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:
you must view this in a browser that supports the canvas element

Source:
you must view this in a browser that supports the canvas element

Composite:
you must view this in a browser that supports the canvas element

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-overdestination + source
destination-oversource + destination
source-indestination & source
destination-insource & destination
source-outsource - destination
destination-outdestination - source
source-atop destination + (source & destination)
destination-atopsource + (destination & source)
lighterdestination + source + lighter(source & destination)
darkerdestination + source + darker(source & destination)
xorsource ^ destination
copysource

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.

animate: play | pause | step

    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!

composite patterncomposite patterncomposite pattern

comments powered by Disqus

Peter Coles

Peter Coles

is a software engineer who lives in NYC, works at Ringly, and blogs here.
More about Peter »

github · soundcloud · @lethys · rss

It’s time to get big money out of politics. Join the kick-started campaign to put government back in the hands of the people. Pledge mayday.us now