w3resource

HTML5 Canvas: Compositing

Introduction

By default, images are layered on the canvas in drawing order, with new images layered on top of older images. In computer graphics, alpha compositing is the process of combining an image with a background to create the appearance of partial or full transparency. It is often useful to render image elements in separate passes, and then combine the resulting multiple 2D images into a single, final image in a process called the composite.

In a web page, it's background is the lowest layer, followed by any HTML elements positioned beneath the canvas element. Any CSS background applied to the canvas element comes next, followed by anything drawn on the canvas, with the most recent image, line, or shape in the top layer.

The canvas element also supports a global alpha channel. The global alpha channel can be set to any value between 0.0 and 1.0 (default value), where 0.0 indicates fully transparent and 1.0 indicates no transparency.

All drawing operations are affected by the global compositing attributes, globalAlpha and globalCompositeOperation, and so can be attenuated to any degree, up to full transparency. This allows you to draw semi transparent images, even if the source image has no alpha channel.

Global Alpha

The global alpha value allows you to draw with varying degrees of transparency. The context’s globalAlpha property returns the current alpha value applied to rendering operations. Can be set, to change the alpha value.

Syntax:

ctx.globalAlpha [ = value ]

Note: Values outside of the range 0.0 .. 1.0 are ignored.

The following web document shows the various images with transparency between 0 to 1 :

Output:

html5 canvas transparency

Code:

<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas Transparency</title>
</head>
<body> 
<canvas id="MyCanvas" width="650" height="600"></canvas>
<script>
var canvas = document.getElementById("MyCanvas"); 
if (canvas.getContext) // Test for support.
  {          
    var ctx = canvas.getContext("2d"); // Get the context to draw on.
      for (var g = 0,x=0, y=25; g <= 10; g+=1, x+=25, y+=25) 
       {
         ctx.globalAlpha = g/10;  
         ctx.fillStyle = "red";
         ctx.strokeStyle = "black";
         ctx.fillRect(x, y, 200, 200);  // Create a filled rectangle.
         ctx.strokeRect(x, y, 200, 200); // Put an outline around it
         ctx.globalAlpha = 1;  
         ctx.fillStyle = 'blue';
         ctx.font = "14px Unknown Font, sans-serif";  
         ctx.fillText("Transparency Value "+g, 202+x, y+10);
         ctx.globalAlpha = g/10;                         
       }
  }      
</script>
</body> 
</html>

globalCompositeOperation property

The globalCompositeOperation attribute sets how shapes and images are drawn onto the existing bitmap, once they have had globalAlpha and the current transformation matrix applied. It must be set to a value from the following list. In the descriptions below, the source image, A, is the shape or image being rendered, and the destination image, B, is the current state of the bitmap.

Syntax:

ctx.globalCompositeOperation [ = value ]

Property values:

Parameters   Description
source-atop A atop B
  • Display the source image wherever both images are opaque.
  • Display the destination image wherever the destination image is opaque but the source image is transparent.
  • Display transparency elsewhere.
source-in A in B
  • Display the source image wherever both the source image and destination image are opaque.
  • Display transparency elsewhere.
source-out A out B
  • The source image is copied out of the destination image.
  • The source image is displayed where the source is opaque and the destination is transparent.
  • Other regions are transparent.
source-over A over B
  • Display the source image wherever the source image is opaque.
  • Display the destination image elsewhere.
destination-atop B atop A.
  • Display the source image wherever both images are opaque.
  • Display the destination image wherever the destination image is opaque but the source image is transparent.
  • Display transparency elsewhere.
destination-in B in A
  • Display the source image wherever both the source image and destination image are opaque.
  • Display transparency elsewhere.
destination-out B out A
  • The source image is copied out of the destination image.
  • The source image is displayed where the source is opaque and the destination is transparent.
  • Other regions are transparent.
destination-over B over A
  • Display the source image wherever the source image is opaque.
  • Display the destination image elsewhere.
lighter A plus B Display the sum of the source image and destination image, with color values approaching 255 (100%) as a limit.
copy

A (B is ignored)

Display the source image instead of the destination image.
xor A xor B Exclusive OR of the source image and destination image.
vendorName-operationName   Vendor-specific extensions to the list of composition operators should use this syntax.

The following web document draws a rectangle and a circle :

Output:

html5 canvas rectangle circle

Code :

<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas rectangle and circle </title>
</head>
<body>
<canvas id="MyCanvas" width="650" height="600"></canvas>
<script>
 var canvas = document.getElementById("MyCanvas"); 
 if (canvas.getContext) // Test for support.
   {          
     var ctx = canvas.getContext("2d");                
     // draw green rectangle
     ctx.beginPath();
     ctx.rect(100, 20, 100, 100);
     ctx.fillStyle = 'green';
     ctx.fill();
     // draw red circle
     ctx.beginPath();
     ctx.arc(190, 120, 60, 0, 2 * Math.PI, false);
     ctx.fillStyle = 'red';
     ctx.fill();                
   }   
</script>
</body> 
</html>

Let set the context’s globalCompositeOperation property values one by one on the above example.

Example - 1: globalCompositeOperation property value : source-atop

