O'Reilly logo

HTML5 Canvas by Jeff Fulton, Steve Fulton

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Filling Objects with Colors and Gradients

In this chapter, we have quickly looked at color and fill styles as we proceeded through the discussions of basic and complex shape construction. In this section, we will take a deeper look at coloring and filling shapes we draw on the canvas. In addition to these simple colors and fills, there are a number of different gradient styles that we can employ. Furthermore, Canvas also has a method to fill shapes with bitmap images (see Chapter 4).

Setting Basic Fill Colors

The Canvas fillStyle property is used to set a basic color for filling shapes on the canvas. We saw this earlier in the chapter when we used simple color names for our fillStyle. An example is:

context.fillStyle = "red";

Below is a list of the usable color string values from the HTML4 specification. As of this writing, the HTML5 color specification has not been set. In the absence of any additional HTML5-specific colors, the HTML4 colors will work properly in HTML5:

Black = #000000
Green = #008000
Silver = #C0C0C0
Lime = #00FF00
Gray = #808080
Olive = #808000
White = #FFFFFF
Yellow = #FFFF00
Maroon = #800000
Navy = #000080
Red = #FF0000
Blue = #0000FF
Purple = #800080
Teal = #008080
Fuchsia = #FF00FF
Aqua = #00FFFF

Note

All these color values will work with the strokeStyle as well as the fillStyle.

Of course, using a string for the color name is not the only available method of specifying a solid color fill. The list below includes a few other methods:

Setting the fill color with the rgb() method

The rgb() method lets us use the 24-bit RGB value when specifying our fill colors:

context.fillStyle = rgb(255,0,0);

This will result in the same red color as the string value above.

Setting the fill color with a hex number string

We can also set the fillStyle color with a hex number in a string:

context.fillStyle = "#ff0000";
Setting the fill color with the rgba() method

The rgba() method allows us to specify a 32-bit color value with the final 8 bits representing the alpha value of the fill color:

context.fillStyle = rgba(255,0,0,1);

The alpha value can be from 1 (opaque) to 0 (transparent).

Filling Shapes with Gradients

There are two basic options for creating gradient fills on the canvas: linear and radial. A linear gradient creates a horizontal, vertical, or diagonal fill pattern; the radial variety creates a fill that “radiates” from a central point in a circular fashion. Let’s look at some examples of each.

Linear gradients

Linear gradients come in three basic styles: horizontal, vertical, and diagonal. We control where colors change in our gradient by setting color stops at points along the length of the object we wish to fill.

Linear horizontal gradients

Example 2-14 creates a simple horizontal gradient, as shown in Figure 2-23.

Example 2-14. A linear horizontal gradient

function drawScreen() {

      // horizontal gradient values must remain 0
      var gr = context.createLinearGradient(0, 0, 100, 0);

      // Add the color stops.
      gr.addColorStop(0,'rgb(255,0,0)');
      gr.addColorStop(.5,'rgb(0,255,0)');
      gr.addColorStop(1,'rgb(255,0,0)');

      // Use the gradient for the fillStyle.
      context.fillStyle = gr;
      context.fillRect(0, 0,100,100);

   }
A linear horizontal gradient

Figure 2-23. A linear horizontal gradient

To create the horizontal gradient, we must first create a variable (gr) to reference the new gradient. Here’s how we set it:

var gr = context.createLinearGradient(0,0,100,0);

The four parameter values in the createLinearGradient method call are the top-left x and y coordinates to start the gradient, as well as the two bottom-right points to end the gradient. Our example starts at 0,0 and goes to 100,0. Notice that the y values are both 0 when we create a horizontal gradient; the opposite will be true when we create a vertical gradient.

Once we have defined the size of our gradient, we then add in color stops that take two parameter values. The first is a relative position origin point along the gradient to start with color, and the second is the color to use. The relative position must be a value from 0.0 to 1.0:

gr.addColorStop(0,'rgb(255,0,0)');
gr.addColorStop(.5,'rgb(0,255,0)');
gr.addColorStop(1,'rgb(255,0,0)');

Therefore, in Example 2-14, we have set a red color at 0, a green color at .5 (the center), and another red color at 1. This will fill our shape with a relatively even red to green to red gradient.

Next, we need to get the context.fillStyle to be the gradient we just created:

context.fillStyle = gr;

Finally, we create a rectangle on the canvas:

context.fillRect(0, 0, 100, 100);

Notice that we created a rectangle that was the exact size of our gradient. We can change the size of the output rectangle like this:

context.fillRect(0, 100, 50, 100);
context.fillRect(0, 200, 200, 100);

Example 2-15 adds these two new filled rectangles to Example 2-14 to create Figure 2-24. Notice that the gradient fills up the available space, with the final color filling out the area larger than the defined gradient size.

Example 2-15. Multiple gradient-filled objects

