HTML Canvas Compositing
The globalCompositeOperation Property
The globalCompositeOperation
property sets
the type of compositing operation to apply when drawing new shapes. In the
previous chapters new drawings have been placed on top of each other. We can
decide what to do with new shades with the globalCompositeOperation
property.
Let's look at some examples!
The "source-over" Value
The "source-over" value is default. It will draw new shapes on top of the existing content.
Example
Set globalCompositeOperation
property to
"source-over". Then draw two overlapping rectangles:
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.globalCompositeOperation = "source-over";
// Draw two overlapping rectangles
ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle =
"red";
ctx.fillRect(40, 40, 100, 100);
</script>
Try it Yourself »
The "source-out" Value
The "source-out" value will draw new shapes only where it does not overlap the existing content.
Example
Set globalCompositeOperation
property to
"source-out". Then draw two overlapping rectangles:
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.globalCompositeOperation = "source-out";
// Draw two overlapping rectangles
ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle =
"red";
ctx.fillRect(40, 40, 100, 100);
</script>
Try it Yourself »
The "destination-over" Value
The "destination-over" value will draw new shapes behind the existing content.
Example
Set globalCompositeOperation
property to
"destination-over". Then draw two overlapping rectangles:
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.globalCompositeOperation = "destination-over";
// Draw two overlapping rectangles
ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle =
"red";
ctx.fillRect(40, 40, 100, 100);
</script>
Try it Yourself »
The "destination-atop" Value
The "destination-atop" value will keep the existing content where it overlaps the new shape. The new shape is drawn behind the existing content.
Example
Set globalCompositeOperation
property to
"destination-atop". Then draw two overlapping rectangles:
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.globalCompositeOperation = "destination-atop";
// Draw two overlapping rectangles
ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle =
"red";
ctx.fillRect(40, 40, 100, 100);
</script>
Try it Yourself »
The "lighter" Value
The "lighter" value will result in a brighter color where both shapes overlap.
Example
Set globalCompositeOperation
property to
"lighter". Then draw two overlapping rectangles:
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.globalCompositeOperation = "lighter";
// Draw two overlapping rectangles
ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle =
"red";
ctx.fillRect(40, 40, 100, 100);
</script>
Try it Yourself »
The "copy" Value
The "copy" value will result in that only the new shape is shown.
Example
Set globalCompositeOperation
property to
"copy". Then draw two overlapping rectangles:
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.globalCompositeOperation = "copy";
// Draw two overlapping rectangles
ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle =
"red";
ctx.fillRect(40, 40, 100, 100);
</script>
Try it Yourself »
The "xor" Value
The "xor" value will result in that shapes are transparent where both overlap, and drawn normal everywhere else.
Example
Set globalCompositeOperation
property to
"xor". Then draw two overlapping rectangles:
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.globalCompositeOperation = "xor";
// Draw two overlapping rectangles
ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle =
"red";
ctx.fillRect(40, 40, 100, 100);
</script>
Try it Yourself »
The "multiply" Value
The "multiply" value will result in a darker picture. Multiplies the pixels of the top layer with the pixels of the bottom layer.
Example
Set globalCompositeOperation
property to
"multiply". Then draw two overlapping rectangles:
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.globalCompositeOperation = "multiply";
// Draw two overlapping rectangles
ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle =
"red";
ctx.fillRect(40, 40, 100, 100);
</script>
Try it Yourself »
The "screen" Value
The "screen" value will result in a lighter picture. Invert the pixels, then multiply, and inverted again (opposite of "multiply").
Example
Set globalCompositeOperation
property to
"screen". Then draw two overlapping rectangles:
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.globalCompositeOperation = "screen";
// Draw two overlapping rectangles
ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle =
"red";
ctx.fillRect(40, 40, 100, 100);
</script>
Try it Yourself »
The "darken" Value
The "darken" value will result in a darker color where both shapes overlap (keeps the darkest pixels of both layers).
Example
Set globalCompositeOperation
property to
"darken". Then draw two overlapping rectangles:
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.globalCompositeOperation = "darken";
// Draw two overlapping rectangles
ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle =
"red";
ctx.fillRect(40, 40, 100, 100);
</script>
Try it Yourself »
The "lighten" Value
The "lighten" value will result in a lighter color where both shapes overlap (keeps the lightest pixels of both layers).
Example
Set globalCompositeOperation
property to
"lighten". Then draw two overlapping rectangles:
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.globalCompositeOperation = "lighten";
// Draw two overlapping rectangles
ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle =
"red";
ctx.fillRect(40, 40, 100, 100);
</script>
Try it Yourself »
The "hue" Value
The "hue" value adopts the hue of the top layer and preserves the luma and chroma of the bottom layer.
Example
Set globalCompositeOperation
property to
"hue". Then draw two overlapping rectangles:
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.globalCompositeOperation = "hue";
// Draw two overlapping rectangles
ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle =
"red";
ctx.fillRect(40, 40, 100, 100);
</script>
Try it Yourself »
The "luminosity" Value
The "luminosity" value adopts the luma of the top layer and preserves the hue and chroma of the bottom layer.
Example
Set globalCompositeOperation
property to
"luminosity". Then draw two overlapping rectangles:
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.globalCompositeOperation = "luminosity";
// Draw two overlapping rectangles
ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle =
"red";
ctx.fillRect(40, 40, 100, 100);
</script>
Try it Yourself »
The globalCompositeOperation Property Values
The globalCompositeOperation
property can have the following values:
Value | Description |
---|---|
source-over | Default. Draws new shapes on top of the existing content |
source-in | Draws new shapes only where both the new shape and the existing content overlap. Everything else is made transparent |
source-out | Draws new shapes only where it does not overlap the existing content |
source-atop | Draws new shapes only where it does overlap the existing content |
destination-over | Draws new shapes behind the existing content |
destination-in | Keeps the existing content where both the new shape and existing content overlap. Everything else is made transparent |
destination-out | Keeps the existing content where it does not overlap the new shape |
destination-atop | Keeps the existing content where it overlaps the new shape. The new shape is drawn behind the existing content |
lighter | Result in a brighter color where both shapes overlap |
copy | Shows only the new shape |
xor | Shapes are transparent where both overlap and drawn normal everywhere else |
multiply | Multiplies the pixels of the top layer with the pixels of the bottom layer. A darker picture is the result |
screen | Invert the pixels, then multiply, and invert again. A lighter picture is the result (opposite of "multiply") |
overlay | A combination of multiply and screen. Dark parts of base layer is darker, and light parts is lighter |
darken | Keeps the darkest pixels of both layers |
lighten | Keeps the lightest pixels of both layers |
color-dodge | Divides the bottom layer by the inverted top layer |
color-burn | Divides the inverted bottom layer by the top layer, and then inverts the result |
hard-light | Like "overlay", but instead with the top layer and bottom layer swapped |
soft-light | A softer version of "hard-light" |
difference | Subtracts the bottom layer from the top layer - or the other way round - to always get a positive value |
exclusion | Like "difference", but with lower contrast |
hue | Adopts the hue of the top layer and preserves the luma and chroma of the bottom layer |
saturation | Adopts the chroma of the top layer and preserves the luma and hue of the bottom layer |
color | Adopts the hue and chroma of the top layer and preserves the luma of the bottom layer |
luminosity | Adopts the luma of the top layer and preserves the hue and chroma of the bottom layer |