You’ve seen how canvas can set different stroke and fill styles, and I mentioned that those styles can be any valid CSS color string (e.g. green or rgba(100, 100, 100, 0.3)). In addition, canvas can define gradient and pattern objects that can be used to fill and stroke paths.
Gradients
Canvas can create both linear and radial gradients:
• Context.createLinearGradient(x, y, x1, y1): Creates a linear gradient starting at coordinates (x, y) and ending at coordinates (x1, y1). Returns a Gradient object that can be used as a stroke or fill style.
• Context.createRadialGradient(x, y, r, x1, y1, r1): Creates a radial gradient consisting of two circles, the first one centered at (x, y) with radius r, and the other centered at (x1, y1) with radius r1. Returns a Gradient object that can be used as a stroke or fill style.
• Gradient.addColorStop(position, color): Adds a color stop to the Gradient. The position parameter must be between 0 and 1; it defines the relative position within the gradient of the color stop. You can add as many color stops as you want to a particular Gradient.
Listing 4-8 shows a simple three-stop gradient being used to stroke rectangles.
Listing 4-8. A Three-Stop Gradient
<!DOCTYPE html>
<html>
<head>
<title>The HTML5 Programmer's Reference</title>
<style>
<canvas id="myCanvas" width="200" height="200">Did You Know: Every time you use a browser that doesn't support HTML5, somewhere a kitten cries. Be nice to kittens, upgrade your browser!
</canvas>
<script>
// Get the context we will be using for drawing.
var myCanvas = document.getElementById('myCanvas');
var myContext = myCanvas.getContext('2d');
// Create a gradient object and add color stops.
var myGradient = myContext.createLinearGradient(0, 0, 200, 200);
myGradient.addColorStop(0, '#000');
myGradient.addColorStop(0.6, 'green');
myGradient.addColorStop(1, 'blue');
// Set the stroke styles and stroke some rectangles.
myContext.strokeStyle = myGradient;
This example creates a linear gradient object and adds three color stops to it, then uses it as the stroke style for two rectangles. The results are shown in Figure 4-7.
Figure 4-7. A linear gradient
Patterns
Canvas also supports the concept of a pattern as a fill or stroke style:
• Context.createPattern(Image, repeat): Creates a Pattern object that can be used as a fill or stroke style. The Image parameter must be any valid Image (see “Images” section, next, for details). The repeat parameter specifies how the pattern image is repeated.ust be one of the following:
• repeat: Tiles the image both horizontally and vertically.
• repeat-x: Repeats the image only horizontally.
• repeat-y: Repeats the image only vertically.
• no-repeat: Does not repeat the image at all.
Listing 4-9 illustrates using a simple image as a pattern.
Listing 4-9. Creating a Pattern
<!DOCTYPE html>
<html>
<head>
<title>The HTML5 Programmer's Reference</title>
<style>
canvas {
border: 1px solid #000;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="200" height="200">Did You Know: Every time you use a browser that doesn't support HTML5, somewhere a kitten cries. Be nice to kittens, upgrade your browser!
</canvas>
<script>
// Get the context we will be using for drawing.
var myCanvas = document.getElementById('myCanvas');
var myContext = myCanvas.getContext('2d');
// Create a new image element and fill it with a kitten.
var myImage = new Image();
myImage.src = 'http://www.placekitten.com/g/50/50';
// We can't do anything until the image has successfully loaded.
myImage.onload = function() {
// Create a pattern with the image and use it as the fill style.
var myPattern = myContext.createPattern(myImage, 'repeat');
myContext.fillStyle = myPattern;
myContext.fillRect(5, 5, 150, 150);
};
</script>
</body>
</html>
This example creates a new image element and sets its URL to a placeholder image service. You have to wait for the image to finish loading before continuing, so you attach an onload event handler to it, in which you create the pattern and use it as the fill style for a rectangle.
The results look as cute as you would expect, as shown in Figure 4-8.
Figure 4-8. A kitten as a pattern
Images
The canvas element can also load and manipulate images. Once an image is loaded into a canvas, you can also draw on it with the drawing commands.
The canvas element can use these sources for images:
• an img element,
• a video element, and
• another canvas element.
Canvas has one method for drawing images, but it can take many different parameters and thus has multiple capabilities:
• Context.drawImage(CanvasImageSource, x, y): Draw the image from CanvasImageSource at the coordinates (x, y).
• Context.drawImage(CanvasImageSource, x, y, width, height): Draw the image at coordinates (x, y), scaling the image to the specified width and height.
• Context.drawImage(CanvasImageSource, sliceX, sliceY, sliceWidth, sliceHeight, x, y, width, height): Slice the area from the image specified by the rectangle starting at (sliceX, sliceY) with sliceWidth and sliceHeight, and then draw that slice on the canvas at (x, y), scaling the slice to the specified width and height.
Listing 4-10 demonstrates the basic functionality of drawImage.
Listing 4-10. Drawing an Image on a Canvas
<!DOCTYPE html>
<html>
<head>
<title>The HTML5 Programmer's Reference</title>
<style>
canvas {
border: 1px solid #000;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="200" height="200">Did You Know: Every time you use a browser that doesn't support HTML5, somewhere a kitten cries. Be nice to kittens, upgrade your browser!
</canvas>
<script>
// Get the context we will be using for drawing.
var myCanvas = document.getElementById('myCanvas');
var myContext = myCanvas.getContext('2d');
// Create a new image element and fill it with a kitten.
var myImage = new Image();
myImage.src = 'http://www.placekitten.com/g/150/150';
// We can't do anything until the image has successfully loaded.
myImage.onload = function() {
myContext.drawImage(myImage, 25, 25);
};
</script>
</body>
</html>
In this example all you’re doing is creating a new img element of a placeholder image. Once the image is loaded, draw it on your canvas, as shown in Figure 4-9.
Figure 4-9. An image drawn in a canvas
Listing 4-11 demonstrates scaling an image on a canvas.
Listing 4-11. Image Scaling with Canvas
<!DOCTYPE html>
<html>
<head>
<title>The HTML5 Programmer's Reference</title>
<style>
canvas {
border: 1px solid #000;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="200" height="200">Did You Know: Every time you use a browser that doesn't support HTML5, somewhere a kitten cries. Be nice to kittens, upgrade your browser!
</canvas>
<script>
// Get the context we will be using for drawing.
var myCanvas = document.getElementById('myCanvas');
var myContext = myCanvas.getContext('2d');
// Create a new image element and fill it with a kitten.
var myImage = new Image();
myImage.src = 'http://www.placekitten.com/g/50/50';
// We can't do anything until the image has successfully loaded.
myImage.onload = function() {
myContext.drawImage(myImage, 25, 25, 50, 150);
};
</script>
</body>
</html>
This example gives you a 100px by 100px placeholder, but when you draw it on the canvas, you scale it to be 50px × 150px, as shown in Figure 4-10.
Figure 4-10. Scaling an image in canvas
Finally, Listing 4-12 shows slicing a larger image and scaling the slice on the canvas.
Listing 4-12. Slicing and Scaling an Image on canvas
<!DOCTYPE html>
<html>
<head>
<title>The HTML5 Programmer's Reference</title>
<style>
canvas {
border: 1px solid #000;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="200" height="200">Did You Know: Every time you use a browser that doesn't support HTML5, somewhere a kitten cries. Be nice to kittens, upgrade your browser!
</canvas>
<script>
// Get the context we will be using for drawing.
var myCanvas = document.getElementById('myCanvas');
var myContext = myCanvas.getContext('2d');
// Create a new image element and fill it with a kitten.
var myImage = new Image();
myImage.src = 'http://www.placekitten.com/g/300/300';
// We can't do anything until the image has successfully loaded.
myImage.onload = function() {
myContext.drawImage(myImage, 25, 25, 150, 150, 0, 0, 150, 50);
};
</script>
</body>
</html>
Here you are loading a 300px × 300px placeholder image, but slicing only a 75px × 75px portion of it starting at (25, 25). Then you’re taking that slice and rendering it in the canvas, scaling it to be 150px × 50px.
The result is rather distorted, as Figure 4-11 shows.