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 an 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 color 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
  1. <!DOCTYPE html>  
  2.    
  3. <html lang="en" xmlns="http://www.w3.org/1999/xhtml">  
  4. <head>  
  5.     <meta charset="utf-8" />  
  6.     <title>Composition in HTML5</title>  
  7.     <style>  
  8.         body {  
  9.             margin: 0px;  
  10.             padding: 0px;  
  11.         }  
  12.   
  13.         #myCanvas {  
  14.             border: 1px solid #9C9898;  
  15.         }  
  16.     </style>  
  17. </head>  
  18. <body>  
  19.     <canvas id="myCanvas" width="578" height="430"></canvas>  
  20.     <canvas id="tempCanvas" width="578" height="430" style="display: none;"></canvas>  
  21.     <script>  
  22.         var canvas = document.getElementById('myCanvas');  
  23.         var context = canvas.getContext('2d');  
  24.         var tempCanvas = document.getElementById('tempCanvas');  
  25.         var tempContext = tempCanvas.getContext('2d');  
  26.    
  27.         var squareWidth = 55;  
  28.         var circleRadius = 35;  
  29.         var shapeOffset = 50;  
  30.         var operationOffset = 150;  
  31.         var arr = [];  
  32.    
  33.         arr.push('source-atop');  
  34.         arr.push('source-in');  
  35.         arr.push('source-out');  
  36.         arr.push('source-over');  
  37.         arr.push('destination-atop');  
  38.         arr.push('destination-in');  
  39.         arr.push('destination-out');  
  40.         arr.push('destination-over');  
  41.         arr.push('lighter');  
  42.         arr.push('darker');  
  43.         arr.push('xor');  
  44.         arr.push('copy');  
  45.    
  46.         // translate context to add 10px padding  
  47.         context.translate(10, 10);  
  48.    
  49.         // draw each of the operations  
  50.         for (var n = 0; n < arr.length; n++) {  
  51.             var thisOperation = arr[n];  
  52.    
  53.             tempContext.save();  
  54.    
  55.             // clear temp context  
  56.             tempContext.clearRect(0, 0, canvas.width, canvas.height);  
  57.    
  58.             // draw rectangle (destination)  
  59.             tempContext.beginPath();  
  60.             tempContext.rect(0, 0, squareWidth, squareWidth);  
  61.             tempContext.fillStyle = 'blue';  
  62.             tempContext.fill();  
  63.    
  64.             // set global composite  
  65.             tempContext.globalCompositeOperation = thisOperation;  
  66.    
  67.             // draw circle (source)  
  68.             tempContext.beginPath();  
  69.             tempContext.arc(shapeOffset, shapeOffset, circleRadius, 0, 2 * Math.PI, false);  
  70.             tempContext.fillStyle = 'red';  
  71.             tempContext.fill();  
  72.             tempContext.restore();  
  73.    
  74.             // draw text  
  75.             tempContext.font = '10pt Verdana';  
  76.             tempContext.fillStyle = 'black';  
  77.             tempContext.fillText(thisOperation, 0, squareWidth + 45);  
  78.    
  79.             // translate visible context so operation is drawn in the right place  
  80.             if (n > 0) {  
  81.                 if (n % 4 === 0) {  
  82.                     context.translate(operationOffset * -3, operationOffset);  
  83.                 }  
  84.                 else {  
  85.                     context.translate(operationOffset, 0);  
  86.                 }  
  87.             }  
  88.    
  89.             // copy drawing from tempCanvas onto visible canvas  
  90.             context.drawImage(tempCanvas, 0, 0);  
  91.         }  
  92.     </script>  
  93. </body>  
  94. </html> 
Output
 
output.jpg