Output:

html5 canvas source-atop

Code:

<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas set global composite - source-atop</title>
</head>
<body>
<canvas id="MyCanvas" width="650" height="600"></canvas>
<script>
var canvas = document.getElementById("MyCanvas"); 
 if (canvas.getContext) // Test for support.
   {          
     var ctx = canvas.getContext("2d");    
     
     // draw green rectangle (destination)
     ctx.beginPath();
     ctx.rect(100, 20, 100, 100);
     ctx.fillStyle = 'green';
     ctx.fill();
     // set global composite - source-atop
     ctx.globalCompositeOperation = 'source-atop';
     // draw red circle (source)
     ctx.beginPath();
     ctx.arc(190, 120, 60, 0, 2 * Math.PI, false);
     ctx.fillStyle = 'red';
     ctx.fill();        
   }  
</script>
</body> 
</html>

Example - 2: globalCompositeOperation property value : source-in

Output:

html5 canvas source- in

Code :

<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas set global composite - source-in</title>
</head>
<body>
<canvas id="MyCanvas" width="650" height="600"></canvas>
<script>
var canvas = document.getElementById("MyCanvas"); 
 if (canvas.getContext) // Test for support.
   {          
     var ctx = canvas.getContext("2d");    
     
     // draw green rectangle (destination)
     ctx.beginPath();
     ctx.rect(100, 20, 100, 100);
     ctx.fillStyle = 'green';
     ctx.fill();
     // set global composite - source-in
     ctx.globalCompositeOperation = 'source-in';
     // draw red circle (source)
     ctx.beginPath();
     ctx.arc(190, 120, 60, 0, 2 * Math.PI, false);
     ctx.fillStyle = 'red';
     ctx.fill();        
   }  
</script>
</body> 
</html>

Example - 3: globalCompositeOperation property value : source-out

Output:

html5 canvas source-out

Code:

<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas set global composite - source-out</title>
</head>
<body>
<canvas id="MyCanvas" width="650" height="600"></canvas>
<script>
var canvas = document.getElementById("MyCanvas"); 
 if (canvas.getContext) // Test for support.
   {          
     var ctx = canvas.getContext("2d");    
     
     // draw green rectangle (destination)
     ctx.beginPath();
     ctx.rect(100, 20, 100, 100);
     ctx.fillStyle = 'green';
     ctx.fill();
    // set global composite - source-out
     ctx.globalCompositeOperation = 'source-out';
     // draw red circle (source)
     ctx.beginPath();
     ctx.arc(190, 120, 60, 0, 2 * Math.PI, false);
     ctx.fillStyle = 'red';
     ctx.fill();        
   }  
</script>
</body> 
</html>

Example - 4 : globalCompositeOperation property value : source-over

Output:

html5 canvas source-over

Code :

<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas set global composite - source-over</title>
</head>
<body>
<canvas id="MyCanvas" width="650" height="600"></canvas>
<script>
var canvas = document.getElementById("MyCanvas"); 
 if (canvas.getContext) // Test for support.
   {          
     var ctx = canvas.getContext("2d");    
     
     // draw green rectangle (destination)
     ctx.beginPath();
     ctx.rect(100, 20, 100, 100);
     ctx.fillStyle = 'green';
     ctx.fill();
    // set global composite - source-over
     ctx.globalCompositeOperation = 'source-over';
     // draw red circle (source)
     ctx.beginPath();
     ctx.arc(190, 120, 60, 0, 2 * Math.PI, false);
     ctx.fillStyle = 'red';
     ctx.fill();        
   }  
</script>
</body> 
</html>

Example - 5: globalCompositeOperation property value : destination-atop

Output:

html5 canvas destination-atop

Code:

<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas set global composite - destination-atop</title>
</head>
<body>
<canvas id="MyCanvas" width="650" height="600"></canvas>
<script>
var canvas = document.getElementById("MyCanvas"); 
 if (canvas.getContext) // Test for support.
   {          
     var ctx = canvas.getContext("2d");    
     
     // draw green rectangle (destination)
     ctx.beginPath();
     ctx.rect(100, 20, 100, 100);
     ctx.fillStyle = 'green';
     ctx.fill();
    // set global composite - destination-atop
     ctx.globalCompositeOperation = 'destination-atop';
     // draw red circle (source)
     ctx.beginPath();
     ctx.arc(190, 120, 60, 0, 2 * Math.PI, false);
     ctx.fillStyle = 'red';
     ctx.fill();        
   }  
</script>
</body> 
</html>

Example - 6 : globalCompositeOperation property value : destination-in

Output:

html5 canvas destination-in

Code:

<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas set global composite - destination-in</title>
</head>
<body>
<canvas id="MyCanvas" width="650" height="600"></canvas>
<script>
var canvas = document.getElementById("MyCanvas"); 
 if (canvas.getContext) // Test for support.
   {          
     var ctx = canvas.getContext("2d");    
     
     // draw green rectangle (destination)
     ctx.beginPath();
     ctx.rect(100, 20, 100, 100);
     ctx.fillStyle = 'green';
     ctx.fill();
    // set global composite - destination-in
     ctx.globalCompositeOperation = 'destination-in';
     // draw red circle (source)
     ctx.beginPath();
     ctx.arc(190, 120, 60, 0, 2 * Math.PI, false);
     ctx.fillStyle = 'red';
     ctx.fill();        
   }  
