HTML5 Canvas Composition and Its Attributes

Composition using Canvas in HTML5

Composing means combining several images into one image. In combination with the alpha property (transparency using either rgba or globalAlpha), it is a very powerful tool for bringing elements from various scenes into a single scene.

We can draw new shapes behind existing shapes and mask off certain areas and clear sections from the canvas using globalCompositeOperation attributes.

In other words we can say that to perform a composite operation with a HTML5 Canvas, we can use the globalCompositeOperation property of the canvas context.  This property defines the composite operation between the source and destination states of the canvas. Assuming you are trying to compose two different images, the image you draw first is the "source" and the second image is the "destination". Before drawing the destination, you should use the globalCompositeOperation attribute to specify the type of composing you wish to do.

NOTE: It's important to note that a canvas context can only support one composite operation throughout its life cycle. If we want to use multiple composite operations, as this tutorial does, we need to apply the operations on a hidden canvas and then copy the results onto a visible canvas.

This attribute takes the following twelve values:

source-over: The destination image that goes over the source. The destination will cover parts of the source where they intersect.

srcover.jpg
source-in:
Only those parts of the destination that intersect with the source are visible.

srcin.jpg
source-out: Only those parts of the destination that fall outside the source are visible.

srcout.jpg
source-atop: The source and parts of the destination that intersect with the source are visible. Where the destination covers the source, the source is invisible.

srcatop.jpg

destination-over: The source image goes over the destination and covers the intersecting parts of the destination.

destover.jpg

destination-in: Only those parts of the source that intersect with the destination are visible.

destin.jpg

destination-out: Only those parts of the source that fall outside the destination are visible.

destout.jpg

destination-atop: The destination and parts of the source that intersect with the destination are visible. Where the source covers the destination, the destination is invisible.

destatop.jpg

lighter: The portion where source and destination intersect appear lighter, with the colour of the destination being dominant.

lighter.jpg

darker: Where both shapes overlap the color is determined by subtracting color values.

darken.jpg
copy:
Only draws the new shape and removes everything else.

copy.jpg
xor:
The intersecting pixels of the source and destination are xored.

xor.jpg

Example

<!DOCTYPE html>

 

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">

<head>

    <meta charset="utf-8" />

    <title>Composition in HTML5</title>

    <style>

        body {

            margin: 0px;

            padding: 0px;

        }

 

        #myCanvas {

            border: 1px solid #9C9898;

        }

    </style>

</head>

<body>

    <canvas id="myCanvas" width="578" height="430"></canvas>

    <canvas id="tempCanvas" width="578" height="430" style="display: none;"></canvas>

    <script>

        var canvas = document.getElementById('myCanvas');

        var context = canvas.getContext('2d');

        var tempCanvas = document.getElementById('tempCanvas');

        var tempContext = tempCanvas.getContext('2d');

 

        var squareWidth = 55;

        var circleRadius = 35;

        var shapeOffset = 50;

        var operationOffset = 150;

        var arr = [];

 

        arr.push('source-atop');

        arr.push('source-in');

        arr.push('source-out');

        arr.push('source-over');

        arr.push('destination-atop');

        arr.push('destination-in');

        arr.push('destination-out');

        arr.push('destination-over');

        arr.push('lighter');

        arr.push('darker');

        arr.push('xor');

        arr.push('copy');

 

        // translate context to add 10px padding

        context.translate(10, 10);

 

        // draw each of the operations

        for (var n = 0; n < arr.length; n++) {

            var thisOperation = arr[n];

 

            tempContext.save();

 

            // clear temp context

            tempContext.clearRect(0, 0, canvas.width, canvas.height);

 

            // draw rectangle (destination)

            tempContext.beginPath();

            tempContext.rect(0, 0, squareWidth, squareWidth);

            tempContext.fillStyle = 'blue';

            tempContext.fill();

 

            // set global composite

            tempContext.globalCompositeOperation = thisOperation;

 

            // draw circle (source)

            tempContext.beginPath();

            tempContext.arc(shapeOffset, shapeOffset, circleRadius, 0, 2 * Math.PI, false);

            tempContext.fillStyle = 'red';

            tempContext.fill();

            tempContext.restore();

 

            // draw text

            tempContext.font = '10pt Verdana';

            tempContext.fillStyle = 'black';

            tempContext.fillText(thisOperation, 0, squareWidth + 45);

 

            // translate visible context so operation is drawn in the right place

            if (n > 0) {

                if (n % 4 === 0) {

                    context.translate(operationOffset * -3, operationOffset);

                }

                else {

                    context.translate(operationOffset, 0);

                }

            }

 

            // copy drawing from tempCanvas onto visible canvas

            context.drawImage(tempCanvas, 0, 0);

        }

    </script>

</body>

</html>

Output

output.jpg

Up Next
    Ebook Download
    View all
    Learn
    View all