Free Trial

Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.

  • Create BookmarkCreate Bookmark
  • Create Note or TagCreate Note or Tag
  • PrintPrint
Share this Page URL
Help

4. Hacking Your Graphics with Canvas and... > Hack 38. Apply Styles to Your Canvas...

Hack 38. Apply Styles to Your Canvas Elements

We don’t live in a black-and-white Web, which makes it essential to be able to apply colors and styles to your <canvas> tag elements. Style your canvas elements with this familiar CSS syntax.

If you need to catch up on how to create shapes, strokes, or fills on your <canvas> tag, read [Hack #37].

Shapes and strokes have little effect on our applications if we can’t apply color and styles to them. The specification for canvas styles borrows heavily from CSS, so a lot of the syntax should be familiar to you.

Color

Canvas elements can be colored with any CSS color value style, and they even support transparency with RGBA and HSPA colors. Also, canvas strokes and shapes have a default color value of black.

Let’s look at a code example for drawing a grid of lines across a 200 × 200 <canvas> tag:

    var myCanvas = document.getElementById('myCanvas')
    var myContext = myCanvas.getContext('2d');
    myContext.beginPath();
    for(i=0; i<201; i++){
        myContext.moveTo(0,i);
        myContext.lineTo(200,i);
        i+=10;
    }

    for(i=0; i<201; i++){
        myContext.moveTo(i,0);
        myContext.lineTo(i, 200);
        i+=10;
    }
    myContext.stroke();

This example draws vertical lines every 10 points, and then loops around again to draw horizontal lines every 10 points. As stated previously, the default color for each line is black. To give the look of graph paper we want to make the lines a light blue color. We can accomplish this by adding a single line of code:

    myContext.strokeStyle = '#99C4E5';

Since the whole grid is accomplished through one stroke, we only need to declare the style once. To add a bit of depth to our grid we will make the horizontal lines slightly darker than the vertical lines. Since we are going to style the lines in two different ways, we need to add a few lines of JavaScript to our code to separate our illustration into two different strokes. To accomplish this, we will end the stroke after the first for loop and then start a new stroke for the second for loop:

    var myCanvas = document.getElementById('myCanvas2')
    var myContext = myCanvas.getContext('2d');
    myContext.strokeStyle = '#1487E0';

    myContext.beginPath();
    for(i=0; i<201; i++){
        myContext.moveTo(0,i);
        myContext.lineTo(200,i);
        i+=10;
    }
    myContext.stroke();
    myContext.beginPath();
    myContext.strokeStyle = '#B1CADD';

    for(i=0; i<201; i++){
        myContext.moveTo(i,0);
        myContext.lineTo(i, 200);
        i+=10;
    }

As soon as we started the second stroke with the beginPath method, we set a new, darker stroke style for the horizontal lines.

There are two different methods for adding color to your shapes. strokeStyle applies to lines and the outline of shapes, and fillStyle applies to shapes or strokes that have a fill applied to them. It’s important to note that once you set a stroke or fill style, the setting will persist in the context until it is changed back to the original value, or until it is set to a new value.

Gradients

Just as with other HTML5 elements, adding gradients can provide for deep visual depth, and can be quite useful. Let’s take a look at our example of a simple black-and-white smiley face, before applying a few gradients to spice it up:

    var mySmile = document.getElementById('mySmile')
    var smileCtx = mySmile.getContext('2d');

    smileCtx.beginPath();
    smileCtx.arc(100,100,99,0,Math.PI*2); // head
    smileCtx.moveTo(170,100);
    smileCtx.arc(100,100,70,0,Math.PI);   // Mouth
    smileCtx.stroke();

    smileCtx.beginPath();
    smileCtx.moveTo(60, 65);
    smileCtx.arc(60,65,12,0,Math.PI*2);  // Left eye
    smileCtx.fill();

    smileCtx.beginPath();
    smileCtx.moveTo(140,65);
    smileCtx.arc(140,65,12,0,Math.PI*2);  // Right eye
    smileCtx.fill();

The preceding code provides us with the basic smiley face shown in Figure 4-5.

The <canvas> tag with the smiley face illustration
Figure 4-5. The <canvas> tag with the smiley face illustration

As every child who wasn’t raised by wolves knows, smiley faces are supposed to be yellow. Let’s redraw our smiley face with a yellow background:

    var mySmile = document.getElementById('mySmile')
    var smileCtx = mySmile.getContext('2d');

    smileCtx.beginPath();

    smileCtx.fillStyle = '#F1F42E';
    smileCtx.arc(100,100,99,0,Math.PI*2); // head

    smileCtx.stroke();
    smileCtx.fill();

    smileCtx.beginPath();
    smileCtx.moveTo(170,100);
    smileCtx.arc(100,100,70,0,Math.PI);   // Mouth
    smileCtx.stroke();

    smileCtx.beginPath();
    smileCtx.fillStyle = 'black';
    smileCtx.moveTo(60, 65);
    smileCtx.arc(60,65,12,0,Math.PI*2);  // Left eye
    smileCtx.fill();

    smileCtx.beginPath();
    smileCtx.moveTo(140,65);
    smileCtx.arc(140,65,12,0,Math.PI*2);  // Right eye
    smileCtx.fill();

This gives us a more iconic version of our smiley face, as shown in Figure 4-6.

The same canvas smiley face with a yellow fill on the head circle
Figure 4-6. The same canvas smiley face with a yellow fill on the head circle

In order to accommodate the introduction of color, we had to make a few changes to our code. First, we extracted the mouth from the same stroke that made the head so that the fill would not overwrite the line used for the mouth. Then we added a fill method to the end of the head circle to color it yellow. The last change we made was to reset the fill color back to black for the eyes. Again, once we set the style, we needed to reset it to black to return to the default value.

Now, to prove that we have some artistic talent, we will change our yellow color to a yellow gradient. We can apply two types of gradients:

createLinearGradient(x1,y1,x2,y2)
createRadialGradient(x1,y1,r1,x2,y2,r2)

The createLinearGradient method is passed four different arguments: the start point (x1,y1) and the end point (x2,y2) of the gradient.

The createRadialGradient method is passed six arguments. The first three define an inner circle with coordinates (x1,y1) and one radius (r1) and an outer circle with coordinates and a second radius.

Our example will use a radial gradient to give our smiley face three-dimensional depth. First we will set our gradient to a variable, and then we will add a series of color stops to the gradient. In our code example, we’ll replace the fillStyle with our gradient:

    var mySmile = document.getElementById('mySmile')
    var smileCtx = mySmile.getContext('2d');

    var radgrad = smileCtx.createRadialGradient(100,100,10,100,100,100);
    radgrad.addColorStop(.5, 'rgba(247,241,192,1)');
    radgrad.addColorStop(1, 'rgba(244,225,56,1)');
    smileCtx.beginPath();

    smileCtx.fillStyle = radgrad;
    smileCtx.arc(100,100,99,0,Math.PI*2); // head

    smileCtx.stroke();
    smileCtx.fill();

    smileCtx.beginPath();
    smileCtx.moveTo(170,100);
    smileCtx.arc(100,100,70,0,Math.PI);   // Mouth
    smileCtx.stroke();

    smileCtx.beginPath();
    smileCtx.fillStyle = 'black';
    smileCtx.moveTo(60, 65);
    smileCtx.arc(60,65,12,0,Math.PI*2);  // Left eye
    smileCtx.fill();

    smileCtx.beginPath();
    smileCtx.moveTo(140,65);
    smileCtx.arc(140,65,12,0,Math.PI*2);  // Right eye
    smileCtx.fill();

We have simply replaced our fill color with the gradient as a fill. This gives us the added depth we want to make our smiley face stick out from the crowd (see Figure 4-7).

The smiley face canvas drawing with a gradient in place of a solid fill color
Figure 4-7. The smiley face canvas drawing with a gradient in place of a solid fill color

Additional Styles

You can accomplish a transparency effect with a color of your choosing, or you can apply the transparency globally to a stroke. To adjust the transparency level, use the globalAlpha method:

globalAlpha = .2;

Unlike the color styles, the globalAlpha method only applies to the current stroke. Once a new stroke is started, the globalAlpha method resets to 1.

Because they play such a large role in illustrations, lines are given additional control values in your <canvas> tag. You can set the following values for a stroke on your <canvas> tag:

lineWidth

A numerical value that represents the width in points

lineCap

The shape of the end of a line, which can be declared as butt, round, or square

lineJoin

The shape of a line joint, which can be declared as round, bevel, or miter

miterLimit

Determines how far the outside connection point can be placed from the inside connection point, when the lineJoin type of miter is selected

Patterns and shadows can also be applied to canvas elements, and they follow similar syntax to CSS implementations. For details on these features and more, see the W3C specification on the <canvas> tag.

  • Safari Books Online
  • Create BookmarkCreate Bookmark
  • Create Note or TagCreate Note or Tag
  • PrintPrint