function drawScreen() {

   var gr = context.createLinearGradient(0, 0, 100, 0);

   // Add the color stops.
   gr.addColorStop(0,'rgb(255,0,0)');
   gr.addColorStop(.5,'rgb(0,255,0)');
   gr.addColorStop(1,'rgb(255,0,0)');

   // Use the gradient for the fillStyle.
   context.fillStyle = gr;
   context.fillRect(0, 0, 100, 100);
   context.fillRect(0, 100, 50, 100);
   context.fillRect(0, 200, 200, 100);

    }
Linear horizontal gradient on multiple objects

Figure 2-24. Linear horizontal gradient on multiple objects

Applying a horizontal gradient to a stroke

Gradients can be applied to any shape—even the stroke around a shape. Example 2-16 takes the filled rectangles from Example 2-15 and creates a strokeRect shape instead of a filled rectangle. Figure 2-25 shows the very different result.

Example 2-16. A horizontal stroke gradient

function drawScreen() {

      var gr = context.createLinearGradient(0, 0, 100, 0);

      // Add the color stops.
      gr.addColorStop(0,'rgb(255,0,0)');
      gr.addColorStop(.5,'rgb(0,255,0)');
      gr.addColorStop(1,'rgb(255,0,0)');

      // Use the gradient for the fillStyle.
      context.strokeStyle = gr;
      context.strokeRect(0, 0, 100, 100);
      context.strokeRect(0, 100, 50, 100);
      context.strokeRect(0, 200, 200, 100);

   }
Horizontal stroke gradients

Figure 2-25. Horizontal stroke gradients

Applying a horizontal gradient to a complex shape

We can also apply a linear gradient to a “closed” shape made up of points, as shown in Example 2-17. A shape is considered closed when the final point is the same as the starting point.

Example 2-17. Horizontal gradient on a complex shape

function drawScreen() {

      var gr = context.createLinearGradient(0, 0, 100, 0);

      // Add the color stops.
      gr.addColorStop(0,'rgb(255,0,0)');
      gr.addColorStop(.5,'rgb(0,255,0)');
      gr.addColorStop(1,'rgb(255,0,0)');

      // Use the gradient for the fillStyle.
      context.fillStyle = gr;
      context.beginPath();
      context.moveTo(0,0);
      context.lineTo(50,0);
      context.lineTo(100,50);
      context.lineTo(50,100);
      context.lineTo(0,100);
      context.lineTo(0,0);
      context.stroke();
      context.fill();
      context.closePath();

   }

In this example, we use the context.fill() command to fill in our shape with the current fillStyle, creating the output shown in Figure 2-26.

A horizontal gradient on a complex shape

Figure 2-26. A horizontal gradient on a complex shape

Figure 2-26 shows the new shape we have created with points. As long as the points are closed, the fill will work as we expect.

Vertical gradients

Vertical gradients are created in a very similar manner as the horizontal variety. The difference is that we must specify a y value that is not 0, and the x values must both be 0. Example 2-18 shows the shape from Example 2-17 created with a vertical rather than a horizontal gradient to produce the output in Figure 2-27.

Example 2-18. Vertical gradients

function drawScreen() {

      var gr = context.createLinearGradient(0, 0, 0, 100);

      // Add the color stops.
      gr.addColorStop(0,'rgb(255,0,0)');
      gr.addColorStop(.5,'rgb(0,255,0)');
      gr.addColorStop(1,'rgb(255,0,0)');

      // Use the gradient for the fillStyle.
      context.fillStyle = gr;
      context.beginPath();
      context.moveTo(0,0);
      context.lineTo(50,0);
      context.lineTo(100,50);
      context.lineTo(50,100);
      context.lineTo(0,100);
      context.lineTo(0,0);
      //context.stroke();
      context.fill();
      context.closePath();

   }
A vertical gradient example

Figure 2-27. A vertical gradient example

The only difference between Example 2-18 and Example 2-17 is the line creating the linear gradient.

The horizontal version (Example 2-17):

var gr = context.createLinearGradient(0, 0, 100, 0);

The new vertical version (Example 2-18):

var gr = context.createLinearGradient(0, 0, 0, 100);

All of the same rules for strokes on horizontal gradients apply to vertical ones. Example 2-19 takes the shape from Example 2-18, stroking it with the gradient instead of filling it, producing the outline shown in Figure 2-28.

Example 2-19. A vertical gradient stroke

function drawScreen() {

      var gr = context.createLinearGradient(0, 0, 0, 100);

      // Add the color stops.
      gr.addColorStop(0,'rgb(255,0,0)');
      gr.addColorStop(.5,'rgb(0,255,0)');
      gr.addColorStop(1,'rgb(255,0,0)');

      // Use the gradient for the fillStyle.
      context.strokeStyle = gr;
      context.beginPath();
      context.moveTo(0,0);
      context.lineTo(50,0);
      context.lineTo(100,50);
      context.lineTo(50,100);
      context.lineTo(0,100);
      context.lineTo(0,0);
      context.stroke();
      context.closePath();

   }
A vertical gradient stroke

Figure 2-28. A vertical gradient stroke

Diagonal gradients

You can easily create a diagonal gradient by varying both the second x and second y parameters of the createLinearGradient() function:

var gr= context.createLinearGradient(0, 0, 100, 100);

To create a perfect diagonal gradient, as shown in Figure 2-29, fill a square that is the same size as the diagonal gradient. The code is provided in Example 2-20.

Example 2-20. A diagonal gradient

function drawScreen() {

      var gr = context.createLinearGradient(0, 0, 100, 100);

      // Add the color stops.
      gr.addColorStop(0,'rgb(255,0,0)');
      gr.addColorStop(.5,'rgb(0,255,0)');
      gr.addColorStop(1,'rgb(255,0,0)');

      // Use the gradient for the fillStyle.
      context.fillStyle = gr;
      context.beginPath();
      context.moveTo(0,0);
      context.fillRect(0,0,100,100)
      context.closePath();

   }
A diagonal gradient example

Figure 2-29. A diagonal gradient example

Radial gradients

The definition process for radial and linear gradients is very similar. Although a radial gradient takes six parameters to initialize rather than the four needed for a linear gradient, it uses the same color stop idea to create the color changes.

The six parameters are used to define the center point and the radii of two circles. The first circle is the “start” circle, and the second circle is the “end” circle. Let’s look at an example:

var gr = context.createRadialGradient(50,50,25,50,50,100);

The first circle has a center point of 50,50 and a radius of 25; the second has a center point of 50,50 and a radius of 100. This will effectively create two concentric circles.

We set color stops the same way we did with the linear gradients:

gr.addColorStop(0,'rgb(255,0,0)');
gr.addColorStop(.5,'rgb(0,255,0)');
gr.addColorStop(1,'rgb(255,0,0)');

Example 2-21 puts this together to create the result shown in Figure 2-30.

Example 2-21. A simple radial gradient

function drawScreen() {

      var gr = context.createRadialGradient(50,50,25,50,50,100);

      // Add the color stops.
      gr.addColorStop(0,'rgb(255,0,0)');
      gr.addColorStop(.5,'rgb(0,255,0)');
      gr.addColorStop(1,'rgb(255,0,0)');

      // Use the gradient for the fillStyle.
      context.fillStyle = gr;
      context.fillRect(0, 0, 200, 200);

   }
A simple radial gradient

Figure 2-30. A simple radial gradient

Example 2-22 offsets the second circle from the first to create the effects shown in Figure 2-31.

Example 2-22. A complex radial gradient

function drawScreen() {

      var gr = context.createRadialGradient(50,50,25,100,100,100);

      // Add the color stops.
      gr.addColorStop(0,'rgb(255,0,0)');
      gr.addColorStop(.5,'rgb(0,255,0)');
      gr.addColorStop(1,'rgb(255,0,0)');

      // Use the gradient for the fillStyle.
      context.fillStyle = gr;
      context.fillRect(0, 0, 200, 200);

}
A complex radial gradient

Figure 2-31. A complex radial gradient

As with the linear gradients, we can also apply the radial gradients to complex shapes. Example 2-23 takes an arc example from earlier in this chapter, but applies a radial gradient to create Figure 2-32.

Example 2-23. A radial gradient applied to a circle

function drawScreen() {

      var gr = context.createRadialGradient(50,50,25,100,100,100);

      // Add the color stops.
      gr.addColorStop(0,'rgb(255,0,0)');
      gr.addColorStop(.5,'rgb(0,255,0)');
      gr.addColorStop(1,'rgb(255,0,0)');

      // Use the gradient for the fillStyle.
      context.fillStyle = gr;
      context.arc(100, 100, 100, (Math.PI/180)*0, (Math.PI/180)*360, false);
      context.fill();

   }
A radial gradient applied to a circle

Figure 2-32. A radial gradient applied to a circle

Example 2-23 takes the radial gradient from Example 2-22 and applies it to a circle shape rather than a rectangle shape. This removes the red square from the background of the shape.

We can also apply our radial gradient to the stroke of our arc rather than the fill, as shown in Example 2-24 and Figure 2-33.

Example 2-24. An arc stroke gradient

function drawScreen() {

      var gr = context.createRadialGradient(50,50,25,100,100,100);

      // Add the color stops.
      gr.addColorStop(0,'rgb(255,0,0)');
      gr.addColorStop(.5,'rgb(0,255,0)');
      gr.addColorStop(1,'rgb(255,0,0)');

      // Use the gradient for the fillStyle.
      context.strokeStyle = gr;
      context.arc(100, 100, 50, (Math.PI/180)*0, (Math.PI/180)*360, false)
      context.stroke();

   }
An arc stroke gradient

Figure 2-33. An arc stroke gradient

Example 2-24 created a circle that is smaller than the version in Example 2-23, so the radial gradient would show up on the stroke of the arc. If we left it the same size as Example 2-23, we would have a solid red fill because the radial gradient is solid red at the diameter edge of the circle.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required