</script>
</body> 
</html>

Example - 7 : globalCompositeOperation property value: destination-out

Output:

html5 canvas destination-out

Code :

<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas set global composite - destination-out</title>
</head>
<body>
<canvas id="MyCanvas" width="650" height="600"></canvas>
<script>
var canvas = document.getElementById("MyCanvas"); 
 if (canvas.getContext) // Test for support.
   {          
     var ctx = canvas.getContext("2d");    
     
     // draw green rectangle (destination)
     ctx.beginPath();
     ctx.rect(100, 20, 100, 100);
     ctx.fillStyle = 'green';
     ctx.fill();
     // set global composite - destination-out
     ctx.globalCompositeOperation = 'destination-out';
     // draw red circle (source)
     ctx.beginPath();
     ctx.arc(190, 120, 60, 0, 2 * Math.PI, false);
     ctx.fillStyle = 'red';
     ctx.fill();        
   }  
</script>
</body> 
</html>

Example - 8 : globalCompositeOperation property value : destination-over

Output:

html5 canvas destination-over

Code :

<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas set global composite - destination-over</title>
</head>
<body>
<canvas id="MyCanvas" width="650" height="600"></canvas>
<script>
var canvas = document.getElementById("MyCanvas"); 
 if (canvas.getContext) // Test for support.
   {          
     var ctx = canvas.getContext("2d");    
     
     // draw green rectangle (destination)
     ctx.beginPath();
     ctx.rect(100, 20, 100, 100);
     ctx.fillStyle = 'green';
     ctx.fill();
     // set global composite - destination-over
     ctx.globalCompositeOperation = 'destination-over';
     // draw red circle (source)
     ctx.beginPath();
     ctx.arc(190, 120, 60, 0, 2 * Math.PI, false);
     ctx.fillStyle = 'red';
     ctx.fill();        
   }  
</script>
</body> 
</html>

Example - 9 : globalCompositeOperation property value : lighter

Output :

html5 canvas lighter

Code :

<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas set global composite - lighter</title>
</head>
<body>
<canvas id="MyCanvas" width="650" height="600"></canvas>
<script>
var canvas = document.getElementById("MyCanvas"); 
 if (canvas.getContext) // Test for support.
   {          
     var ctx = canvas.getContext("2d");    
     
     // draw green rectangle (destination)
     ctx.beginPath();
     ctx.rect(100, 20, 100, 100);
     ctx.fillStyle = 'green';
     ctx.fill();
     // set global composite - lighter
     ctx.globalCompositeOperation = 'lighter';
     // draw red circle (source)
     ctx.beginPath();
     ctx.arc(190, 120, 60, 0, 2 * Math.PI, false);
     ctx.fillStyle = 'red';
     ctx.fill();        
   }  
</script>
</body> 
</html>

Example - 10 : globalCompositeOperation property value : copy

Output :

html5 canvas copy

Code :

<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas set global composite - copy</title>
</head>
<body>
<canvas id="MyCanvas" width="650" height="600"></canvas>
<script>
var canvas = document.getElementById("MyCanvas"); 
 if (canvas.getContext) // Test for support.
   {          
     var ctx = canvas.getContext("2d");    
     
     // draw green rectangle (destination)
     ctx.beginPath();
     ctx.rect(100, 20, 100, 100);
     ctx.fillStyle = 'green';
     ctx.fill();
   // set global composite - copy
     ctx.globalCompositeOperation = 'copy';
     // draw red circle (source)
     ctx.beginPath();
     ctx.arc(190, 120, 60, 0, 2 * Math.PI, false);
     ctx.fillStyle = 'red';
     ctx.fill();        
   }  
</script>
</body> 
</html>

Example - 11 : globalCompositeOperation property value : xor

Output:

html5 canvas xor

Code:

<!DOCTYPE html>
<html>
<head>
<title>HTML5 Canvas set global composite - copy</title>
</head>
<body>
<canvas id="MyCanvas" width="650" height="600"></canvas>
<script>
var canvas = document.getElementById("MyCanvas"); 
 if (canvas.getContext) // Test for support.
   {          
     var ctx = canvas.getContext("2d");    
     
     // draw green rectangle (destination)
     ctx.beginPath();
     ctx.rect(100, 20, 100, 100);
     ctx.fillStyle = 'green';
     ctx.fill();
     // set global composite - xor
     ctx.globalCompositeOperation = 'xor';
     // draw red circle (source)
     ctx.beginPath();
     ctx.arc(190, 120, 60, 0, 2 * Math.PI, false);
     ctx.fillStyle = 'red';
     ctx.fill();        
   }  
</script>
</body> 
</html>

Code Editor:

See the Pen html css common editor by w3resource (@w3resource) on CodePen.


Previous: HTML5 Canvas translation, scaling and rotation tutorial



Follow us on Facebook and Twitter for latest update.