Canvas blending is an HTML feature for designers and web developers. In this blog post, I present the syntax and some use cases where blend modes are particularly useful.
What are blend modes?
To put it simply, blend modes are ways of combining two graphic objects using special mathematical formulas.
Recently, blend modes have landed in HTML 2D Canvas. The feature is enabled in Apple Safari, Mozilla Firefox and Google Chrome.
At a first glance, blend modes seem to be no different than transparency, but in reality, the results achieved with blending are much more expressive than using simple opacity. In practice, blending is generally used together with transparency.
If you want to read more about each of the blending operations, you can check out How To: An Explanation of Illustrator’s Blending Modes by Sara Froehlich.
Using canvas blending
To use blend modes in canvas, set the globalCompositeOperator property of the Context 2D Canvas, as follows:
// Get the canvas element. "cvs" is the id of the html canvas element.
var canvas = document.getElementById("cvs");
// Get the Context object.
var context = canvas.getContext("2d");
// Set the blending operation.
context.globalCompositeOperation = "multiply";
After this block is executed, any graphic elements drawn on the canvas are blended using the “multiply” blend mode.
In the first example, there are two assets: a raindrop pattern and a picture of a building. We’d like to make the building look as if it’s reflected in the raindrop.
To achieve this result, we first draw the raindrop picture. Once this operation is finished, we set the blendMode of the canvas to soft-light.
In the next step, we draw the second image. Click the button to preview the effect. As you can see, the result looks like a reflected building.
Finally, we add one more effect: we blend the result with a linear gradient. All we have to do is create and draw the gradient in the canvas, since the blending operation is already set. You can see the result by clicking on the button.
After finishing these tasks, we want to prevent any further elements drawn into the canvas from blending.
This means we have to clear the blending operator, as follows:
context.globalCompositeOperation = "source-over";
The next demo showcases two of the most extensively used blend modes: screen and multiply.
Imagine the following scenario: you are developing a game where a character is trapped in a dungeon. The dungeon consists of a dark cavern. The player needs a light source. Let’s see how we can achieve these results with blending:
The following pen shows this result. Use the W, A, S, D keys to travel around the map. Press any other key to intensify the light source.
Here, we use the multiply blend mode to darken the map: this is done by drawing the actual map as an image, followed by setting the blend mode of the canvas context to multiply. Next, a gray rectangle is drawn on top of the initial image. The darkening effect is now complete.
The second use of blending is to simulate the light emitted from the character in the dungeon. For this, we use a radial gradient, from transparent to yellow. This gradient is now blended with the backdrop using the “screen” blend mode operation, thus simulating the effect of a torch.
The next example shows how fog effects can be simulated using blend modes. If you hover over the next pen, you will see how fog is dynamically added to the canvas. How is this achieved?
Radial gradients from transparent to white are added to the photo, using the soft-light blend mode.
In general, when using blend modes, the result can sometimes be too intense. In order to temper this, it’s a common pattern to blend with transparency. The trick is to tune the blending result by setting opacity on the layer that is blended. As shown in this example, varying the opacity of the gradient’s color actually determines the density of the fog. You can set the fog density through the slider at the bottom of the page and observe how the result if more powerful for higher opacity.
Here’s another effect that can be obtained with canvas blend modes: let’s say you are designing a game where the player controls a character. If the character has low hit points, you can flash the player’s screen, with red, as a warning sign. In the next example, this is done by drawing a red rectangle on top of the whole canvas, using the overlay blend mode.
This shows the power of blend modes. You can click the radio buttons to switch the way the overlay rectangle is drawn. The blending result is clearly better than the one using only transparency.
My last example is a solution to the following problem: you have a pattern and you want to draw a group of elements, and blend this whole group with the pattern. If you set the blend mode of the canvas and start drawing the elements of the group one by one, they blend with each other, causing an undesirable result.
Thankfully, as shown in the following pen, there is a solution for this problem: In this example, we have a t-shirt pattern and a robot. The robot is made of a group of elements.
To blend the robot with the t-shirt pattern, this is what you have to do:
Draw the robot in a new canvas. This is achieved by creating a new canvas element. When we’re done drawing the robot, we set the blend mode on our original canvas and draw the newly created canvas on the original one, as follows:
// This creates a new canvas where we’ll draw the robot.
var layerCanvas = document.createElement("canvas");
var layerContext = layerCanvas.getContext("2d");
// Actually draw the robot.
layerContext.fillStyle = "purple";
layerContext.arc(50, 50, 40, 0, 2 * Math.PI);
layerContext.fillStyle = "navy";
layerContext.fillRect(5, 35, 90, 30);
layerContext.fillStyle = "purple";
layerContext.fillRect(20, 40, 20, 20);
layerContext.fillRect(60, 40, 20, 20);
// Set the blend mode of the original canvas
context.globalCompositeOperation = "overlay";
// Blend the robot with the pattern.
// Drawing the newly created canvas on top of the original one.
context.drawImage(layerCanvas, 100, 70);
In this blog post, we show the usage of canvas blend modes and provided some examples, most of which can be used in designing games or photo editing. Finally, we highlight the differences that opacity makes when used with blending, and why blending is different than simple transparency.
We’d love to hear from you, either if you have questions, demos or thoughts on this feature.
Here are the code samples used in this blog post: