navigate site menu

Start learning with our library of video tutorials taught by experts. Get started

HTML5: Graphics and Animation with Canvas

HTML5: Graphics and Animation with Canvas

with Joe Marini

 


One of the most exciting additions that HTML5 offers to designers is the ability to draw free-form graphics on a drawing surface known as the Canvas. In this course, author Joe Marini introduces the technical concepts behind Canvas and shows how to perform drawing operations directly in a web page. The course covers drawing basic and complex shapes, setting colors and styles, adding shadows, patterns, and gradients, more advanced techniques such as scaling, rotating, and compositing objects, and how to incorporate Canvas elements in a slideshow and an animation.
Topics include:
  • Understanding the differences between Canvas and SVG Graphics
  • Drawing shapes
  • Drawing arcs and paths
  • Rendering text
  • Using clipping paths
  • Drawing images and video
  • Transforming objects with the translate tag
  • Manipulating raw pixels
  • Applying a custom transformation
  • Creating an animation or slideshow control with Canvas

show more

author
Joe Marini
subject
Web, Animation, Web Design, Web Development
software
HTML
level
Intermediate
duration
3h 7m
released
Jun 03, 2011

Share this course

Ready to join? get started


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Welcome
00:03Hi! I'm Joe Marini, and I'd like to welcome you to HTML5: Graphics and Animation with Canvas.
00:08In this course, we're going to learn about the new canvas element, which brings
00:12sophisticated graphics capabilities to HTML5-based web pages.
00:16First, we'll take a look at some real-world web sites that are using the
00:20canvas element today.
00:21I'll show you how to incorporate a canvas element into your page and draw
00:25basic graphic elements.
00:27Then we'll move on to more advanced drawing features like gradients, patterns,
00:31and transformations.
00:33I'll walk you through creating a canvas-based animation from start to finish.
00:37And finally, we'll see how incorporate a canvas-based solution into a real web
00:41site using free tools available on the web today, such as jQuery and modernizr.
00:46With the HTML5 canvas element, Web developers finally have many of the same
00:51advanced graphics capabilities at their fingertips that native application
00:55developers have had for years.
00:57So if all that is enough to get you excited, then let's get started with HTML5:
01:01Graphics and Animation with Canvas.
Collapse this transcript
Using the exercise files
00:00If you are a Premium member of the lynda.com Online Training Library, or if
00:05you're watching this tutorial on a DVD-ROM, you have access to the exercise
00:08files used throughout this course.
00:11So let me show you how they're laid out.
00:12Here we are in the Exercise Files folder.
00:14The way I have laid it out is each folder is named with a two-digit number at
00:19the beginning, and that corresponds to the chapter that we're currently
00:22looking at in the course.
00:24And the name that follows the number is just a little hint of what's contained inside.
00:29So if we open up one of these chapters, you'll see that way I've laid out each
00:33example file, there's two versions of each file:
00:35there's a finished version and there's a start version.
00:37The finished version is the particular tutorial in its finished state.
00:42That's what I'll be showing at the end of each one of the tutorials.
00:45The start version is the same as the finished version but with key pieces of code removed.
00:50And what we'll do is any tutorial, we'll start with the starting point, add the
00:54code until we reach the same point as the finished version.
00:56So you really have your choice:
00:58you can either open up the finished version and see how things work and run it
01:01for yourself, or you can follow along with me as we build the start version
01:05until it reaches the finishing point.
01:08In addition to each one of the tutorials, I've also included a file
01:11called ExampleSnippets.
01:13Let's go to the code editor and see what that looks like.
01:15This is the snippets file that I've included for this course.
01:17So each one of these chapters has various code snippets that I add to the
01:22starting point for each one of the tutorials.
01:25This way, I just simply copy the code and paste it into the starting point, so
01:28you don't have to sit there and watch me type.
01:30So I'll be doing things like copying this piece of code, putting it into the
01:34starting point, showing it in the browser, and so on.
01:37Now this ExampleSnippets file, you'll have access to this as a free downloadable
01:42tutorial file directly from the online course page, even if you're not a Premium
01:46member of the lynda.com Online Training Library.
01:50If you are a Monthly subscriber or Annual subscriber to lynda.com, you don't
01:54have access to the exercise files, other than that ExampleSnippets file that I just showed.
01:58But you can follow along from scratch with your own assets. All right!
02:01Let's get started.
Collapse this transcript
Using the HTML5 Canvas element in the real world
00:00Since the canvas tag is new to HTML5, there are going to be browsers out there
00:04that don't support it.
00:05So let's take a quick look at what happens when a browser that is not aware of
00:09the canvas tag encounters one in a document.
00:12So here we have a canvas, and inside we have some text.
00:17Now in browsers that understand what the canvas tag is, this text will not show
00:22up and will instead be replaced by the canvas itself in the rendering surface.
00:27A browser that does not understand the canvas tag will ignore it and render the
00:31contents of the interior of the canvas tag instead.
00:34In this case, let's just quickly show you what I'm talking about.
00:38What I'm going to do is simulate a browser that does not understand canvas, since
00:42all the browsers I have on this machine know about it.
00:44So I'll just quickly comment this out and will comment this one out as well.
00:52This is pretty much how the browser will treat the canvas tag if it
00:55doesn't recognize it.
00:56So now let's just quickly take a look at that.
00:58So you can see that in the case where a browser doesn't know what the canvas tag
01:04is, the interior text gets rendered instead.
01:07So that will happen in cases where you have an older browser and it comes across
01:12a canvas tag, or generally speaking, pretty much any tag it doesn't recognize.
01:16But in the case where the browser does understand what the canvas tag is--
01:20let's go back and uncomment it, save--and you can see that I've got a
01:29style defined for this canvas up here with a dotted 3-pixel black border
01:33and a background color.
01:34So it should render as a gray square with a border.
01:37Let's go back to the browser and refresh.
01:40So I am going to refresh this now, and you can see that in a browser that does
01:43understand the canvas tag, it does show up, and it's properly styled.
Collapse this transcript
1. Examples of Current HTML5 Sites
Real-world example: CanvasMol
00:00Before we get into working with canvas in the rest of the course, let's take a
00:04look at some of the real-world examples that people have built using canvas to
00:10achieve effects and drawing operations that used to require native plug-ins like
00:15Silverlight and Flash but can now be done using modern browsers and HTML5.
00:20This example is called canvasMol.
00:22It's on a web site called alteredqualia.com.
00:25Basically, this shows how canvas can be used to model molecules on a drawing surface.
00:30So let's take a look at some ones.
00:31Here's one of my favorite ones; here's Caffeine.
00:33So you can see that what's happening here is when I click on a molecule over
00:37here in this list, this canvas drawing surface pops up and it shows me the
00:41molecule for that particular item.
00:44In this case, this is the caffeine molecule.
00:46I can use the mouse to grab this thing and move it around.
00:50And I can choose some other ones.
00:52Here's one, Fructose, another one of my favorites.
00:55So you can see now I bring up another canvas, the frame rate slows down a little
00:59bit because this drawing is happening in real time, and the more canvases you
01:04have on the drawing surface, the more processing power it takes.
01:08So let's add another one little one.
01:09Let's add Lycopene, and then we can scroll down and see that.
01:13That's a pretty fairly complex molecule, but you get the idea here.
01:16What's happening is the canvas is being used to render each one of these
01:20molecular bonds with individual atoms.
01:22You can see that they're all shaded a certain way, and they're rotating.
01:27Each one of the canvases responds to the mouse.
01:31And we can add one more over here from the list.
01:34Let's go ahead and add Penicillin.
01:36So I can just go ahead and add each one of these in succession, and what's
01:39happening is a new little window is being popped up with the canvas inside of it.
01:44And you can see that each one of the canvases is now drawing each molecule
01:48rotating in real time.
01:49Each one responds to the mouse.
01:51You can see that as I add more canvases, the drawing rate slows a little
01:54bit, but not very much; it's still highly usable.
01:56Each one is still also pretty responsive.
01:59So this is a really great example of something that would've probably required a
02:02plug-in in the past but is now just happening natively using canvas in HTML5.
Collapse this transcript
Real-world example: Raphaƫl-JavaScript Library
00:00So, canvas is used for a lot more than just wizzy graphical effects.
00:04This is the Raphael JavaScript library.
00:07This is used for charting.
00:08And it can create charts using both canvas and a technology called SVG, which we
00:13are not covering in this particular title, but it can do both. So let's take a
00:17look at what it does.
00:18You can see down here, I will just go down to the Demo section.
00:20These are all examples of the kinds of things you can do with the Rafael Drawing Library.
00:26Let's take a look at this one right here.
00:28This one shows example of a graph that's showing data for particular months.
00:32And you can see, as I switch among the months, the chart is changing to show
00:38various different data sets, and you can see that there is a little animation
00:42step that happens in there.
00:43Let's go back to the first one.
00:45Here is a really cool example called a Polar Clock, and this is using canvas to
00:50draw a clock that is drawn using circles.
00:53So, you can see each one of these rings is color-coded and the color-coded rings
00:57correspond to the text up here.
00:58So the blue ring is the hours, the gray is the minutes.
01:02You can see the second hand is out here. Then the date is shown in the two
01:06interior rings in different shades of green.
01:08So, it is now April 26 and you can see that this clock is just an interesting
01:13way of using the canvas to draw something that we take for granted every day,
01:17such as clocks on the wall.
01:18And let's take a look at one more example.
01:20This here is an example of using the canvas to rotate a pre-drawn image.
01:26This is an actual JPEG image that's drawn onto the canvas, and using these
01:30controls, I can rotate it.
01:32You can see that there is little animation that goes along that as well.
01:36You can see, it starts off slow, speeds up, and then slows down, using easing.
01:40These are all kind of things that used to require plug-ins and are now provided to
01:44you as part of canvas in HTML5.
Collapse this transcript
Real-world example: The Wilderness Downtown
00:00A really great example of using HTML5 canvas to produce some really cool effects
00:04is a site called thewildernessdowntown.com.
00:08And this is a pretty immersive site built by Arcade Fire and some other folks.
00:14I am running this in Google Chrome.
00:15It's actually pretty cool!
00:17You type in the address of a place and then the site builds a sort of
00:23customized music video around the location you give it, complete with some
00:28interesting HTML5 canvas effects.
00:30You can see the birds are being chased away by my mouse over here.
00:33That's actually pretty cool.
00:34All this is HTML5 that you are seeing right now.
00:36So, let's give it an address, and I'm going to use the address of lynda.com's
00:45recording studio, and we are here in beautiful Ventura, California.
00:50I am going to click Search.
00:51Okay, so now it's going to go build out that music video.
00:55Right, we are ready to go, so we can play the film.
00:57So, now as you're watching the movie, I am going to point out some of the canvas
01:01effects that are happening.
01:02(music playing) First, you see the video come up.
01:06(video playing)
01:13This is being accomplished right now via HTML5 video.
01:16(video playing)
01:34So, now here is an example of the canvas being used to draw the birds flying
01:40around the sky up there, those guys right here.
01:44You can see they are still responding to my mouse. (video playing)
01:47(video playing)
02:04So, now here is the combination.
02:06We have a video that's using an image that's been pulled from the Google Earth service.
02:12Those birds you see being drawn there are drawn using HTML5 canvas and you can
02:19see that there are various windows coming and going.
02:28This is the HTML5 canvas being used to render an image.
02:32You saw it there, and it was faded out a little bit to make it look
02:34like it was a bit old.
02:35You can see the effect over there.
02:39So, the colors have been sort of washed out a little bit using the canvas effects.
02:42(video playing)
02:54You can see the image is now being rotated.
02:57There is some more canvas with our location.
03:08You can see that as he's turning around the video down there,
03:10it is synchronized with the video up top.
03:12(video playing)
03:38That's pretty much it. That's a pretty great use of canvas.
03:42You can see here that at the end it gives you an opportunity to write a little
03:45postcard to yourself and the contents here are drawn using HTML5 canvas, really
03:51great example of using canvas technologies to augment existing media, like video
03:56and audio and different windows, and just a nice immersive experience.
Collapse this transcript
Real-world example: Sketchpad
00:00Another really great example of using HTML5 canvas to accomplish things that
00:04used to require native applications is Sketchpad.
00:08And you can see the URL up there is mugtug.com/sketchpad.
00:12This is a drawing application created using HTML5 canvas, and I'm going to just
00:17do some stuff, like I can select the ellipse, and I can draw the ellipse on the
00:21canvas here, and I can use the brush and I can draw things.
00:25And you can see that I've got various settings in these windows down here.
00:28So, I can change all kinds of things. I can change colors.
00:37I can even do advanced operations like cropping.
00:39So, this is a cropping tool.
00:41I am going to drag out a little cropping rectangle here and hit Enter, and you can
00:47see that by using the canvas, I'm able to grab subsets of images that have been
00:51drawn, draw them in to entirely new canvases.
00:55This is actually a really powerful application.
00:57You can see also up here I have other windows I can drag out. So this is a
01:00great example of something that used to require a native application to do and
01:05it's been implemented entirely using canvas and HTML5 technologies.
Collapse this transcript
Real-world example: Pirates Love Daisies
00:00Okay, the next example we are going to look at is Pirates Love Daisies.
00:03Pirates Love Daisies is a game that was produced using just HTML5 canvas and
00:10native web technologies.
00:12You've probably seen games like this before.
00:13It's a classic tower defense game where you have to defend something against a
00:18wave of oncoming bad guys, probably something along the lines of Plants Versus
00:23Zombies is a pretty famous one.
00:25In this case, you are the pirates, and there's a group of mean sea creatures that
00:29are trying to come and steal your daisies, and that's the premise of the game.
00:32So, I am just going to go ahead and click start the game.
00:34And all this is done using canvas, so I am just going to go and click a map, and
00:38I am going to click Play.
00:38So, now down here on my people, I am going to click on a pirate and I am going
00:43to choose an anchor point to put them.
00:45And so you can see that there's my pirate. I am going to go ahead and upgrade
00:49Scarlett and Scarlett is going to make quick work of the rats that are coming in to
00:53try and take my daisies. Maybe I'll put Inigo up there.
00:59You can see that this game, it's pretty advanced.
01:01It was created using a JavaScript library called Easel, like an artist
01:04drawing easel, Easel.js.
01:07And it's a pretty great little game.
01:09The pirates are defending the daisies up here.
01:11This is just implemented using canvas.
01:13This is HTML5 canvas using native web technologies.
01:16There's no Silverlight here.
01:18There is no Flash involved, and it's a pretty good example of what you can
01:21do using canvas.
Collapse this transcript
2. Setting Up Your Workspace
Installing the tools
00:00Before we can begin working with the HTML5 canvas, we first have to make sure
00:04that we have the right tools installed.
00:07You're going to need to have some browsers installed to test with, and you can
00:10see over here I've got Firefox, and Chrome, IE, Opera, and Safari.
00:16You can get those browsers from their respective browser download pages.
00:21Make sure you have IE of at least version 9, because that's the version of IE
00:25that supports the canvas tag. And in addition to the browsers that you are going
00:29to need to test out your results in, you will need to have a text editor to edit
00:34the HTML and JavaScript code that we'll be working with.
00:38Now you can use any code editor you want to--
00:41You probably already have your favorite code editor for your platform.
00:44However, I'm going to be using a product called Aptana Studio in this course,
00:50and this is the web site where you can download it from.
00:52If you just go to aptana.com, you'll see that there's a products link, and
00:57that's this right here.
00:58You can download Aptana Studio.
01:00The reason I'm using Aptana Studio is because it is cross-platform--
01:04it works on both Mac and Windows--and it's free.
01:08So again, you can use whatever code editor you want.
01:11I just happened to be using Aptana, and once you've downloaded and installed it,
01:15this is what it looks like.
01:16No big surprises here.
01:18It pretty much works the same way as any other IDE does.
01:21So once you have your browsers and code editor installed, we can go ahead and
01:25get started learning how to use the HTML5 canvas.
Collapse this transcript
Exploring the Canvas examples used in this course
00:00The HTML5 canvas provides a lot of drawing operations to learn about.
00:04So what I'm going to do first is show you a quick overview of the kinds of
00:08things that we're going to learn how to do in this course.
00:11So using HTML5 canvas, we'll learn about how to draw lines, and you can see this
00:15is the example here.
00:16This is the actual finished example that we're going to build. And you can see
00:20that we can draw lines of varying thickness with different end caps and
00:23different kinds of joins.
00:25We'll see how to draw arcs. And again, these are the finished examples that
00:28you're going to be able to build when you've watched that particular section.
00:32So here we do have some arcs. Some of them are filled.
00:36We can draw text in the canvas using various effects.
00:39We've got some colors, and sizes, and stroking and filling going on, We'll see
00:43how to do things like draw shadows, so these are objects that have shadows with them.
00:49You can see that the shadow color and blur effect can be changed depending on
00:53the type of object that you're drawing.
00:55We'll also see how to do things like draw gradients, both linear gradients, as
01:00in this example, and radial gradients.
01:02Then we'll move on to some more advanced stuff, like seeing how the canvas can
01:06draw using different compositing methods.
01:09These compositing methods affect how objects are drawn to the canvas, and there
01:13are twelve of them and you can see the examples here. And again, you'll be
01:16building this later on in the title.
01:17Then we will see how to use things like transformations to move objects around
01:22on the canvas and affect how they are drawn.
01:25And you can do things like rotate and scale and translate.
01:28This is the rotate one.
01:29We'll see how to do this later.
01:30Then we move on to some more advanced operations.
01:33I'll show you how to build animations like this one, where we have a box
01:37moving across a blue canvas, and we'll build something a little more advanced than that even.
01:42We'll build a nice little slideshow rotator.
01:45You can see that this is rotating through some pictures that are being drawn to a canvas.
01:50So these are the examples that we're going to be building, and you might want
01:54to fire up your code editor, because we're going to just dive right in and
01:57start building stuff.
Collapse this transcript
3. Introducing the Canvas Element
Introducing the Canvas tag
00:00Let's begin by introducing the canvas element.
00:03The canvas element provides web pages with a place where they can draw free-
00:07form graphics of all kinds: shapes, images, text, lines, all kinds of objects.
00:13Just think if it as a piece of paper on the page where your script code can
00:16just draw anything it wants.
00:18The canvas tag is supported in all of the latest browsers, and I have listed them here.
00:23So as long as you have a modern version of that particular browser, it should
00:27support the canvas tag.
00:29Now, browsers that don't support canvas can display fallback content.
00:33So if you have a browser that doesn't understand what a canvas is, you can place
00:37content inside the canvas tag that will be displayed to the user when their
00:41browser tries to render it.
00:42Pages can actually have more than one canvas and in fact, you can even overlap them.
00:46One of reasons why you might do this is because canvases can be set to be transparent.
00:51So you might have one canvas that contains say the background for a game and another
00:55canvas that has the characters in the game and so on and so forth, and you can
00:59position them on top of each other.
01:01So you can have more than one canvas, and it might come in handy to have
01:03more than one canvas.
01:04Now it's important to know that canvas contents are created on the fly using script.
01:10Now what this means is once you've drawn stuff onto the canvas, there is no
01:14going back to get it again; it doesn't become part of the page DOM.
01:17So the bits are on the screen, and if you want to remember them, you have to
01:21care of it yourself.
01:22Once they're drawn, they are just forgotten about by the script engine.
01:25They're good for dynamic visual media, but the canvas is not good for things
01:30that you might want to manipulate later using script, and that's what SVG is
01:35for, and we'll take a little bit of a peek at that later.
01:37Let's take a look at the canvas tag.
01:39The canvas coordinate system starts at the upper left, and it has two axes with
01:45increasing values of X going from the left to the right and the Y axis going
01:48from top to the bottom.
01:50All canvas element start out invisible, and that means that they are a
01:53transparent black background.
01:55So, there is the black canvas with the opacity set all the way down to 0,
01:59so they can't be seen.
02:00This graphic shows you what the coordinate system looks like.
02:03So on the left-hand side there we have the Y axis, increasing in values from top to bottom.
02:08We have the X axis going from left to right, and we have 0, 0 point up there in
02:12the corner, and the width and height down on the lower right.
02:16The canvas tag is declared using the word 'canvas', and you typically provide it
02:20with an ID, because you'll be accessing it from script, and a width and a height.
02:24And that Fallback content you see there inside the canvas tag is what will be
02:28displayed to the user if a browser does not understand what a canvas is.
02:33Canvases come along with some attributes and functions as well, and here they are.
02:38There is a width and a height, which defined the width and the height of the
02:41canvas, and there is a couple of methods.
02:43There is toDataURL and the getContext.
02:46So let's take a look at each one of those.
02:48The width and the height properties are pretty much self-explanatory.
02:51They are the width and the height of the canvas, and if you don't define them,
02:55they default to 300 wide by 150 height.
02:58And it's important to note that, as well as getting the values of these
03:02properties, they can be set.
03:04So you can dynamically change the width and the height of the canvas from your code.
03:09The toDataURL method takes the contents of the canvas and makes a static image
03:14out of them as a data URL.
03:17Now to do this, you pass in the type of image you want the toDataURL method to
03:22create, such as image/png, and that support is mandatory according to the W3C
03:28spec. But some browsers may choose to support other formats like image/jpeg, or
03:34image/gif that kind of thing.
03:36So this method basically takes the contents and gives you back a Base64 encoded
03:41data URL of the contents.
03:44The getContext method is probably the more important ones.
03:47It retrieves the drawing context for the canvas, and the drawing context
03:52contains information about the canvas and provides all of the methods you use to draw with.
03:58Things for setting colors and stroke styles and drawing shapes and so on, all of
04:03that is done using the context.
04:06So, let's actually switch over to our code editor and build our first canvas.
04:10Okay, so here I am in Aptana Studio and I'm going to open up the example files.
04:16So if you go into the Exercise Files folder, I'm going to go into the folder for
04:20this lesson and open up the start. This is our Firstcanvas_start.html.
04:27I'm also going to open up my snippets file, and I'll be referring to this
04:33throughout this course.
04:34Essentially, this file contains all the code snippets for each one of the
04:38examples in order to go from the start state to the finished state, and I'm
04:41going to use these so that you guys don't have to watch me type.
04:44And if you have access to this file, you can follow along with me in your own code editor.
04:48So what we're going to first do is put a canvas into this document.
04:51I am going to put it right here in the body.
04:53So I'll go to the Snippets, and I'll take this canvas and I'll paste it in. So let's save.
05:00So here is the canvas tag, here's it's ID, and I've got a width and a height on there.
05:05And here is the fallback content right there.
05:08It just says, "Your browser does not support canvas."
05:10All right, let's take a look at this in the browser.
05:14So we'll go out here.
05:15I am going to double-click, and you can see that nothing shows up.
05:18Remember, I said that canvases all start out as invisible.
05:22So we need to do something to make this canvas visible.
05:24Let's go back into the code.
05:25I am going to go back to my snippets and I'm going to copy this style
05:29declaration right here.
05:30And just like other HTML elements, you can define styles that affect canvas tags.
05:37So I am going to copy this and go back to my source and paste that here in the head section.
05:44So I've defined a style for the canvas with this ID--
05:48that's this guy right here--and it has a border which is a dotted 3-pixel black
05:54outline and a light gray background-color.
05:57So let's save, and let's go back to the browser, and let's refresh.
06:01Okay, now you can see that the canvas is visible, so it has a dotted border here,
06:07and the background is light gray.
06:09So let's see how this looks in another browser. This is IE.
06:14Let's open this up in Firefox, and you can see it looks the same.
06:19Now we know how to declare a canvas tag.
06:21We know how to style it and make it visible.
06:23Let's take a look at how canvas compares to SVG, and then we'll move in to
06:28some actual drawing.
Collapse this transcript
Understanding the differences between Canvas and SVG
00:00Let's take a look at how canvas compares to SVG, or Scalable Vector Graphics.
00:05SVG is another way of drawing content into web pages.
00:10It's similar to the canvas, but it works in a pretty different fashion.
00:14So let's compare the two.
00:16Canvas has elements that are drawn programmatically.
00:20In other words, your script code draws elements directly onto the canvas surface.
00:25In SVG, the elements are actually a part of the page's DOM, or Document Object Model.
00:32In SVG, when you have a shape, say a rectangle or an arc or some kind of
00:36curve, that's actually a tag that is in the document.
00:40Your script can refer to it in the DOM.
00:42You can manipulate it.
00:43You can't do that in canvas.
00:44Once something is drawn to the canvas, the browser forgets all about it.
00:48It just puts the bits onto the canvas and then moves on to the next operation.
00:52In canvas, drawing is done with pixels, whereas in SVG drawing is all done with vectors.
00:59Vectors are lines that are determined by start points and end points and curves,
01:04and on the canvas that's how you do it.
01:06You actually put pixels directly onto the canvas surface.
01:09Canvas does not have animations built into it, whereas SVG does.
01:15In the canvas, when you want to create animations, you have to do that
01:18using script and timing mechanisms, which we will see how to do later on in this course.
01:23In SVG, basic animations, such as moving objects around, all that stuff is built in.
01:28Canvas is pretty high performance for pixel-based drawing operations, whereas
01:34SVG is based on a standard XML syntax.
01:38So where canvas gets a little bit better performance because it can take
01:40advantage directly of your computer's hardware accelerated GPU, or
01:45Graphics Processing Unit,
01:46SVG uses XML which might be a little bit slower to process, but it provides
01:51better accessibility, because again, the elements of the drawing are part of the DOM.
01:57So this is a pretty complete basic look at how the two are different, but keep
02:03in mind they're not mutually exclusive.
02:05You can use canvas and SVG in the same web page.
02:09And because you can position elements, you might even find a way to use the two
02:13of them together, have a canvas in the background and SVG on top.
02:17Now what you can't do is draw SVG into a canvas or vice versa, but just
02:23remember, they're not mutually exclusive.
02:25You can actually use both.
Collapse this transcript
4. Understanding the Canvas Element and 2D Drawing API
Identifying the Canvas element's methods and properties
00:00We've seen how to declaratively create a canvas in HTML.
00:04In this example, let's see how we can use script to affect how canvas looks on the browser.
00:10So I'm going to open up my example file, and in my exercise files, and I'm in
00:15chapter 04, and we'll open up contextprops_start, and you can see we've got some
00:20code we need to write.
00:21Let's go and take a look at this in the browser really quick.
00:24So I'll bring this up in IE, and you can see there's a dotted outline.
00:29There is no background color here, just the outline, and what we're going to
00:32do is write some code that will affect how the canvas tag itself is displayed in the browser.
00:38So let's go back to the code and over in my snippets, I'm going to copy the
00:43three lines under the ContextProps section, so we'll copy those and we'll put
00:48them in here, in the window.onload function.
00:52So what we're doing here is when the window loads, we've got some code that's
00:56going to get a reference to the canvas element by calling getElementById, and
00:59that's thus canvas right here.
01:01And then we're going to programmatically change the width and height from 400
01:05and 300, which are the defaults, down to 150 x 150. So we save this and then when we
01:12go back to the browser. Now when I refresh this, you can see that the canvas got
01:18a little bit smaller.
01:20So this shows us how we can programmatically display the canvas using different
01:25properties, just the same way that we can do it from HTML.
01:28Now in HTML, we can give it attributes that affect how the canvas is displayed
01:32initially, but once that height and width is defined in HTML, we can still go
01:37back and code and programmatically affect them.
Collapse this transcript
Using the Canvas drawing context
00:00To actually draw things onto the canvas, we need to use the canvas's 2D drawing
00:05API and to do that, let's take a look at how it works.
00:09Now drawing on a canvas requires a series of steps.
00:13And in step one, we need to retrieve a reference to the canvas; in other words,
00:17we have to actually get the canvas element out of the page.
00:20Once we've got a reference to the canvas element, we get the drawing
00:24context from it using the getContext () method that we talked about a
00:28little bit earlier.
00:30Now if the result of the getContext () call is not null, then you know you have
00:35the drawing API and you can go ahead and start using it.
00:38Now to do this in script, let's imagine we have the following example.
00:41We've the canvas tag that's defined.
00:44This is the same way we've been defining our canvas tags up until now.
00:46We've got an ID, width, height, and some fallback content. So to draw in script, this is how it goes.
00:52Typically, you would do something like define a function.
00:55You would call getElementById to get the canvas element.
00:59Once you've got the canvas element, you then ask for its context. So here we are
01:03saying canvas element.getContext, and we're passing in 2D, because we want the 2D
01:08drawing API. And if that result is not equal to null, then we can go ahead and
01:14draw, and then you close the function and off you go.
01:18So the canvas drawing API in 2D is pretty comprehensive.
01:22It's broken up into three groups.
01:23The first group has to do with shapes.
01:25There are rectangles, lines, arcs, paths, colors, and styles.
01:30There are different kinds of curves, such as Bezier and Quadratic, and
01:33then there is text.
01:34The next group has to do with how things are drawn.
01:37There are various compositing properties we can use, patterns and gradients.
01:41You can create shadows.
01:42You can also create clipping paths, and we'll investigate all of these later.
01:46And then finally there are things like transforms, images and video, and you
01:49can even access the raw pixels of the canvas in order to do some pretty
01:54interesting effects. And throughout the rest of this course, we'll see how to do each one of these.
01:58So let's take a really simple example to begin with.
02:00Let's actually draw on the canvas using the 2D drawing API.
02:04So I'm over here back in my code editor again, and I'm going to open up my
02:08example. And in this case, I'm going to use the contextdraw_start example, under
02:14chapter 04, so I open that.
02:16So here is our file.
02:17There is our canvas.
02:18Here is the code we're going to write.
02:20I can go copy these lines from the snippets under ContextDraw. So I'll copy,
02:27and we'll go back to the source code and we'll paste it in here.
02:31So what we're going to do now is use the 2D drawing API to put that light gray
02:36background that we saw earlier into the canvas.
02:41Now, I don't expect you to necessarily understand all this right away.
02:44It's just a simple example to show you how this works.
02:46So first, we get a reference to the canvas element by calling
02:49getElementById canvas. Then we say hey, do we have the canvas object, and
02:54is there a method named getContext?
02:56And if there is, we then call the getContext method using 2D as the argument.
03:02That gets us the 2D drawing API.
03:04And then finally, if all that was successful, on the context, we say set the
03:09fill style to be light gray, and then we're going to call a function called
03:12fillRect and fillRect takes a couple of arguments.
03:15There is the origin to start drawing at, 0,0, and then the width and height of the
03:20rectangle you want to draw--in this case, the width and height of the canvas.
03:24So you've probably guessed by now what this does.
03:26It's going to fill the entire canvas with a light gray background.
03:30So let's go ahead and save.
03:32All right, let's go over to the browser.
03:34So I am going to bring this up in the browser, and you can see that's
03:37exactly what happens.
03:38So now the canvas has been filled in.
03:40Let's go ahead and view this in another browser to make sure it is working correctly.
03:43I'll open this in Firefox, and there is the same result.
03:48So that's a pretty simple example of using the 2D drawing API to fill a
03:52rectangle with a gray color, but it gets a lot better than that.
Collapse this transcript
5. Basic Canvas Drawing Techniques
Setting and using colors and styles
00:00One of the most basic things that you need to set when you're going to draw on
00:03the canvas is usually involving some kind of color and style, and the canvas
00:082D drawing context provides some global properties that affect how objects are
00:14stroked and filled.
00:15And there are three properties. The first is the fillStyle.
00:19That's the style to use when filling a shape. And you can set this to anything
00:22that you would normally set a CSS color property to.
00:26So, for example, you can use a CSS color or a gradient or a pattern, and this
00:31defaults to black if you don't set it.
00:34We'll take a look at gradients and patterns later.
00:35We'll focus on colors for now.
00:37In addition to the fillStyle, there is a strokeStyle. And again this is the same idea.
00:41You can set this to a color or gradient or a pattern, and also defaults to
00:45black, and this is the color or style that's you used when strokes are drawn,
00:50usually lines or outlines on objects that have an area. And then there is the
00:56lineWidth property, and this is the width of the imaginary pen that the canvas uses
01:02when it's drawing lines. And that defaults to a width of one, but you can set to anything.
01:08There is two-step process involved to draw with colors and styles.
01:12Step one is you set the fill and stroke styles and the line width to whatever values
01:18you want, and then you call a drawing operation that creates some shape,
01:23or does some kind of drawing thing.
01:25So let's take a look at that in code and see how it works.
01:28Okay, so here I am in my editor, and I'm going to start off with my example
01:33colors_start.htm file.
01:37If we look at this in the browser really quick,
01:39you can see here is our canvas, and I've outlined it so we can see it.
01:43So, let's go back now to the code.
01:46Now in my Snippets under the Color section, I'm going to first copy these two
01:51lines and paste them into here.
01:55So we go through all the operations to get our drawing context to make sure that
01:58we have a valid canvas and everything, and then I set the fillStyle to be
02:02green. And then I call an operation called fillRect and that's going to fill
02:06the rectangle with this color. So let's go back to the browser and refresh, and
02:12you can see that, sure enough, a green rectangle shows up on the canvas.
02:15Now let's use the strokestyle, so back in my Snippets, I'm going to copy the
02:19next three lines, copy, back to the code, and we'll paste those in here.
02:27So in this example, now I'm setting the lineWidth to be five and in the
02:32strokeStyle I'm going to use the CSS style declaration of RGB and Alpha. And I'm going
02:39to set the color to be 100% opacity of blue. And this time I'm going to use the
02:45strokeRect function, and this will actually fill the rectangle.
02:48This has put a line around the edge. So we save. When we go back to the browser,
02:53we refresh, and now you can see that we have a green rectangle with a blue outline around it.
03:00So what we've done here is demonstrate some basic drawing operations on how to
03:03set the filling and stroking style, along with the width of the pen, to affect how
03:09things are drawn onto the canvas, And these kinds of properties will affect lots
03:13of different things that you draw on the canvas,
03:15so this is a pretty basic thing to learn how to do.
Collapse this transcript
Drawing basic shapes: Rectangles and lines
00:00In this movie, we were going to see how to draw some basic shapes.
00:04Now we've already seen these couple of times in other examples, but let's take a
00:08deeper look at how rectangles and lines are drawn.
00:12Now, rectangles are the only primitive shapes supported by canvas. Unlike, say
00:16another technology like SVG that also supports the ellipse,
00:20the canvas only has the rectangle as what is called a primitive shape.
00:25It's a shape that's very simple to draw and it only requires one routine.
00:29Rectangles are pretty much the only primitive one supported by canvas.
00:33There are three functions for operating rectangles.
00:36The first one is the clearRect function, which erases the rectangle defined by
00:42the parameters you give it.
00:43In other words, it makes the area fully transparent;
00:45it gets rid of the contents of that rectangle.
00:48The other two are strokeRect and fillRect.
00:51strokeRect outlines a rectangle with whatever the current stroke style is, and
00:55fillRect fills the rectangle with whatever the current fill style is.
00:58Now all three of these rectangle-drawing operations take a starting point of the
01:03upper-left corner of the rectangle that you want to draw--that's the point where
01:06the rectangle will start-- and then a width and a height.
01:08It makes a rectangle as wide as you say and as high as you say.
01:12Unlike other drawing systems where you give it all four points, here all
01:16you need to do is specify one point and then how high and how wide you want
01:21the rectangle to be.
01:22Lines are a little bit different.
01:24Lines can be created using a variety of settings for how lines join together and how they end.
01:31So let's take a quick look at the line operations.
01:35The first two functions, moveTo and lineTo, are used to get ready to draw a line.
01:41So the moveTo function moves the imaginary pen to the given point, but it
01:45doesn't actually draw anything.
01:46Imagine you are picking you are picking the pen up from the paper and moving it
01:49to its new location.
01:51The lineTo actually does draw a line from whatever the current pen point is to
01:56the new point that you give it.
01:58The next three properties, lineWidth, lineCap, and lineJoin, determine how the
02:03line looks on the screen.
02:05So we have already seen the lineWidth before. That determines how wide the line is.
02:09The lineCap defines how the ending of line is drawn, and there's three properties.
02:13There is the butt property, which is default, or you can draw lines with round
02:17ends or square ends.
02:19The lineJoin property determines how lines join together when you do multiple
02:23line tos, making the join as a round join, a bevel join, or a miter join,
02:28which is the default.
02:30The miter limit is related to the miter join, and this the limit at which line
02:34joins are cut off and are drawn as bevels. And that defaults to 10, and we'll
02:40see that in a moment.
02:41The beginPath begins a new set of drawing operations, and the stroke function
02:47collects all the current path commands and then draws them.
02:50So we will see how to do that in a moment.
02:52But first, let's get started drawing some basic rectangles.
02:56So in my snippets, I'm under the Rectangles section, and I am going to open up my
03:01file called rectangles_start. And here is where I am going to paste my code in.
03:07So I am going to go back to the snippets, and I am going to take the first two
03:12sets and I am going to copy that and paste it in.
03:18So in this case, we are going to draw first a stroked rectangle, and it has a blue
03:22line that is five pixels wide, and then we are going to draw a fill rectangle.
03:26So let's save and go to the browser.
03:29Okay, so you can see there is the operations right there.
03:32There's the stroked one. There is the filled one.
03:34Let's go back to the code.
03:36So now I'll copy and paste the other two.
03:38Actually, I'll do this one first.
03:43I'll copy that. We'll paste it in.
03:46In this case, we have a rectangle that's both stroked and filled.
03:49So the stroke will be red and the fill will be yellow.
03:52Then we have increased the lineWidth to 10.
03:55So we've set the new properties, and then we draw.
03:57So we fill and stroked the rect, so let's save and refresh the browser.
04:02You can see that now you got three rectangles, different kinds of properties.
04:07And then lastly, let's clear a rectangle.
04:11So I am going to copy and we'll paste.
04:13So here is what we are going to do.
04:14We are going to create a rectangle that cuts across all three of the
04:19rectangles we drew previously.
04:21So you can see that this rectangle starts at the 25, 25 point, near the
04:24upper left, and has a width of 100 and a height of 125.
04:29In fact, they all have the same height and width.
04:32They just happen to start at different X points so that they move further and
04:35further to the right along the canvas.
04:38And then the clear rectangle is going to start at the X of 15,
04:42so before the first rectangle. And the Y point of 75, and it is going to be
04:47450 pixels wide and 50 pixels high.
04:50So let's save this and see what it does.
04:53So when we refresh, see all three rectangles got drawn, but then a rectangle
04:58right here got cleared out from underneath them.
05:01So that's how you can clear a rectangle.
05:04Let's now take a look at the lines.
05:06So I am going to go back to my example file. I'm going to open lines_start now.
05:13So here is the starting point.
05:15Let's go back to the snippets.
05:16So now let's go up to the lines section, which is right there, and we've got
05:22varying examples that we are going to do.
05:24So the first example, we will copy these lines right here.
05:28We'll copy and we'll paste. Let's review with these do.
05:34So what we are doing here is creating a for loop that goes from 0 to 10, and we
05:39are going to draw lines of varying widths.
05:42Now, to draw a line, the way that you do this is you always begin a drawing
05:45operation with the beginPath function. That tells the canvas that a path
05:49operation, which lines are part of, are about to begin.
05:53So then we set that lineWidth.
05:54In this case, we are going to set the lineWidth to whatever the loop counter is +1 pixel.
05:59So it will start off at 1 and end at 11.
06:02And then we are going to move to the X position here and the Y position defined
06:08by the current line that we were drawing.
06:10And then we are going to draw a line to the X position of 475 and the same Y.
06:16So this will draw 10 lines of varying widths, and after each line is drawn, we call stroke.
06:22That actually fills the line in.
06:23So the process is called beginPath. Do your line operations. Then call
06:27stroke, and that will stroke the lines, so let's do that.
06:30We are going to save, and then we are going to go to the browser.
06:33You can see in the first example that's what's happened.
06:34You started off drawing lines of varying widths, going from 1 up to 11 and
06:40from this X to this Y.
06:43Now, let's see how to draw lineCaps.
06:46So to draw lineCaps, we are going to go back to snippets and we are going to copy
06:51this code over, and we are going to copy these lines. Remember, there's three
06:58end caps. I will copy that.
07:01So we'll paste it below this one here.
07:05So notice that we've got three canvases:
07:07we have got canvas1, canvas2, and canvas3.
07:09So the canvas1 is going to be the line widths.
07:12The next canvas would be done with line caps.
07:15So let's scroll back up.
07:17Here's canvas2.
07:18So what we are going to do is draw two guidelines so we can clearly see how the
07:24line ending caps are different for each operation.
07:27So we draw two cyan lines of width 1 at the left and right side of the canvas, and
07:36then we are going to draw lines using each one of the lineCaps.
07:38So we are going to set our lineWidth to be 25 and the strokeStyle is going to be black.
07:43And then we are going to draw one line with the butt style, one with a round
07:46style, and one with a square style, from this position to this position.
07:52So we begin the path, we move, we line, we stroke.
07:56And then we do it again: beginPath, moveTo, lineTo stroke.
07:59That's the operation for drawing a line.
08:01So we save. Let's go back to line example and refresh, and you can see right
08:07there, there is the cyan guidelines that we drew.
08:09There is the first one. There is the second one.
08:11And you can see the start and the end point for each line goes from one
08:15cyan line to the other.
08:17So here is the butt example,
08:19here is the round example, and here is the square ending.
08:22You can see how each one of those line caps has a different appearance.
08:28And let's finish up using the lineJoins. So now for the third canvas, we are
08:34going to copy these lines right here, go back to our lines, and we'll paste it in.
08:44So, similarly to the last example, we get the canvas, in this case it is canvas3.
08:49We are going to set the lineWidth to 15 and the strokeStyle to black, and then,
08:53again, for each one of the lineJoins, we are going to round, bevel, and miter.
08:58So then we begin the path, move, line, and line.
09:01So we are going to draw one line up and one line down, and then we stroke it.
09:06So we do one for each of those. We save.
09:09Back here in browser, we are going to refresh, and you can see that the three
09:13line joins have now been drawn.
09:14So there is the round line join, there is the bevel line join right there, and
09:19there is the miter line join, where the miter line just continue these two lines
09:24here up to a point where they both meet.
09:26Now the miter limit controls how much of a ratio there is before the miter gets
09:32cut off and looks like a bevel.
09:33So it defaults to 10.
09:34Let's go back and play with that for a second.
09:36Let's set the context's miterLimit to 20, and we'll save and let's refresh that.
09:49So no effect on that one. Let's try it again.
09:51Let's put it down to say 5, refresh.
09:54One more time, let's put it down to 1. And you can see that when I set the
10:03miterLimit low enough, suddenly the miter gets cut off and turned into a bevel.
10:08So that's how you use the miterLimit. All right!
10:11So in this example we have seen how to draw lines of varying thickness, varying
10:16end cap styles and varying join styles.
Collapse this transcript
Understanding the Canvas state
00:00Before we go any further in learning how to draw on the canvas, we should take a
00:04moment and learn about the canvas state and understand how it works.
00:09Each context that you get on a canvas maintains what's called a drawing state
00:14which your code can manage. You can save the current state and you can restore a previous one.
00:21States are basically pushed onto a stack of saved states.
00:26So each time you save a drawing state, it goes on a stack and then when you
00:29restore it, the one that's currently on the top of the stack gets popped off and
00:33becomes the current drawing state.
00:36The canvas drawing state keeps track of several properties of the canvas.
00:41It keeps track of the current values of the lineWidth, the strokeStyle, the
00:46fillStyle, the lineCaps, etc.--all the stuff that we've seen so far in how to
00:50draw shapes like rectangles and lines.
00:53It also keeps track of what's called a current transformation matrix, and
00:57we'll see that later on in the course when we use transformations.
01:02It also keeps track of the current clipping region, which also we'll see a little bit later.
01:06So it keeps track of each of these three sets of values and you can save
01:11these and restore these.
01:12So that begs the question, well, why would you want to do this?
01:15Well, your code may have set of whole bunch of drawing settings and during the
01:20course of drawing, you might want to just make a minor tweak to one of those
01:24settings, but you don't want to have to keep track of those manually because you
01:29will have to remember, oh I changed the lineWidth here, and I can set it back
01:32to it was. Over here I changed the strokeStyle.
01:35Now I've got to set it back to what it was.
01:37So, saving and restoring the canvas does all of that for you.
01:41Now to save and restore the state, all you need to do is use the Save and Restore functions.
01:46Essentially, you call context.save and then you can perform a new set of drawing
01:52operations, any one of which might change any of the save properties:
01:56the current lineWidth, the current fillStyle or strokeStyle, so on and so
01:59forth. And when you're done, all you have to do is called context.restore and
02:04that will put the drawing state back into the state that it was before you
02:07called Save and made any changes.
02:10So let's actually take a look at how this works in real code because that's
02:14usually the easiest way to understand it.
02:17So let's will switch over to my editor, and in the Snippets code, I am on to the Drawing
02:21State section here in chapter 5, so let's open the example file, and we'll open
02:27drawingstate_start.
02:29So what we're going to do is go back to my snippets and we're going to copy
02:34these lines over here. For now we'll just copy those and we'll paste.
02:43So let's see what we've got so far in the browser.
02:45Let's go over here and go to drawingstart, so we've got a rectangle that has a
02:50yellow interior and a red stroke.
02:52Now, let's go back to the snippets and copy the next group of lines over.
02:58I'll copy these and we'll paste below this.
03:05So for the moment, I'm going to comment out the calls to save and restore, and
03:13let's take a look at the effect.
03:14So here we draw the first rectangle. It's got a red stroke in the yellow
03:18interior. Then we'll go and we change the strokeStyle to be green and the
03:23fillStyle to be blue and the lineWidth to be five. And then we create a new
03:26rectangle, and then we create a third rectangle, but we don't have any
03:30properties that were being set, so let's go ahead and save, and let's go back
03:35to the browser and refresh.
03:36So now we have three rectangles: one is yellow inside in red, and then we have
03:41two rectangles that are blue interiors and green strokes.
03:45So let's go back to the code now. Let's uncomment those two lines.
03:50I'm going to uncomment Restore.
03:51I'm going to uncomment Save.
03:55So the call to the save function will save the current properties of the
04:02context--in this case the stroke, fill and line. Then we reset them over here
04:07and draw a new rectangle, and then we restore them. So let's now save and let's
04:11go back to the browser.
04:12So now when we refresh, you can see that the call to the restore function is
04:18restoring the drawing properties that were set originally for this rectangle
04:23before they were changed for this one.
04:26So again back in the code. So we start off with red and yellow. Then we save that.
04:33We do a whole bunch of things here that changes the current drawing context,
04:37and then we call restore. And that pops off the stack that original context
04:42that we saved which restores the red and yellow settings, allowing us to draw with them again.
04:47So we can see how using the Save and Restore functions to manage the canvas
04:52state can save us a lot of work when we're drawing things and making minor
04:57changes all over the place.
04:58Now, this may seem like a trivial example, but later on when you're drawing really
05:02complex drawings and you're making minor changes to the drawing context property,
05:06this really comes in handy and relieves your code from having to do a lot of
05:10manual work to keep track of drawing properties, of which there are a lot.
Collapse this transcript
Drawing complex shapes: Arcs and paths
00:00Up until now, we've seen how to draw simple shapes like rectangles and lines.
00:05Now let's take a look at drawing more complex shapes, specifically arcs and paths.
00:10So, what is a path? A path is basically a set of connected points, and the points are connected by
00:16lines or by curves, and a path is either open or closed.
00:21The current drawing context always has one, and only one, current drawing path.
00:26Now, paths can be open or closed.
00:28A closed path has an end point that is the same as its starting point. Or the
00:34canvas can automatically draw a line from the ending point to the starting point
00:39and automatically close the path for you.
00:42Now, to begin creating a path, you use the beginPath method, and it doesn't
00:46take any arguments.
00:47You just simply say beginPath and start drawing your paths.
00:51To add paths, you basically use one or more path-drawing routines, and if you've
00:55watched me in the previous movies, you've seen how to do this with lines.
00:59In this movie, we're going to see how to do it with arcs.
01:01To stroke the current path, you just call the stroke function, again with no
01:04arguments. And to fill it, you just call fill. Both of those are no argument
01:09functions that will stroke and fill paths.
01:11And to close the current path, should you decide to close it, you just call closePath.
01:16In case the end point is not the same as the start point, the canvas will close it for you.
01:20Let's talk about arcs for a moment. Arcs are curves that are portions of a
01:25circle, and in fact a circle is an arc.
01:28It's just a special case.
01:29It's a full 360-degree arc.
01:32So to draw an arc, you can either use the arc function or the arcTo function.
01:37So the arc function has several arguments. The first is the X and Y point, that
01:43if the arc was a full circle, would serve as the center of the circle.
01:48The r argument is the radius, which is how far the arc is out from this imaginary
01:55circle center right here.
01:56Now, to actually stroke the path along the edge of the circle that the arc
02:00represents, you have a starting angle and an ending angle.
02:04And then the last argument is true if you want the arc to go anticlockwise
02:09rather than clockwise, which is the default direction.
02:12Now, the other arc function is arcTo, and that takes two control points and a
02:18radius. And then finally the closePath function, which I mentioned earlier,
02:22which closes the current drawing path.
02:25Now we should make a special note that when you use angles, such as the angles
02:29here, these angles are radians; these are not degrees.
02:34So if you want to use degrees for your arguments instead of radians, you can use
02:38a very simple mathematical function right here, which takes Math.PI,
02:42you divide by 180, and you multiply by degrees and that will give you radians.
02:47Let's take a look at some arc examples. Remember 360 degrees is the same as 2 pi radians.
02:54So in this arc, we have a starting point and an ending point, and the way we
02:58do that was by stroking a 90-degree arc.
03:01So we call beginPath to begin the path, and we create an arc with its center
03:06point at 50 and 150. That will be right about this center point right here.
03:11This 100 value is the radius, which is about 100 pixels from the center out to
03:16the edge of the arc.
03:18Then we start at the 1.5-radian mark, and we go to the 2-radian mark, so we'll
03:24start there and it will end at this angle right here.
03:27Let's look at another example.
03:29In this case, we have an arc that's going the other way. So to stroke 270 degrees
03:34arc, again, we call beginPath.
03:36We have the X and Y center--that will be this center point right here. Radius is
03:41still 100. And we're going from the zero-angle part all the way around here to
03:47the 1.5-radian mark, anticlockwise in this case.
03:51So let's actually take a look at some real examples in code to see how this works.
03:55Here we are on the code editor, and I've got my snippets open to the paths section,
04:00and I've got my paths_starts example file for this chapter opened up.
04:06So let's go ahead and copy and paste some of these examples. So I will take
04:11these first lines right here, along with the first example, I'll copy and paste,
04:16okay, and save. And let's go to the browser, and we'll choose paths.start.
04:24You can see that we've got three line segments for this particular path.
04:27Let's take a look. We've got the strokeStyle blue, a fillStyle of red, which we are
04:32now currently using.
04:33The lineWidth is 5, and here's where we are to draw the open path. So we call beginPath.
04:39We move the pen to its starting location,
04:41we add three line segments, and then we stroke, and that will stroke the current
04:45path so those three lines segments gets drawn.
04:47Okay, let's copy the next one.
04:53This time we're going to draw a closed path, so we'll copy and we'll paste.
05:00So in this case, we call beginPath like we always do. Same kind of operation.
05:03We move the pen, draw three line segments, only
05:06in this case we call closePath before we call stroke. So let's save and let's
05:12go back to the browser and refresh. And you can see that there's the same three line segments,
05:16but in this case because of the closePath call, the canvas added this final line
05:21for us to make the ending point the same as the starting point.
05:25One more example. Let's go back to the code, back to the snippets.
05:30This time we're going to draw a closed path.
05:33So I'm going to copy these lines here. Now we're going to paste.
05:38So one more time, three line segments, only in this case, in addition to stroke,
05:43we're going to call fill--and notice there's no closePath call here.
05:48So we save, and then we go back to the browser and we refresh. And in this case
05:53you can see that the path was stroked--
05:55it's not closed, but it was filled in as if it were closed,
05:59there is an imaginary boundary right here--using the current fillStyle.
06:03So now that we've seen paths, let's take a look at arcs.
06:07I have got my arcs_start example open right here, go back to my snippets.
06:15Let's go back up to the arcs, which are right here.
06:21I am going to copy the first example here and paste it.
06:30We'll save, and let's show it in the browser.
06:34So that's the 90-degree arc right there. And just to show you the effect of
06:39changing the radius, let's make the radius 150 this time.
06:45Save, and we'll refresh and watch. So you can see that the center point stayed
06:51the same, but the radius got bigger.
06:54Let's copy some more. In this case, I want to copy this one, and then we'll paste.
07:05Now in this case, we're going to stroke a three-quarter arc. So we've moved the
07:10center point over and we have got 100 radius. And in this case we've got
07:14these two angles, right?
07:16We've got a starting angle. We've got an ending angle. So we're going to save that and refresh it.
07:20You can see that the arc has now been drawn in the counterclockwise direction,
07:26starting from here, going all the way around three quarters to this point,
07:30around that center point right there.
07:31Okay, last example. Let's do a circle, and we'll copy and we'll paste.
07:43All right, so in this example, we've started at zero. We go the full 2 pi
07:48radians. Save, we refresh, and there's our circle using the fill and stroke
07:56style, because you can see we call both fill and stroke.
08:00And just to show you how radians work, let's just do a simple example with degrees.
08:05Let's just say 'var degrees equals 360', and we'll say 'var radians equals
08:14Math.PI/180 * degrees', and we'll just substitute radians in
08:25there for this one.
08:28Now since we're starting off with 360, it's going to have no effect. But just to
08:31show you that it is the same, let's refresh. So it's the same.
08:35But let's just change that to I don't know, 173 degrees, and we'll save, and
08:42we'll refresh. And you can see that it's not quite half a circle, because it's
08:46not 180 degrees, but you get the idea.
08:49You can use radians, or you can have degrees and convert them to radians.
08:53What we've seen in this example is how to draw paths and arcs using the canvas
08:59path- and arc-drawing routines. And we've seen how to draw open and closed paths,
09:05as well have stroke and fill paths. And then finally, we saw how to draw arcs in
09:10both directions using radians and degrees.
Collapse this transcript
Drawing complex shapes: BƩzier and quadratic curves
00:00You can actually get fairly advanced with some of the drawing operations that
00:04are possible with the canvas.
00:06In fact, the canvas lets you draw Bezier and quadratic curves.
00:11The way curves are drawn is in the case of Bezier curves, there is a starting
00:17context point, and an end point that uses two what are called control points to
00:23determine how the curve is drawn.
00:26Quadratic curves are similar.
00:28They use a start point, but they only have one control point and one endpoint.
00:33So Bezier curves because of those two control points, they let you draw curves
00:37that are slightly more complex.
00:39So let's take a look at each one.
00:41The Bezier curve has a starting point, which is right here, the context point.
00:46That's the end point right there. And there are these two control points.
00:50These two control points control how the line curves towards the control
00:56point in each case.
00:57So you can see that because this end point is close to its control point, the
01:01curve is a little bit different over here than it is over here.
01:03And for quadratic curves there's only one control point.
01:07So you set the context point, set the control point, and the end point and you
01:11can see that the curve is slightly less complex than what you get with Bezier curves.
01:17So the functions for drawing these curves are right here.
01:21So like other paths, you first use the moveTo function, which we saw when we
01:27learned how to draw lines in a previous movie.
01:29So you move to a pen location, and then you call bezierCurveTo, and then you
01:35supply a series of points. cx and cy represent the control points.
01:41So this is the first control point,
01:42this is the second control point, and then this is the end point.
01:46It's similar for quadraticCurveTo: you use moveTo to move to a start point, and
01:52then you supply a control point and an ending point.
01:55So let's take a look at this in a real live example.
02:01So here I am in the code editor, and I've got my curves section right here of my snippets.
02:07So let's open up an example file, and what we're going to open up is curves_start.
02:14This is the starting point for our curves example.
02:18So I'm going to go and copy the first example here.
02:22So we'll pick up the stroke and lineWidth properties, and we will call this
02:28right here, and we'll paste this in and save.
02:33All right, let's take a look at how this looks in the browser.
02:36We should have a Bezier curve that's 5 pixels wide and blue; sure enough, we do.
02:42Now that's pretty cool, but we can make it a little bit more instructive to
02:45actually see where the control points are.
02:47So let's go back to the code, and we'll go back to the snippets. And what we're
02:52going to do now is make the control points visible.
02:55So we'll copy and we'll paste this code in.
03:00So what we have here now is a full example.
03:03So we call beginPath, like we do with all paths.
03:06We move it to a location. Then we call the bezierCurveTo, and we supply a whole
03:10bunch of points that determine how the Bezier curve is drawn. And then we call
03:14stroke to actually fill it in. And to make the control points visible, we're
03:18going to define a strokeStyle that's 25% opacity of black with a pixel width of 1.
03:26And then we're going to simply call moveTo and lineTo. And if you look, we're
03:31basically going to line-to each one of the control point locations, so that
03:36we can see what effect the control points have on each one of the points on the Bezier curve.
03:42So let's save and let's refresh, and you can see that these are where the control
03:46points are up here now, and we can actually change the control points.
03:52So what we can do is change that one to say 300, and that's this guy here. So let's save.
04:03Let's refresh.
04:05You can see the effect of moving the control point to no location.
04:09So there is the curve.
04:10You can see that the curve is being affected by these control points.
04:15So now, let's do a quadratic curve. Same idea.
04:24We're going to take the curve and the control points, copy, and we're going to
04:30come out of here and paste those in.
04:34So now in this case, we have a green line that's five pixels wide and just like
04:41with all paths, we begin the path.
04:43We move to the starting location, and then we call quadraticCurveTo, and we
04:48supply the necessary points there.
04:49There is the control point, there's the ending point, and we call stroke to make
04:54the curve visible. And then we have some instruction code right here that makes
05:00the control point visible. So let's save.
05:04Let's refresh.
05:05You can see that now here's our quadratic curve, and there's the control point up
05:09there, and we can play with that a little bit.
05:12So it starts out at 400, 200--that's the starting point--and then the curve goes
05:18straight up from there.
05:19So let's actually move that one over a little bit, to 500 say, and we'll change
05:26the instruction code as well, and we'll refresh. You can see that by moving
05:32the control point, that affects the curve.
05:34In this example, we've seen how to draw curves using Bezier and quadratic math,
05:39and we've seen how changing the control points changes how the curves are drawn.
Collapse this transcript
Rendering text
00:00One of the interesting things about canvas is that in addition to drawing shapes
00:04and curves and paths and so on, you can also draw text directly onto the canvas
00:10using a variety of text-drawing settings.
00:13In fact, drawing text is very similar to drawing any other paths.
00:19You can stroke them.
00:20You can fill them using the same fillStyle and strokeStyle as you would for
00:25other path operations and other shape operations.
00:29It's important to note that when you draw text on the canvas, it is not
00:33affected by any kind of CSS box model;
00:37it's just a path, and it's drawn using the canvas rules, not any CSS rules that
00:43you may have defined elsewhere in your document.
00:48And it's also important to note that you shouldn't use text on the canvas as a
00:53replacement for regular document text, because that makes accessibility
00:57really, really hard.
00:58In fact, screen readers won't be able to read the text that you draw on the canvas.
01:03So if you have any grand ideas about using canvas to replace headings, like h1s
01:07or h2s and so on, it sounds like a great idea, but you probably should find
01:12another way to do that, because accessibility-wise, that's just not going to
01:16work for people who rely on assistive technologies.
01:21So to draw a text on the canvas, we use some text-drawing properties and
01:26methods, and those are here.
01:28So we can set a couple of properties.
01:29First, you can set the font that you want to draw with, and anything that you
01:34would normally put into a font CSS rule can go in here.
01:37And then you can also set textAlign and textBaseline.
01:41textAlign can be either a start, which is the default, which is where the
01:45drawing point starts.
01:46There's end, and there's left, right, and center.
01:50For textBaseline, there's a couple of different settings. Some of these are
01:54pretty advanced, so I'm not going to go very deep into them. There's top.
01:57There's middle or bottom, which you may be used to from regular HTML. But there's
02:01also things like ideographic and hanging, and those are mostly used for
02:06languages such as, for example, Chinese or Korean, where there's an ideographic
02:11baseline involved with particular characters and so on.
02:14The point is that the canvas does give you that kind of control over how text is drawn.
02:19Those three properties are available for setting how text is drawn.
02:23It's very similar to how you set fillStyle or strokeStyle for strokes and fills and so on.
02:28Then the next few routines actually draw the text.
02:32So there's the fillText method, which renders the text string supplied by the txt argument--
02:39that's the string that you want to draw-- at the point of x and y. And then this
02:45parameter here (maxW), that's optional, which is why it's in these brackets.
02:50If you specify a maxWidth, then the canvas will render that string no wider
02:55than this space right here.
02:57So it will compress the characters if it needs to, or do what it can do to make
03:02the string fit into that space.
03:04And along with fillText, there's strokeText. Same idea here.
03:08You give it the text to stroke,
03:10you give it the point that you want the text to be drawn at, and an
03:15optional maximum width.
03:17And the last function, measureText, will return the dimension metrics of the
03:23string that you pass in using whatever the current font settings up here that
03:28you happen to pass in.
03:30So let's take a look at some text drawing examples in real code.
03:36Okay, so here we are in the editor, and in my Text section of my
03:41ExampleSnippets, I'm going to open up the text_start example. And we're going to
03:50go back to the Snippets, and we'll copy some code over.
03:53So the first one is the string that we're actually going to draw, and we'll copy
03:56the first example and we'll paste that in, so we'll save.
04:03So this is a really simple example.
04:04I've got a string I want to render, and I'm just going to render it using
04:09whatever the default settings are for rendering text onto the canvas.
04:15So let's save that, and let's go ahead and look at that in the browser.
04:18And you can see that it defaults to a pretty small text size, and it draws
04:23the text right at the point where I said to draw it about 10, 20, which is right up there.
04:28So let's go back to the code and do some more advanced stuff, and let's go
04:33back to the snippets.
04:35This time, let's draw the string with some font information.
04:41So we'll place that.
04:45So now on the drawing context, I've set the font to be 25pt Georgia, and now
04:54we're going to fill the text at a different point below the first one, and we'll
04:59see what effect that had. So we'll Refresh.
05:02So you can see that now the text is being drawn in a much bigger font and a
05:07different font face.
05:09Let's keep on going.
05:12Go back to my Snippets, and this time we're going to fill it, but we're going
05:15to use a fillStyle color. So I'll copy these lines and paste them in there and save.
05:24So now we're using a blue fillStyle to fill the text, and let's see how that works.
05:28Okay, that was pretty cool.
05:30So this time same string, only different color now.
05:33Let's go back to the code.
05:34Okay, now let's draw the string with both a stroke and a fill.
05:43We'll copy and we'll paste.
05:50So in this case, I have defined a font of 32pt Verdana.
05:54We've got a fillStyle, we've got a strokeStyle, and in this case, the
05:58strokeStyle is green at 80% opacity, and we're going to fill and stroke the text this time.
06:06So let's do that.
06:07Okay, a little bit different effect there.
06:10Let's uncomment this line that sets the baseline, just to show you how
06:14setting the baseline works.
06:15So we'll save, and so here's the effect.
06:18When I Refresh, you can see that the text shifted down a little bit. So let's go
06:24ahead and put that back out again and refresh, get it back to what it was.
06:30And then finally, for the last example, let's use the measureText and let's put
06:37an exclamation point in here, just to show you how this works. And we'll go down
06:42here, and we'll copy the measureText, and I'll explain this.
06:49Now, let's go down, and I'll paste it in.
06:55So in this case, we're going to call the measureText function, and when you call
07:02measureText on theString, which in this case has been set to the text string
07:06that we're using, it's going to take the current font settings and then measure
07:10how wide the text is.
07:13There's no built-in method to measure how tall the text is, but you can fake
07:19that up pretty easily by creating a fake span and putting the text inside the
07:24span and then using the CSS features available in your browser to see how high
07:27the span is, and that will tell you how high the text is. But there's no
07:31currently built-in way of doing that.
07:33So this is a simple example. So we're just going to calculate the width.
07:37Now I'll come back here, and actually this comes back with an object that has a width property.
07:43So then we'll call beginPath, we'll set the strokeStyle to black, and then we're
07:47going to move to a point that's underneath the text string, and then we're going
07:52to create a line that is the width of the text at the same Y point.
07:58So I'm going to underline the text, and then we call stroke to fill that line in.
08:03So let's save, and let's refresh.
08:07And you can see that in this case, now that I've modified the string with
08:10exclamation points, the text has changed. And we now have a black line going from
08:16the part where we started drawing the text down to where the character is.
08:20You can see that there's a little bit of space left over here, and the
08:23reason for that is because actually when you call the measureText function,
08:27the measureText result that comes back is not always exactly the same size
08:31as the text string.
08:32In fact, the specification that the W3C makes states that there is currently no
08:37way of finding out what the exact bounding box of the text currently is.
08:44That might be added to a future version of the spec, but it's not there now.
08:49So the lesson to take away from this is there's currently not a way to measure
08:53exactly how wide a string is, in order to build something, say like a text
08:59editor using the canvas.
09:01They're looking at putting that in, but it's not there right now.
09:04Anyway, in this example we've seen how to draw text on the canvas using a
09:08variety of settings, strokes, colors, and fills.
09:11We've seen how to measure the width of the text, and we've seen how to draw
09:15text using both strokes and fills.
Collapse this transcript
6. Complex Canvas Drawing Techniques
Creating shadows
00:00In this chapter we're going to take a look at using some more complex
00:03canvas drawing techniques, and the first one we're going to look at is creating shadows.
00:09So there are four attributes that you can use to draw shadows on the drawing
00:15context on the canvas.
00:17And all drawing operations that take place on the canvas are affected by
00:23these shadow attributes.
00:25This includes paths, images, text, lines, whatever.
00:28When you draw shadows, they can be colored, they can be offset in both the X and
00:37Y direction, and they can have a blur value.
00:40And in fact, these right here are the available properties to use when drawing a shadow.
00:46So the first one is the shadowColor, and that's the color to use when drawing the shadow.
00:51And again, like other places where you can set a color, you can use any kind of
00:55CSS color string to specify a color.
00:58Now if you don't specify one, it defaults to transparent black.
01:02The OffsetX and OffsetY properties are pretty self-explanatory.
01:08They control the horizontal offset of the shadow, which defaults to 0, and the
01:12vertical offset, which also defaults to 0.
01:16And there is a Blur factor that you can set on the shadow as well.
01:20This defaults to 0, but it has to have a value that's greater than 0 in order to
01:25have any visible effect.
01:28So let's jump over to the code and take a look at drawing shadows.
01:34Here we are in the code, and I've got my shadows_start file opened up, and that
01:41is located in the folder for chapter 06.
01:44So let's just take a quick look at that in the browser, take a look at shadows_start.
01:49So we start off with an empty canvas, which is only visible by its dotted
01:53outline, and we'll go back over to the code.
01:56In my Snippets file, under the section for Shadows, I am going to copy some code over.
02:03So this first set of lines here basically sets up some basic shadow settings, so
02:08I'll copy those and I'll bring those over here in the section where we've tested
02:14for the canvas and gotten the context.
02:16We're going to set some shadow settings, so here you can see I'm setting the
02:20shadowColor to black and the Offsets to 10 pixels in both X and Y, and I'm
02:26giving it bit of a Blur factor.
02:28And then I'm going to copy the first example.
02:32So let's copy that and bring it over.
02:36So, in this case, we've created a rectangle using the fillRect function right
02:42here, along with a fillStyle.
02:44And the fillStyle is basically going to fill this rectangle with a blue color,
02:49at 100% opacity, and make a rectangle 200 pixels wide and 100 high.
02:55And because we've set up some shadow properties here, it will draw a shadow
03:00behind the rectangle.
03:02So let's go back to the browser, and we'll refresh.
03:06And you can see that there's the blue rectangle, and there's the shadow behind it.
03:09And let's take a look at this in some other browsers.
03:14So we'll just right-click and we will say Open with.
03:17In this case, let's take a look at Firefox.
03:18Okay, there's the same effect in Firefox.
03:21There's the shadow.
03:23Let's take a look in Opera. And you can see there's the shadow around the object
03:28in the Opera browser.
03:30Let's just do one more.
03:31Let's go ahead and look at this in Chrome.
03:35And there it is in Chrome.
03:36There's the shadow around the object right there.
03:39Let's go back to the code.
03:41Let's get another example.
03:43In this case, let's use some text.
03:45Let's see what drawing a shadow on a text looks like.
03:51So we'll come back and we'll paste this in.
03:54So in this case, we have a text string, and we are setting the fillStyle to be
04:01green. And here I'm changing the shadow colors.
04:05So in this case, the shadow is a bit of a combination of the green and blue
04:11colors at half opacity.
04:13I've changed the Offset, so I have changed the Blur, and I've also set the font
04:16size to be a little bit larger.
04:18So when we go to fill the text, we should see a different color shadow behind the text.
04:26So let's save.
04:28Let's look at it in IE.
04:30And sure enough, you can see there's the text.
04:31There's the shadow behind it.
04:33And let's go back to Firefox. Do the same thing. Yup!
04:37That works. And let's look at it in Chrome.
04:40Sure enough, it all seems to work just fine.
04:44Let's go back to the code and let's look at another example.
04:50In this case, we're going to do it on a line. So we'll copy, and we will paste.
04:59So in this case, now we have a line, and I've got a round line cap with a width of 25.
05:05And once again, changing some of the shadow properties,
05:09in this case, making more of a purple color with a higher Blur number. And the
05:14strokeStyle is going to be red.
05:16We're going to have a red line with a round line cap that's 25 pixels wide.
05:20So we begin our path, we do the moveTo and lineTo, and when we call the stroke
05:25function. That is when the shadow gets created. So let's save.
05:31Let's refresh IE.
05:32You can see there it is, and there's that little purply kind of shadow behind it.
05:36And let's do the same thing in Firefox.
05:39Yeah, it works fine.
05:41Let's go to Chrome. Yeah, works fine there too.
05:44Before we go, let's just take a look at some things we can do with shadows.
05:48What I'm going to do is I'm actually going to take the shadowOffset here and
05:54down here, I'm actually going to make these negative numbers.
05:58So I'm going to do -15 and -15, and we'll save.
06:04Okay, now let's go back to the browser and refresh.
06:07So you see how the shadow in that case moved up and to the left behind the object.
06:13So in addition to specifying positive numbers which moves the shadow to the
06:17right on the X axis and down on the Y axis, by specifying negative numbers, we
06:24can move the shadow up and to the left.
06:27So negative X means go to the left, and negative Y means go up.
06:32So in this example, we've seen how to draw shadows with varying colors, varying
06:35blur effects, and varying offsets using the shadow properties.
Collapse this transcript
Drawing with patterns
00:00The HTML5 canvas element makes it easy to draw using patterns.
00:04In fact, drawing operations that use fill and stroke styles can take patterns, as
00:09well as gradients, as settings.
00:11The way you create a pattern is from an image, a video, or another canvas element.
00:17So if you use an image that's an animated image, the pattern that you create
00:21will use the poster frame of the animated image as the pattern.
00:25And if there is no poster frame in the animated image, it will use the first
00:28frame of the animation.
00:31For video, the current playback frame is used as the pattern.
00:36It's not the live video;
00:37it will actually grab a frame and it will use it as the pattern.
00:40So at whatever point you create the pattern, then it will choose whatever frame
00:44happens to be drawn at that point and use it.
00:47Patterns can be set to repeat.
00:48They can either repeat not at all, or in both dimensions, or only in X or Y dimensions.
00:55So to create a pattern, it's pretty simple;
00:57you basically use the createPattern function.
01:01So createPattern takes two arguments.
01:03The first one is an element and that has to be either an image, video, or canvas element.
01:08The second argument can be one of these four strings:
01:11no-repeat, repeat, repeat-x, or repeat- y--pretty much just like any other CSS
01:16background property you would set on an image.
01:18All right, let's jump over to the code and actually take a look at patterns in real life.
01:24Okay, so here I am in the code. I'm at my Patterns section in my Snippets file, and
01:29I've got my patterns_start file open from chapter 06.
01:33So let's start making some patterns.
01:35The first thing I want to do is create a pattern from an image.
01:39So I'm going to copy this example right here and paste it in, and I'll save.
01:47So to create a pattern from an image, I'm actually going to create a new image
01:51object using the DOM and then load the image in.
01:54Now, because images might load slowly over the network, if I try to just
01:58simply create a pattern right away, that might give me an error because the
02:02image hasn't loaded yet.
02:03So to prevent that, I'm going to use an onload function here.
02:06So when the onload function completes, that's when my createPattern method will
02:11be called, and then we'll fill the rect of the canvas with a rectangle that uses
02:16its fillStyle as this image pattern.
02:19So the image we're going to use is this one right here. And if we look at the
02:24examples, it's this little image right here.
02:27We're going to tile the background on the canvas with this image.
02:30So let's go ahead and do that.
02:32So what we do is we create the image. Then we set the onload function. Then we
02:37set the source of this image to be the path to that image. That will cause the
02:41image to load. And then when the load completes, this function will be called.
02:45Then we tell the context to go ahead and use the fillStyle, set the results of
02:51the createPattern function into the fillStyle, and then we fill the rectangle,
02:55starting at the upper left of the canvas and all the way across the canvas to
02:59the width and height.
03:00So let's save this and try it out. And you can see that we've got a nice little
03:05repeating tiled image here, and now if you just say repeat-x, save, refresh,
03:13right, we only get the X direction.
03:16Let's go back and change that, and let's try it in one other browser.
03:20We'll try it in Firefox. And you can see the results are the same.
03:24So, now let's make another pattern and let's get rid of this one to avoid competition.
03:30So in this case, now we're going to create a pattern from a video.
03:34So I'll copy this over, and I'll show you what we're doing.
03:38So down here in the document, I've got a video.
03:41This is an HTML5 video element with an ID, and it's pointing at this source right
03:46here, and it's hidden from view.
03:49So let's take a look at the source. It's this video right here.
03:53So I'll bring this up in the player.
03:55Let's take a quick look at it.
03:56Okay, so this is the video that we're going to use as our pattern.
04:01Now to use the video as the pattern, remember that when we create the pattern,
04:06it's going to grab the current playback frame.
04:09So what we need to do is set a timeout function in order to grab a pattern
04:14that's a few seconds into the video.
04:17So I'm setting a timeout that's waiting 3000 milliseconds, or 3 seconds, and when
04:22the timeout function completes, my resulting function is going to go get the
04:26video element from the document, get the canvas, and get the context,
04:30and then create a pattern from the video element and set that as the current
04:36fillStyle of the context.
04:38And then when I call the fillRect function, again, covering the entire canvas,
04:43the rectangle will be filled with repeating images of whatever frame was playing
04:48at 3 seconds into the video.
04:51So let's save, and let's put a little autoplay on the video right there.
04:58That way it plays automatically. And we'll bring it up in the browser.
05:02Okay, the video is playing. 1, 2, 3. All right!
05:07So, at 3 seconds, you can see that what happened was the frame got grabbed at the 3-
05:11second index and was filled into the entire canvas right here. And because of the
05:17repeat, the image is repeating across.
05:20So it's creating a pattern from video.
05:22Let's go back and let's get rid of this one, and we'll take that off as well.
05:32The last example, I'm going to create a pattern from another canvas, and that's
05:39this one right here.
05:41So we'll copy that, and we will paste.
05:45So let me explain what's going on here.
05:48Once again, we look down at the document, and I've actually got two canvasses.
05:52Here is the example canvas that we've been using throughout the course that
05:55we've been drawing our results into.
05:57I also have another canvas down here with a width and height of 25. And I'm
06:02going to draw some content into that canvas and then use it as a pattern.
06:07So the way I do that is I get a reference to the patcanvas and its context and I
06:14set the strokeStyle to red and the lineWidth to 1.
06:17I'm drawing a 1-pixel line from the top left of that canvas down to the bottom right.
06:22So I've got a diagonal red line, and then I stroke it.
06:25That way we get to the actual drawing of the line.
06:28So now I've done that.
06:29I can use that canvas as a pattern.
06:31So I have a variable here called strokePat, and I tell my regular canvas to go
06:35ahead and create a pattern out of the patcanvas. And I'm passing in repeat.
06:39Then I'm going to set the strokeStyle--no fillStyle this time,
06:43this time it's a stroke--to the strokePattern.
06:45I am going to set the lineWidth to be 25 to make sure it shows up.
06:48And then I'm going to stroke a rectangle with these dimensions, and it's going to
06:52have a stroke width of 25.
06:54So let's go ahead and save and let's refresh, and you can see here is the little
06:59source canvas over here, right, with its red line in it, and you can see that when
07:03I stroked the rectangle, that pattern is now there.
07:06Let's do the same thing in Firefox, and we'll see it works.
07:09All right, so we've seen three examples of how to create patterns, using images,
07:15video, and even another canvas as our pattern source.
Collapse this transcript
Drawing with gradients
00:00Creating gradients using the HTML5 canvas is pretty easy.
00:04There is two kinds of gradients:
00:05there is linear and there is a radial.
00:08The way you create gradients is there are two steps involved.
00:11First, you have to create the gradient using the appropriate function to create
00:16a gradient of the right type, either linear or radial.
00:18Now once you created the gradient, you have to add color stops to the gradient
00:22at certain positions in order to create the necessary color transitions.
00:27Once you've created the gradient, it can be used anywhere a stroke or a
00:30fill style can be used, pretty much like patterns as well.
00:34Let's take a look at how gradients work.
00:35Linear gradients are defined along a path.
00:38There is two points that define a linear gradient.
00:41The linear gradient then travels along that path from the first point to the second point.
00:47So in this example, we have a gradient defined by the starting point x0, y0, and
00:52the ending point, x1, y1.
00:54In this case, we've got a light blue color traveling along that line to the
00:59lower-right point, x1, y1.
01:02Radial gradients work a little bit differently.
01:05Radial gradients are defined by two circles.
01:08The radial gradient travels from the edge of the inner circle to the edge of the outer circle.
01:13And in this case, we've got the inner circle of a darker blue color, and the
01:17gradient travels from the edge of the inner circle to the outer one.
01:21To create gradients, you use the createLinearGradient or
01:24createRadialGradient functions.
01:27The createLinearGradient function takes four arguments, two points.
01:30This is the first point.
01:31This is the second point, which I showed earlier, and that's the line that the
01:36gradient travels along.
01:37The createRadialGradient function takes six arguments, which define the two circles.
01:42The first circle is centered at x0, y0 and has a radius of r0. And the second
01:47circle is at x1, y1 and has a radius of r1.
01:50So that defines the two circles, which define how the radial gradient travels.
01:56Regardless of which gradient you create, you use the addColorStop function to
02:00add color stops at various positions.
02:02The first argument, position, is a floating point number going from 0 all the way up to 1.0.
02:07You can kind of think of that as a percentage.
02:10So, for example, a gradient at the 80% position would be at 0.8.
02:14You could add multiple color stops at different positions, and you simply define
02:18the color using any standard CSS color string to create the color.
02:23Let's go see gradients in action.
02:25So I'm here in my code.
02:26This is the gradients_start file, and this is in chapter 06.
02:31And now I'm going to go to my gradients section in my snippets. That's right here.
02:38So the first example we are going to do is create a linear gradient.
02:42So let's just copy this example right here, and we'll paste.
02:46We've got the call to createLinearGradient right here, and this is the first point.
02:56This is the second point.
02:57Both of these points start at x of 20 and go from y 20 to 280.
03:02This is going to be a straight-line gradient, and then we need to add some color stops.
03:06We're going to go from red to blue and then blue to green.
03:08So at the 0 position, we're going to start with red and then at the halfway mark,
03:12we'll put blue in, and then we'll end up with green at the 100% mark.
03:18Then to display the gradient, we'll simply set the fillStyle of the context to
03:21the linear gradient we just created, and then we'll fill the rectangle with the gradient.
03:26So let's save, and let's go up and look at the finished result, and you can
03:31see that it worked.
03:32So in this case, the linear gradient is going from this point here straight
03:36down to this point here.
03:38Let's see what happens when we change those two points.
03:40So back here in the code, I'm going to change this point here to be 220.
03:47So now I've got x of 20, 20, and the second point is 220, 280.
03:53So we'll save, and we'll go back to the browser and we'll refresh.
03:58You can see now that I've got the gradient going from the top left down to the lower right.
04:04So that's pretty good for a linear gradient. Let's try radial.
04:10So let's go back to my snippets, and now we're going to copy the code that
04:16does the radial one. We'll copy and we'll paste.
04:22All right, let's take a look at the code.
04:29So in this case, I'm now creating a radial gradient, and this is the first circle.
04:34The first circle has its center point at 525, 150 and has a radius of 20.
04:39The second circle is centered at the same location the first circle is but
04:42has a larger radius, in this case 100.
04:44So we've got two circles that are centered at the same point, but of
04:47just different radii.
04:48So now we're going to add some color stops to this gradient.
04:51We're going to addColorStop and we're going to do the same thing;
04:53we're going to red to blue to green.
04:55So red goes at 0, blue is at halfway, green is at the 100% position.
05:01We set the fillStyle to be the gradient we just created.
05:05And then we're going to just create an arc that has the contents of the arc as the gradient.
05:10So after setting the fillStyle, when you call fill, it's going to fill it with gradient.
05:14Let's save. Okay, let's go back to the browser and we'll refresh, and you can see that we now
05:20have a circle with the radial gradient.
05:23So here is the inner circle right here filled with red, and the gradient is
05:26traveling from the edge of that circle out to the edge of the larger one.
05:31So let's go back to the radial gradient definition and offset the circle a little bit.
05:35So we'll go back to the code, and instead of putting this circle at x of 525 and
05:43150, let's offset a little bit.
05:45Let's put this one at y of 100 and we'll put the x, let's say, at 500.
05:51And this is going to cause the circle to move up and to the left a little bit.
05:56So let's save, back to the browser, refresh, and you can see that the circle was here.
06:02Now it's moved up here, and the gradient is a little compressed over this way and a
06:06little bit elongated this way.
06:08So we've seen how to create linear and radial gradients, and we've seen how to
06:12add color stops and even change the directions and origins of the gradients.
Collapse this transcript
Using clipping paths
00:00The HTML5 canvas element gives you the ability to create what are
00:03called clipping paths.
00:05You can think of a clipping path as basically a mask.
00:07It defines a region or a boundary inside of which drawing will take place and
00:12outside of which drawing will have no effect.
00:14Now initially, the entire canvas is, by default, the current clipping path, which
00:18means anywhere you draw on the canvas, as long as it's visible on the screen,
00:22those bits are going to show up to the user when you draw.
00:25You can create a clipping path using any path, and it's pretty easy.
00:29There's just one function to do,
00:30so you draw out a path normally, and then you call the clip function, and
00:33everything just works.
00:34So imagine we had a photo that looks like this.
00:36We applied a clipping path that looks like this.
00:40So the white area is where the image will show through, and the black area is
00:43where the image will be blocked out.
00:45If we were to draw this image on the canvas using that clipping path, it would
00:49look something like this.
00:51So, only the part of the image that's shown through the open area would
00:54actually be drawn onto the canvas.
00:57Now to do this, you use the clip function.
00:59The clip function creates a new clipping region by calculating how the current
01:04clipping region intersects with the area that's defined by the current path.
01:09And then the new clipping region simply replaces the current clipping region,
01:12because each context can only have one current clipping region.
01:16Now, to do this in code, it looks something like this.
01:17Here is a canvas, and imagine you have some code that looks like this.
01:22So we define a path, and then we make an arc, and then we call stroke.
01:27That usually gives us a circle that looks like this.
01:29If we now go ahead and call the clip function on the canvas context, now drawing
01:35will only take place inside of that arc.
01:38So let's take a look at this in code.
01:40So here I am in the editor, and I've got my snippets opened to my clipping paths region.
01:45I'm going to go ahead and open up my clipping_start example.
01:50So here's what we're going to do.
01:52First, let's go to the snippets, and let's copy the first few lines over.
01:58We'll copy that one, and we'll paste it in.
02:01Then we'll scroll down a little bit, and we'll get the drawImage call.
02:07We'll copy that, and we'll paste that in.
02:09So let's save, and let's see how this looks in the browser.
02:13So I'm going to bring up clipping_start in the browser.
02:16So you can see that the current clipping region right now is the entire canvas;
02:19nothing is being blocked out.
02:20So the entire image is filling the canvas.
02:25So let's go back to the code and that image, by the way, is down here in the document.
02:29So I'm just getting the image and drawing it onto the canvas. We've seen this
02:32already; nothing new here.
02:34Let's go back to the snippets and let's try creating a clipping path.
02:37Let's start by making a circular clipping path.
02:40This is what I just showed in the slides.
02:44So I'm going to paste that in, and I'm going to uncomment these two lines.
02:49So before we run the code, let me point it out.
02:52So this code is going to draw an arc at the center of the canvas.
02:55So we divide the Width by 2, divide the Height by 2.
02:58That gives the middle of the canvas.
02:59It's got a radius of 150 pixels, and it's a full and complete circle.
03:04So that gives us a full circle in the middle of the canvas, and then this
03:07function call right here is the important one.
03:09That creates a clipping region out of the current path.
03:12So let's go ahead and do that.
03:14We'll save, and we're going to refresh. And you can see that the results of that,
03:19we have a circle in the middle of the canvas, and only the part where the
03:23circle is is where the image is being drawn; the image is being masked out on either side.
03:27So that's a pretty simple, easy example, but let's make it a little bit more complex.
03:32So let me go back to the code, and let's go and comment these two lines out again.
03:36Let's go back to the snippets.
03:39Now, let's create an arbitrary clipping path.
03:45So using what we already know and have learned about creating paths can be
03:50applied to clipping paths.
03:51So here, we have a call to beginpath, we have a series of lines, then we close
03:56the path, and then we call clip.
03:59So this is going to create a clipping path out of just some arbitrary path that
04:03I've made with a few line segments.
04:05There's going to be four line segments:
04:07one, two, three, and then closePath will make the final one.
04:11So let's save, and let's click the Refresh button.
04:14You can see that now the clipping region has been changed to the four points
04:18that I've created using a path.
04:20So I took an ordinary path, didn't stroke it--although I could if I wanted to--
04:24and I made a clipping region out of it.
04:26Let's see if it works in other browsers.
04:28So let's go ahead and open this in say Firefox.
04:33You can see, the result are the same.
04:34So in this example, we saw how to take ordinary paths and create clipping
04:39regions, which are masks, through which drawing can take place and outside of
04:43which drawing is prevented.
Collapse this transcript
Drawing images and video
00:00So using the HTML5 canvas element, you can even draw images and video onto canvas
00:05elements in the web page.
00:07You can do this programmatically via JavaScript.
00:10So using the image-drawing functions, you can draw images in a variety of ways.
00:14You can draw them from either an image or a video element that's either in the
00:17page or dynamically loaded, or from another canvas element that's elsewhere in the page.
00:24You can even resize or crop the source image that's being drawn.
00:29So let's take a look at the image-drawing routines.
00:32There are three ways to draw images.
00:34The first one is the simplest.
00:36drawImage takes a source image, and the source image is either an image, a
00:41video, or a canvas, and it draws that image onto the destination canvas at the
00:47point specified by dx and dy.
00:50So that's the destination point where the image will be drawn.
00:53The second version drawImage again takes the source image that you want to draw
00:58and it draws it onto the destination canvas at the location point dx and dy, but
01:04it scales the image to fit into the width specified by dw and the height by dh.
01:11The last version of drawImage takes a source image but also takes two sets of
01:16arguments that specify how the source and how the destination should be drawn.
01:20It takes a source x and source y as well as a source width and source height.
01:25So you can actually draw only a portion of the source image onto the destination
01:30canvas at dx, dy, and the given width and the given height.
01:35So that sounds pretty complex.
01:37It's probably a lot easier to see an illustration of how each of these work.
01:40So let's take a look.
01:42The simple version of this takes the image and dx and dy.
01:46So you have the source image, and then you have the destination canvas, and this
01:50version just simply takes the source image and copies it directly onto the
01:54destination canvas at the dx, dy point.
01:57The next version up from there takes the image and draws at the location, but
02:02optionally scales it.
02:03So once again, you have the source image.
02:05You have the destination canvas. But in this case I've drawn the image onto
02:09the canvas at the destination point. But in this case it's been scaled to be a little bit larger.
02:15You can also scale it to be smaller.
02:16Now, the last example is a little bit more complex.
02:19So it takes the source image and optionally a portion thereof and draws it onto
02:26the destination canvas.
02:28So here you have the source image and the destination canvas right there.
02:33But now, you've got only a portion of the image that you are copying.
02:36So you copy that portion onto the destination canvas specified by the
02:42arguments that you pass.
02:44Let's take a look at these in action and see how they work in the real world.
02:48So here I am in my example.
02:52This is the snippets, and I've got my images_start file open.
02:56So the first example I'm going to show is just drawing an image directly onto the canvas.
03:02So I'm going to copy, and I'm going to come in here and I'm going to paste.
03:08So what I'm going to do is get the image element by using getElementById and
03:13then just simply draw that image right onto the canvas.
03:16So let's scroll down here in the document, and you can see that I've got this
03:20image down here as well as a video, and this is the source for that image.
03:26And you can see that I've got both of these elements are set to not display, so they
03:30don't show up in the web page when we have them in the browser.
03:34So let's take a look at each one of these.
03:36So, here are the images.
03:38So this is the image I'm going to be using--
03:40that's a nice little shot of Lake Tahoe--and this video right here.
03:44So I'm going to draw this video onto the canvas, and it's just a basic video. So, that's that.
03:51So let's take a look at the first example. Scroll back up.
03:55Again, pretty straight forward. Just get the image and draw it onto the canvas.
03:59So we'll save and you can see it works.
04:02So the image is being copied and then pasted onto the canvas.
04:06Let's take a look at another example.
04:08So for the next example, I'm going to draw the image scaled down onto the canvas
04:14using the second version of the drawing routines.
04:18So I'm going to get rid of this one to avoid any competition. There we go!
04:24Let's get rid of that comment.
04:27So now this is the second version of the drawImage function. So, same idea;
04:31draw out in a location, but scale it down.
04:33In this case, it looks like I am going to scale it down by about half.
04:36So I'll save and refresh.
04:39We can see that that worked, and in fact let's try it in another browser.
04:46Let's open that in Firefox. Yup!
04:48So that worked as well.
04:49Let's go back to the code. All right!
04:52So for the next example, now we're going to draw just a portion of the source
04:57image onto the destination canvas.
05:00So I'm going to copy that, go back to the sample, and paste.
05:07So what we're going to do is specify a rectangle that starts in the source
05:13image--so we have the source image right here.
05:14We're going to copy from this portion of the source onto this part of
05:20the destination canvas. So, let's save.
05:23What we're going to do is just get a copy right here.
05:26This little island is going to be what's taken out of the source image and drawn.
05:31So we refresh.
05:33We can see that that's what happened.
05:35Let's go back to Firefox, do the same thing, Refresh.
05:38You can see that in both cases a portion of the source image was essentially
05:43cropped and drawn into the destination canvas. And then for the last example,
05:49let's actually draw some video.
05:50Now, drawing video is a little bit challenging because you can't just simply say, hey,
05:56draw this video.
05:57The drawImage function is going to draw whatever the current playback
06:03frame happens to be.
06:04So here's how we need to do this.
06:06First, let's scroll down.
06:09So, here's the video.
06:10The video tag is right here. And you can see that it's set to loop, and
06:14it's currently hidden.
06:15It's also not playing.
06:16There's no auto-play in here.
06:18So what we are going to do is get the video element, tell the video element to
06:25go ahead and play, and then we're going to set a interval function, which is
06:29going to be called every 16 milliseconds.
06:32So every 16 milliseconds, we're going to get the canvas, get the drawing
06:37context, and get the video element, and then we're just going to draw the image
06:42from the source video directly onto the canvas.
06:45So this will grab each frame as it's being played, every 16 milliseconds,
06:48and draw the video. So let's save.
06:51Let's refresh.
06:55So what's happening is the video element is actually down here, and this is the
06:57canvas. But the interval function is being called every 16 milliseconds which
07:01gives us the frame rate that's needed to play the video back.
07:04So let's try it out in Safari because we haven't picked on Safari yet, and we can
07:11see it's working in Safari as well.
07:13So, what have we seen?
07:14We've seen ways to draw images onto the canvas, and we've seen ways of drawing
07:19source portions of the image.
07:21We've seen how to resize images, and we even saw how to take video content from
07:26a video element and play it back on a canvas.
Collapse this transcript
7. Advanced Canvas Drawing Operations
Transforming objects using the translate tag
00:00In this chapter, we're going to look at some pretty advanced canvas operations,
00:03and in fact some of these are not necessarily routines or features that cause
00:08any drawing to happen, but they certainly do have a profound effect on the
00:12results of drawing operations that you learned about earlier on in the course.
00:16And so we're going to start off by looking at transformations.
00:20Transformations are essentially a way that affect how objects are drawn to the
00:24canvas to achieve some pretty common, but yet difficult to program, effects.
00:30There's three basic transformations that the canvas provides.
00:33There's translate, scale and rotate, along with a way to define your own
00:39free-form transforms.
00:42Transforms affect all of the drawing operations that come after them, and they are additive.
00:49Each transform is added to the effects of the previous one.
00:54So just like other global canvas properties, like line width and so on,
01:00transforms affect everything.
01:01You define a transform, you use it, and then you perform some
01:05drawing operations.
01:06Now, because they are additive, this is where saving and restoring the canvas
01:11state can really come in handy.
01:12Let's start by taking a look at the translate transform.
01:17It's the simplest one to use, and all it really does is moves the canvas origin
01:22to a new location. And the way you do it is by calling the translate function
01:27with an amount to move the origin in the X direction and an amount to move the
01:33origin in the Y direction.
01:35So let's imagine for a moment you have a canvas and at the upper left of the
01:38canvas, that's the current origin point. That's where 0,0 is.
01:42If you use the translate function to move the origin by an amount X and Y, then
01:48all you have done is move the location of the origin.
01:53So now, anything drawn at 0,0 will be drawn at this point on the canvas
01:58instead of this point.
02:00So let's take a look at how that works.
02:01I'll go into the code.
02:03So here we are in my editor, and in the snippets file, I'm under the
02:08Translate Transform section.
02:10So let's open up our example, and we're going to go to the Advanced folder, and
02:16we're going to go to the translate_start example.
02:21So what we're going to do is copy some code, and we're going to come in here and
02:25copy this over, copy, and we're going to paste.
02:32So before I show you what the example does, let me just comment out this call
02:36to translate, and we will save and we will go over the browser and look at the results.
02:41So, let's bring this up.
02:43So you can see that I'm drawing a blue rectangle at the origin point 0,0 right here.
02:48So if we go look in the code, you can see that there it is. It's at 0,0.
02:54It's 100 pixels wide and 50 pixels high.
02:57Now, if I uncomment the call to translate, what I'm doing here is calling
03:03translate and I'm getting the width of the canvas and dividing it in half, and
03:07I'm getting the height of the canvas and dividing it in half.
03:10So this will pretty much move the origin of the canvas right to the middle, half
03:17the width and half the height.
03:18So when I call fillRect again, even though I'm calling it to draw at the 0,0
03:24location, the origin has now been moved to the middle of the canvas.
03:28So the second rectangle will be drawn at the middle point of the canvas.
03:33So let's save, and let's go back to the browser, and let's refresh.
03:38So you can see, I've got two rectangles. They are both drawn at 0,0.
03:43But in the first example, 0,0 is up here, and then after the call the
03:46translate, 0,0 moves to here.
03:49So this can be pretty useful when you are creating a whole bunch of objects to
03:53be drawn on the canvas at different locations and the results of those
03:57locations are arrived at via various calculations and so on.
04:01Rather than having to keep track of all of those points, you can just simply
04:04move the origin to where you need it to move to, do your drawing, and then set
04:08it back to its previous state.
04:10So in this example, what we've seen is how to use a basic translate transform to
04:15move the origin around and affect where objects are drawn.
Collapse this transcript
Scaling objects with the scale transformation
00:00The scale transformation causes drawing operations to be multiplied by a scale
00:06factor in the X and Y directions. And you can scale operations in the X and Y
00:14directions independently.
00:15You can provide a scaling factor for X and a scaling factor for Y.
00:19So the way that scale transformation works is pretty simple. So suppose I had a
00:24rectangle that was 20 pixels wide and 10 pixels high.
00:29Well, if you put that through a scale transform and I pass in say a factor of
00:342 for both the X and the Y direction, the result of that would be, if I call
00:40the same function, even though I said fill the rectangle with 20 pixels wide
00:44and 10 high, because of the scale factor, this would be 40 pixels wide and 20
00:49pixels high. So let's take a look at that in code and see how it works.
00:53So here I am in the code editor, and I've got my Scale Transform section of my
00:58snippets. So let's open up our scale example.
01:04So here is our scaling code.
01:06Let's go back to the snippets. So I'm going to copy this guy over and paste.
01:18So, a couple of things I want to point out.
01:20First, I'm using the blue fill style to fill the rectangle at the 0,0 location.
01:26So what I'm going to do now is perform a scale transform and draw the same size rectangle
01:32again, only at a different location.
01:35So here you can see the width and the height of the same.
01:37I'm just offsetting this rectangle so we can see it.
01:40I'm also using the save and restore in order to save the drawing context of the
01:46canvas and restore it after doing any drawing.
01:50So let's save. Let's go out to the scale_start. So you can see, here is
01:55the rectangle, right.
01:56Here is the first one. Here is the second one.
01:58Now they're both being told to draw at the same size, but because of the scaling
02:02factor, this one is larger.
02:04So let's take a look at where save and restore canvas state come in handy.
02:09So suppose these weren't here, and suppose I had another call to scale, only in
02:17this case I want to scale things down.
02:20So I would say, instead of 1.50.5-- and let's change this one to 0.5 as well, and
02:29I'll do the same thing with the fillRect, and in fact I'll offset this one a
02:33little bit--325--so we can see it.
02:36Now let's go over to the canvas and see what happened. We'll refresh. Actually, I
02:41should probably move it a little bit more.
02:48So you can see that the scale factor is not really affecting this the way that
02:54we'd expect it to, because what's happening is I'm first doing a scale-up and
02:59then a scale back down.
03:00If I put save and restore around this, watch how that changes things.
03:11Now we save, and then we go back out. Now let's refresh.
03:18See, now things are really being shrunk down.
03:21So what was happening was, since I was calling this scale function after this
03:27one--remember, transforms are additive.
03:29So I go from a scale factor of 1 to a scale factor of 1.5 and then 2. Then I go
03:37to scale factor of a half.
03:39Well, that only cuts this scale factor in half, not the original one. But by
03:44putting the save and restore around it, this scale function operates on the
03:49drawing context's regional scale factor, which is 1 and 1 in both the X and Y directions.
03:55So now we've seen how to use a scale transform and we've even seen how to use
04:00save and restore to save the canvas's drawing context so that transforms don't
04:05interfere with each other.
Collapse this transcript
Rotating objects with the rotate transformation
00:00Rotate transforms cause subsequent drawing operations to be rotated by a given angle.
00:06And remember, whenever we say angle in canvas, we're talking about radians;
00:09we're not talking about degrees.
00:11It's also important to note that rotation takes place around whatever the
00:15current origin of the canvas is, not the center of an object that you're about to draw.
00:21If you want to rotate around an object's center, or for that matter around any
00:26point on a particular object, you should use the translate transform to move the
00:31origin to the object center or whatever point you want to rotate around, then
00:35rotate, and then translate the origin back.
00:38The rotate transform just takes one argument, and that's the angle argument.
00:43The angle specifies the amount to rotate the drawing operations that come after
00:48you set the rotation transform.
00:50Remember, that's radians, it's not degrees.
00:52So let's jump over to the code and take a look at rotate.
00:56So I've got my Rotate Transform snippets up here, and let's open up the rotate
01:03example. So, a couple of examples to show.
01:08First, let's do the simple one.
01:10We'll copy and we'll paste.
01:16So what I'm doing here is causing the fillStyle of the context to be blue, and
01:22I'm going to fill a rectangle at 153, so X is 150, Y is 30, and the rectangle is
01:29100 pixels wide and 50 pixels high. And then after that I'm going to rotate by
01:34half a radian and then draw the same rectangle again at the same location.
01:39So let's save and let's bring this up in the browser.
01:44So you can see that what happened was the first rectangle was drawn with no
01:48rotation. The second rectangle, however, was rotated by half of the radian in
01:53the clockwise direction. And you can see that if you were to draw a straight line
01:58from the top of this rectangle, it would go almost to where the origin is,
02:02pretty much the same point that this one is pointing out right here.
02:05So rotation did not take place around the center of the object;
02:08it took place around the origin up here.
02:11So if we wanted to say rotate an object around the center of itself, we'd have to
02:17first change the origin to the center of the object, then rotate it.
02:22So let's go back to the code and see if we can do that.
02:23So let's go back to the snippets, and let's take this example.
02:30We'll go back to the rotation. So we'll get rid of this one, and we'll replace it with a new one.
02:37Let's take a look at what's going on here.
02:38So I'm actually combining two different transforms here to achieve a particular effect.
02:45So I start out by translating the origin from the upper-left corner to the exact
02:52middle of the canvas.
02:53So I divide the width in half, divide the height in half. That gives me the
02:56middle. Then I calculate a radian equivalent to a 20-degree rotation.
03:02Then I have this for loop, which start at 0, goes to 3600, and increments the
03:09degrees by 20 degrees each time.
03:12So I've divided this up into a certain number of steps, in this case 18,
03:17and each time we step, we're going to rotate by this radian, which is a 20-degree rotation.
03:23We're going to stroke a line each time, so let's see what that looks like.
03:27So I go back over here and I refresh, and you can see what's happened is the
03:32original line that I drew right here, has been rotated around itself in a series
03:37of 18 steps, 20 degrees each time.
03:40So again, what's happening is I've translated to the middle of the canvas.
03:46Then I have a call to move to, which moves me 100 pixels negative, which means it moves
03:52me to the left in the X direction, and then I lineTo 100 in the positive X
03:58direction. So I'm creating a 200-pixel-long line centered about whatever the
04:03current origin is, which is in the middle of canvas, but it's rotated each time.
04:07Each time to this for loop, I'm rotating by an additional 20 degrees.
04:10That's this radian right here.
04:12So for 18 steps, we rotate, and that's what causes each subsequent draw of the line to
04:18be drawn through the new origin but rotated each way.
04:22So this example shows us how to use two transforms together to achieve an
04:25effect, as well as using the rotate transform to rotate objects around the
04:30origin of the canvas.
Collapse this transcript
Applying a custom transformation
00:00The last transform we're going to take a look at is the custom transform.
00:03Now in addition to the transforms that are built into the canvas, you can
00:06also define your own.
00:09Transforms are defined as a matrix.
00:12A matrix has the format that you see here.
00:14There are six variables.
00:15There is a, b, c, d, e, and f. And to use a transform, a new point is found
00:22by applying that transformation matrix to each point in the image that's being transformed.
00:29Now, you don't need to panic.
00:31I'm not going to make you learn matrix math, but this does come in handy when
00:35you want to apply a transformation that is not built into the canvas.
00:39So, for example, canvas gives you transforms for rotation, scaling, and
00:44translating, but there are plenty of other transforms out there that you might
00:47want to use, and since they are not built in, you would have to use a matrix
00:50like this to define one.
00:52So we'll see examples of that in a moment, but the way that you apply a custom
00:55transform is by using one of the two transform functions.
01:00The first one is simply called transform, and it takes these six arguments, which
01:04correspond to the variables you see in this matrix here.
01:07The transform function takes the transform you're defining here and adds it to
01:12whatever the current transform of the canvas currently is.
01:17So if the canvas already has a transform, like a rotation or a scale or a
01:21resulting transform from a series of transforms that came before it, then this
01:25one will simply be added to that one,
01:27because remember, transforms are additive.
01:29The second one is called setTransform, and it takes the same six arguments.
01:34The main difference between setTransform and transform is that setTransform
01:39resets the canvas to be what's called the identity transform, which is a
01:44transform that just doesn't do anything.
01:46So in other words, it erases all the previous transforms and then applies the
01:51one you're defining here.
01:52So this one is additive.
01:54This one is not additive.
01:56This one resets the canvas and then apply the transform that you're defining.
02:00Let's take a look in the code to see how this stuff works.
02:04So here I am in the code.
02:05I've got my snippets file open, and I'm at the custom transform area, so let's
02:11open up our custom transform example.
02:14It's called transform_start.
02:16Let's do something simple that we've already seen before.
02:20So, let's first copy these two lines, and we'll paste those in.
02:25Now, you've seen this already. Basically, we just take a blue rectangle and put
02:29it on the canvas, so let's just make sure that that works, and it does work. That's good.
02:33All right, so let's go back to the code.
02:35What we're going to do now is recreate the translate transform using our custom transform.
02:43So we'll copy this and we'll paste it over, and I'll explain how it works.
02:48So a translation matrix for a translate transform looks like this.
02:53Those six variables are right here. And the first row is 1 0 and then the amount
02:59you want to translate the x by, and then the second row is 0 1 and the amount
03:04you want to translate y by.
03:05So remember, the variables go in the order of a, b, c, d, e, and f. So let's
03:11define that transform.
03:12We're going to make the new rectangle red, so that's the fillStyle there.
03:16Just like in the translate example, we're going to translate the rectangle to
03:20the center of the canvas.
03:22So tx is going to be the width of the canvas divided by 2. The y will be the
03:26canvas height divided by 2--
03:27that gives us the middle of the canvas. And then instead of using the translate
03:31function, we're just going to call the transform function, and we pass in 1, 0--
03:35that's these two right here--then 0, 1--that's these two right here--and then tx and then ty.
03:41That will add this translate transform to the canvas, then we'll fill the
03:46rectangle, and then we'll call the reverse transform, which translates us back
03:51to the upper left of the canvas--just in case we had any drawing that came after this.
03:57So we save and then let's go to the browser and let's refresh. And you can see
04:02that the blue rectangle is drawn at 0, 0. The red rectangle is also drawn at 0,
04:070, but the new origin has now been translated to right there.
04:11So that seems to have worked fine.
04:12Let's go back to the code.
04:13So you can see right there, even though the rectangle is placed at 0, 0,
04:17because of the translation, the origin was moved to the middle of the canvas.
04:21Let's create a new transform.
04:23So now we're going to go back to snippets, and we're going to copy this example.
04:27Okay, so we copy and we'll come over here and we'll paste.
04:34In this example, we're going to create what's called a skew transform.
04:38Now a skew transform--sometimes it's called a shear transform--and in this case
04:42we're going to have a green rectangle and we're going to shear the objects using
04:46various directions x and y. So, a skew transform is defined by the number 1 and
04:52then the amount you want to skew in the y direction, then the amount you want to
04:55skew in the x direction, the number 1 here, and then these two are left at 0.
05:00So we're going to use a green rectangle for this one. And the skewing factor is
05:03defined by a multiplication factor, so I'm going to multiply by 0.2 in the x
05:07direction and I'm going to leave the y direction alone.
05:10Now in this case, I'm going to use the setTransform function, and remember, this
05:14resets whatever the transform is that's currently on the canvas.
05:19So, I don't have to worry about any transforms that came before me. And then
05:23we're going to fill the rectangle at this location, the point 250 by 20, and it
05:28will be 100 wide and 50 high.
05:30So let's save, and let's go back to the browser and let's refresh.
05:36You can see now that I've drawn a green rectangle that's been skewed in the X
05:40axis direction, so it's been sheared a little bit.
05:43Let's make some changes and see how that works. Let's go back to the code.
05:46I can increase the amount of shear. I can say this is 0.4, and let's refresh the browser now.
05:53You can see that the shear amount got a little bit more.
05:55All right, let's try it in the y direction.
05:58So I'll set this to 0, and we'll make this 0.3 and we'll save and we'll refresh.
06:05And you can see that this time the rectangle got sheared in the Y axis.
06:10Now what we have done here is create a new transform that is not built into the
06:14canvas. And just for good measure, let's make sure it works in other browsers.
06:19So we'll bring this up in Firefox, and you can see, the effect is the same.
06:26Let's bring it up in Chrome, and you can see the effect is the same there, too.
06:33So what we have learned here is how to use the custom transform matrix to
06:37recreate a transform we already know how to use, but we also saw how to create a
06:41new transform that's not built into the canvas.
06:45You can look up all kinds of transform matrices on the Internet and just plug in
06:49the values into that transform function. And doing so, you can create transforms
06:54that are not built into the canvas that you can use in your own drawings.
Collapse this transcript
Compositing in Canvas using globalAlpha
00:00In this section we're going to talk about the canvas compositing methods and the
00:03global alpha setting.
00:05The canvas context has a setting for what's called the global alpha, and that's
00:10the opacity setting that affects all of the drawing operations that happen on the canvas.
00:13There's also a setting for what's called the default compositing method, and that
00:19affects how new content is drawn onto the canvas surface and how it is
00:23potentially affected by the content that's already there.
00:27Now, to use the global alpha, you simply set the context.globalAlpha property to
00:31a value from 0.0 to 1.0.
00:34The default being 1.0, which means full opacity.
00:37Now there are 12 different compositing methods, and I've illustrated them
00:41here for you to look at.
00:43The first is called source-over, and this is the default.
00:47Basically, what that means is every time you draw something new, it gets drawn
00:51on top of what's already there, which is pretty much the behavior you'd expect.
00:55Each time you draw a new shape, you'd just expect it to appear on the canvas,
00:59on top of everything that came before it.
01:01The next one is source-in.
01:02You can see that what's happening is the drawing is only taking place where
01:07there's already content on the canvas.
01:10So in this case, the green rectangle is only showing up where there are already
01:13portions of the blue rectangle.
01:15Source-out is just the opposite.
01:18The newly drawn object, the green rectangle, is only showing up where the blue
01:22rectangle is not, where they don't overlap.
01:25The source-atop is kind of like source-in, except that it leaves the original
01:31content in its place.
01:32The source-in left only the new content; source-atop leaves the old content plus
01:38the intersection of whatever the new content was.
01:41The lighter compositing method takes a look at the intersection of the new
01:45content and the old content, draws the pixels in a lighter color of what they
01:50would have been normally.
01:52The xor or exclusive or drawing operation, or compositing method, takes the new
01:58content, intersects it with the old content, and then clears the area where the two overlap.
02:04The second row shows some other operations.
02:07The destination-over is kind of like source-over, only that the new content is
02:12drawn, but it's clipped by what's already there.
02:15Then there's destination-in, which is kind of the opposite of source-in.
02:19In this case, only where the two overlap is the content drawn, but the new
02:24content is left out and the old content is kept.
02:27In destination-out, that's the opposite of destination-in, so wherever the
02:31two don't intersect, that stuff is left, but all the other content is removed from the canvas.
02:36Destination-atop is the opposite of source-atop.
02:41In this case, the new content is kept, along with whatever the old content was,
02:46as long as it intersects with the new content.
02:48Darker basically says draw the new pixels but make them darker instead of lighter.
02:53And then copy means just draw the new content;
02:57anything that was already on the canvas is removed and only the new drawing
03:00operation is what wins.
03:02So let's go over to the code and see these in action.
03:05So here I am in the code and on the snippets I've got my Global Alpha snippet.
03:10So let's go ahead and copy this over.
03:15First, I want to copy a bunch of definitions, and what I'm going to do is
03:18paste that in here.
03:19Okay, so I've got my globalAlpha.
03:22It starts off at 1.0, and that's the default value, but we're just going to set
03:25it anyway for purposes of illustration.
03:28Then I have an array of rectangles. So, I've got 1, 2, 3, 4, 5, 6, 7,
03:32I've got 8 rectangles all defined at different locations. They overlap each other.
03:38So let's go ahead and get to drawing.
03:40I'm going to copy that in.
03:45So this for loop will loop over this array of rectangles and draw each
03:51rectangle on the canvas.
03:53So for the moment, I'm going to comment this line out.
03:55So you can see that the rectangles are being drawn.
03:57There's a blue one and a red one.
03:59I'm drawing them down the canvas here.
04:01So let's go put that line back in.
04:02So each time through the loop, the globalAlpha is going to be reduced by 0.3.
04:07So let's see what effect that has.
04:10The opacity changes, for each time through the loop and the drawing operations
04:14get lighter and lighter.
04:16Just to make sure that that works cross browser, let's go ahead and open this up in.
04:21let's say Firefox. Sure enough, it works.
04:23Now, let's take a look at some compositing operations.
04:26So I'll go to my snippets and here's my Compositing example.
04:35Copy this and paste it in.
04:37So one of the things that I want to point out here is that because some of these
04:41drawing operations affect the current canvas content, what I've done is made a
04:47whole row of separate canvases to show each example.
04:51So I've got two rows of six canvases, each one is 150 x 150, and we're going to
04:58draw in each one of those guys.
05:00So here are all the compositing methods as strings--source-over, source-in and so on.
05:06All 12 of them are there.
05:07I've got two rectangles, and each one of these rectangles is going to be drawn in
05:13each one of the canvases.
05:16So, I have an index variable that's going to keep track of what compositing
05:20method we're currently drawing, and then I have a loop.
05:23So I'm going to start at 0, loop over the array of compositing methods. Each
05:27canvas is identified by the name canvas + an integer.
05:31So you can see there is canvas1, canvas2, canvas3.
05:34So I'm going to get each canvas, get its drawing context, and draw two rectangles:
05:38one blue and one green.
05:40So I'm going to draw the first rectangle, then set the composite operation right
05:44there, to whatever the composite method is, and then fill the second rectangle.
05:49So let's go ahead, save this.
05:53Let's go back to the folder here, fire up compositing_start.
05:57You can see that each one of the rectangles is being drawn, and we are getting
06:03the same results for the compositing method as I showed in the slides.
06:08Let's go over to Firefox and see how it looks there. It looks pretty good.
06:13And just for good measure, let's try it out in Chrome as well. Looks right.
06:21So in this example, we saw how to use compositing methods, we saw how to use the
06:25global alpha to affect drawing operations, and we can see how we can draw content
06:29onto the canvases using a variety of methods that affect the source and
06:34destination content.
Collapse this transcript
Manipulating raw pixels
00:00Probably one of the coolest and most powerful features of the HTML5 canvas is
00:05that your script can now get access to raw pixel data on the canvas and
00:11manipulate the pixels directly.
00:13You can access the individual pixel data as an array of bytes on the canvas.
00:19Then this data can then be manipulated and put back into the canvas.
00:24Every image in a canvas, and in fact this is true of all canvas content, is
00:30composed of four-byte-wide pixels.
00:33So let's imagine we had a picture like this on the canvas and we looked at an individual row.
00:39So that individual row would be made up of pixels, starting at the left-hand
00:43side over here and continuing all the way over to here.
00:46Imagine each pixel is a little box going across the row.
00:49Well, each one of these pixels is made up of a four-byte combination.
00:54There's a red, green, and blue component of that pixel along with the alpha setting.
01:00So by getting access directly to these bytes, we can manipulate how the image
01:06looks in the canvas.
01:08So if we were to calculate the size of that image data array, it would be the
01:13height of the image, right, so this height here, times the width, times four--
01:17because remember each one of these pixels is four bytes wide.
01:20So to get the number of bytes, you'd multiply the height, times the width, times
01:24four to account for the four bytes that make up each pixel.
01:29Now one of the things I should point out here is that this is an obvious security issue.
01:34If any willy-nilly script could just get access to the image data on a canvas, it
01:40could surreptitiously send it back to another web site or another web server.
01:45So, for security reasons scripts have to come from the same origin.
01:50If a script wants to try to access the content of a canvas on the web page,
01:54then the script had to have come from the same origin as the web page itself;
02:00otherwise, it is denied access and the browser raises a security exception.
02:05So what are the functions for accessing image data?
02:09Well, we have a couple things we can do.
02:11We can get the width and height of the canvas pixel data.
02:15There is also a data property, which is a single-dimension array of all the raw pixel data.
02:22This is the big array that has all the bytes of the image.
02:26We can create new image data from scratch. So this is createImageData. There are two versions.
02:32One takes a width and a height; the other one takes an existing image data
02:36structure and creates a new one from it.
02:38We can also get image data, and we can get image data within the given bounds.
02:43So starting at the source canvas, we can start at source x and source y point and
02:49given a width and a height, we can get a portion of the image data.
02:53We can then do whatever we want with the image data and put it back
02:56using putImageData.
02:58Now putImageData puts the modified image data specified by image data back into
03:03the image at point dx and dy.
03:06These arguments here--dirtyDx, dirtyDy, dirtyW, and dirtyH--
03:12these are all optional and they specify what's called a dirty rectangle.
03:17Now if a dirty rectangle is supplied, then only the bits inside that
03:21rectangle are updated.
03:23So let's take a look at a real-life example of using the image data access.
03:28So here's my code, and here in my snippets
03:31I've got my rawdata example, and here's my rawdata file.
03:36Now, one of the things I want to point out is that I'm running this from a web
03:40server that happens to be located on my machine.
03:44So here you can see in the browser, I've got localhost accessing this file.
03:48Again, that's so that the browser has a domain to go off of when it's running my
03:53script code and trying to access the image data.
03:56So if you want to see this example work, all you need to do is run it from a
03:59real web site. It doesn't matter if it's localhost or whatever web site you
04:02usually work on; you can just simply run this by loading up the local file in the browser.
04:07So let's go back to the code.
04:09So let's go to the snippet, and what I'm going to do is copy this first example here.
04:17So, let's scroll down a little bit.
04:21Here is the source image that I'm going to be manipulating, and it is this image right here.
04:29So what I'm going to do is go back to the source.
04:34So what we are doing is getting the element out of the document, and then we're
04:38going to simply draw the image onto the canvas.
04:41So let's make sure that that works first.
04:43So let me refresh. Okay, so that's working.
04:45So we're taking the source image, drawing it onto the canvas, and everything is fine.
04:49That's no big deal;
04:50we've already seen that before. So let's go back to the code.
04:52So, let's do something interesting to this image.
04:56Let's get the image data and do some manipulation to it.
05:05Paste. So let's take a look at what the code does that I just copied in here.
05:10What we're going to do is get the image data and every 15th row of the image
05:15we're going to convert into a five- row-high strip of inverted pixels.
05:22So we're going to take whatever the pixel value is and invert it.
05:28I've got a couple of variables here.
05:31I've got a variable that's tracking the current row, and I'll start it for row 0.
05:35And then I have the maximum row, which is the same as the canvas height.
05:39Then I get the image data by calling the ctx.getImageData function, and to get
05:45the image data, I want all of the image data.
05:47I want from the upper-left corner down to the bottom right.
05:50So this will get me all of the bytes in the image. And then from the image data
05:56that comes back, I want the data property, because this is the array of bytes, and
06:00I'm going to store that in a local variable named pixels.
06:04So now, I'm going to loop over every row in the image.
06:08So I'm starting off at row 0. While the current row is less than the maximum row, I'm
06:13going to have a five-row-high strip.
06:16So I have this local counter named i, which is going to count to our five rows.
06:21Now remember, to get access to each one of the rows' bytes, which is what this
06:25variable right here is going to keep track of, I need to take the current row,
06:30add the local row counter.
06:32So we're going to start off at 0 and then go 0, 1, 2, 3, 4, 5 then go to the
06:37next row, and so on.
06:38So, to get to the current RowBytes, I have the current row times the canvas
06:42width, times four, because there's four bytes in every pixel.
06:47So this will move me to the beginning of each row in the image, in the byte array.
06:53Once I've done that, I then need to loop across all the bytes in that particular row.
06:58So we start off at 0, and then we go to the canvas width times four, so that's all
07:03the bytes. And we're going to increment j by four each time, because we need to skip
07:07over each pixel's four bytes. So to skip over a pixel,
07:10let's just skip over four bytes.
07:12So each time through this loop, we're going to say that the pixel's content at
07:17thisRowBytes plus my index is equal to the number 255, because that's the
07:24maximum value of any given byte, minus whatever's currently in there.
07:28We're going to that for the red, the green, and the blue components of each one of the bytes.
07:33We're not going to do anything with the alpha channel, although we could choose
07:36to, but we're not going to right now.
07:38So we're basically going to invert all of the pixel values.
07:42Then after we've done that, we increment the current row by 15, so we skip over
07:47to the next 15 rows, and we let this remove complete.
07:50So by the time this loop completes, every 15th row will have a four-row-high strip
07:57of inverted pixels. And when that's done, we simply call putImageData to put the
08:02image data back into the canvas. So let's save.
08:06Let's refresh. You can see that what happened here is you've got five rows where the pixels are
08:12all being inverted from their original colors.
08:16So here is the source image,
08:17here's the canvas and our loop has gone through and inverted every 15th row of
08:24a five-row-high pixel strip.
08:26We could stop there, but let's go for the extra point.
08:29Let's try using the optional dirty rectangle, and remember this only affects the
08:35bytes that are inside this rectangle.
08:38So I'm just going to say 50, 50, and let's make the rectangle 400 pixels wide.
08:46Let's make it 200 pixels high.
08:49So we'll save, and we will refresh.
08:52See that now only the pixels inside of that rectangle are the ones that got affected.
08:57So in this example, we've seen how to get access to the raw image data of a
09:01canvas, manipulate the pixels, put them back in, and optionally only affect a
09:06certain range of pixels by a rectangle.
Collapse this transcript
8. Building Practical Examples
Building an image slideshow control
00:00So we have reached the point now where we can use what we've learned on the
00:05HTML5 canvas to start building some real live useful stuff and one of the first
00:09things that we are going to build is a slideshow.
00:11So let me show you what the slideshow looks like when it's finished.
00:16So this is a fairly typical slideshow.
00:20You can see the images are rotating.
00:21There are four of them.
00:23So when we reach the last one, after a few seconds it goes back to the first one.
00:27These images are all being drawn on a canvas, and there is a few-seconds
00:31delay between each one.
00:33So let's see how to go and build this.
00:36So I'll close this, and we will open up the start version in my editor.
00:43So this is SlideShow_start.
00:45Let's go over to the snippets.
00:46You can see this is way the snippets are.
00:48I am under the Slideshow section.
00:50So let's get started building the slideshow.
00:53So I have got an empty document here with a placeholder for the script.
00:57So I am going to copy these first few lines and paste them in.
01:04So this is just some initialization and setup code.
01:08So let's just take a quick look at it.
01:10I have an array here that has paths to all the images that I am going to show in the slideshow.
01:17I have a couple variables that refer to the slideshow canvas and its context, and
01:23I am creating a new image element using the DOM, and I have a little indexer here
01:27that keeps track of what the current image is.
01:31So that's just the setup stuff.
01:33Then we have a function, and we will copy this over.
01:40So now we are setting a function to run when the window loads. And the first
01:45thing we do is get the reference to the canvas. We've done this before throughout the
01:50title, and here we have the reference to the canvas's context.
01:56The first thing we do is set the width and height of the newly created image
02:01element up here to be 600 x 400, which is the size of the images.
02:07Then we have a function call to switchImage, which we will write in second, and
02:11then we have an interval which we are going to use to switch the image every
02:163,000 milliseconds, or three seconds.
02:20So let's go ahead and copy that over.
02:22So now we have the switchImage function.
02:33So the switch image function simply sets the source of the image object to
02:40whatever the current image indexer is looking at in the array of image paths.
02:46So it's going to cycle throughout. Here is the path.
02:48It's going to start at 0 and then go to 1 and then go to 2 so on and so forth.
02:52So the switchImage is responsible for doing the heavy lifting of the example.
02:57It displays the current image and looks at the image in the array that's
03:04currently being indexed by the currentImage counter.
03:06So up here we have the image paths 0, 1, 2, and so on.
03:11So the first thing it does is sets the source attribute on the image object to
03:15whatever path is being looked at by the currentImage counter.
03:19When that image loads we have a function that runs, and it checks to see if the
03:23current image is greater than the length of the image path's array, because if it
03:28is, we need to be reset it back to 0 so it starts at the beginning again.
03:31Then we simply call the drawImage function on the canvas context to draw the
03:36image at the location on the canvas, starting at the upper-left corner and with
03:41the given width and height.
03:42And then, because of this interval, the switchImage function is going to be
03:46called each time the interval timer goes off, which we've set to three seconds.
03:51So, every three seconds the image counter gets incremented, we look at the next
03:55image, and we set the canvas context to draw whatever the current image is.
03:59So let's save, and let's go back to the browser.
04:03If everything goes right then, yup, you can see every three seconds that image is
04:07going to change.
04:09This is the last one here.
04:10So, after three seconds it should go back to the first one, and it does.
04:13That's a pretty simple example of using an interval timer and the canvas's
04:18drawImage function to create a slideshow.
Collapse this transcript
Using smooth transitions in a slideshow
00:00In this example, we are going to see how to use smooth transitions to improve
00:05upon the previous example where we built an image slideshow control.
00:10So what I am going to do is open up the SlideShowSmooth_finished example and
00:15show you what I mean.
00:16In the other example, the transitions between the images were pretty abrupt, but
00:20you can see that what we are doing here is gradually fading in each image to
00:23create a nice smooth transition.
00:25So let's see how to do that.
00:27So I am going to open up my SlideShowSmooth_start example.
00:32This is our starting point. And let's go back to the snippets.
00:36So the setup code is the first few lines we are going to copy over.
00:41So let's paste that in.
00:43So I have an array of all the image paths and then variables that refer to the
00:48canvas and the canvas context.
00:51Then I create an image that's going to be responsible for loading each one of
00:54the images from the local folder or from the web.
00:57I have an indexer here that keeps track of which image we are looking at, and
01:01then finally, a variable that's going to be the timer that smoothly reveals each image.
01:07So it is called the revealTimer.
01:08So let's go ahead and copy over the initialization logic, and that's
01:12this function here.
01:14So let's paste that in.
01:15So when the window loads--and that's this function right here.
01:19So when the window loads up, we are going to get a reference to the canvas
01:24and the canvas context.
01:26Then, on the image, we are going to set the height and width to be the height and
01:29widths of the images that we are going to be loading.
01:32Then we call the switchImage function, which shows the first image, and then we have
01:37we have an animation that waits every three seconds, which is 3,000 milliseconds, to
01:41change to the next image.
01:43So we will save that.
01:46Now we need to copy over the two functions that are the meat of how this works.
01:51So let's copy over switchImage, and I'll explain that one.
01:56Now the switchImage function basically looks at the current image index, gets
02:01its path from the images array, and then sets the source attribute of the image
02:06object that we created up here using the DOM, right there, to be pointing at the
02:12source for whatever the current image index is.
02:16Then we have a little check right here
02:17to see if that current image counter, which we're incrementing each time, if it's
02:22bigger than the array that contains the paths, we just need to set it back to 0.
02:27Then we set the globalAlpha of the canvas context to 0.1, or 10%--and we covered
02:35this back in the globalAlpha movie.
02:38Then we set the revealTimer to be an interval of 100 milliseconds, or a 10th of a second.
02:45So, every 10th of a second we are going to call this revealImage function, which
02:50we need to copy over.
02:50Let's copy and we'll paste.
02:59So let's take a look what the revealImage does.
03:01So every three seconds, switchImage will be called.
03:05Then we have another subInterval down here.
03:07So revealImage saves the current context of the canvas, and it then draws
03:14the current image onto the canvas at the upper-left corner using the width and height.
03:18Then it increments the globalAlpha by 10%.
03:22If the globalAlpha reaches 100%, then we stop the revealTimer.
03:27So what's going to happen is every 10th of a second this revealImage is going to be called.
03:32So because we are incrementing the globalAlpha by .1 each time, it's going to
03:36be called 10 times.
03:38So over a full second, we are going to slowly fade the image onto the canvas on
03:44top of what's already there.
03:46After we do that, we will restore the context, and then the function ends.
03:49So we got two timers going on.
03:51We've got one that's three seconds long and we've got one that's 100 milliseconds
03:56but executes 10 times, which is 1 second.
03:59So let's save, and let's go back to the browser and take a look of this.
04:03Now I can see that over a course of a second, the image fades in.
04:07Then we wait a few seconds and the next one fades in.
04:10So the way that we are accomplishing this is is by setting the globalAlpha to an
04:13increment of 10% each time and then just redrawing the image in place.
04:17That gives the effect of fading in over a smooth transition.
04:21So now we have seen how to create smooth transitions using the globalAlpha and
04:26a JavaScript timer.
Collapse this transcript
Creating a basic animation
00:00Part of the fun of working with HTML5 canvas is that you can learn how to do
00:04things like animation.
00:06So in this movie, we are going to see how to use the canvas and some JavaScript
00:11logic to make a basic animation sequence.
00:15So let me show you what it looks like.
00:17So here, I have a canvas that's light blue with a rectangle, in this case a
00:22square, that has a yellow interior and a red stroke that's just moving from left
00:28to right across the canvas, and when it disappears from view over here, it
00:33reappears over here.
00:34So let's see how we built this.
00:38So I am going to open up my start version of the file, and what we are going to
00:43do is we are going to take a look at the snippets code.
00:46So for the simple animation, let's go ahead and copy over the first few lines
00:52which initialize everything, and we will paste that in there.
00:56So I have got some initialization logic here.
00:58I have got some variables for the rectangle. The Y value is 200, the width is
01:0440, and then I've got an X position which is equal to the initial value of the
01:10rectWidth, but I negate that so it's -40.
01:14And that so the rect appears completely off the screen when it first gets drawn.
01:20So let's go back to the snippets.
01:22So let's copy the initialization function over.
01:24We will copy this here.
01:30So in the initialization function, we get a reference to the canvas and then the
01:34context, and then we call a function called blank.
01:36Blank draws the background which we will copy over in a moment.
01:40Then we have the logic which draws the rectangle.
01:42So we have a fillStyle of yellow, and then we fill the rect with the yellow
01:47content right here.
01:49Let's go ahead and copy that over.
01:50So I am going to copy over the blank function.
01:55So you can see that the blank function simply fills the canvas.
02:03I have got a nice light blue color right here, and it fills the rectangle which
02:08is from the upper left to the width and height of the canvas.
02:12And notice, by the way, that I am using the built-in canvas properties, like
02:15width and height, rather than hard-coding the values which are down here in the document.
02:19That way if I ever want to change the height of the canvas or make any other
02:23changes, I can just change it in one place and then my code automatically
02:26picks up the difference;
02:27I don't have to worry about changing numbers in more than one spot.
02:30So that draws the blank canvas background, and then we've got drawing the rectangle.
02:36Let's go back and copy some more code over.
02:38This is the function where the animation happens.
02:43So let's go ahead and copy that.
02:51So the animation function, you can see up here,
02:54we set an interval every 30 milliseconds, which is about 30-ish or so frames per
03:01second, to call the function labeled anim, which is down here.
03:07So every 30 milliseconds this function will be called, and we check to see if
03:13the X position of the rectangle is less than the width of the canvas, and if it
03:19is, we then draw the blank background,
03:22we move the rectangle by five pixels, and then fill it again.
03:27So we fill it with yellow, we stroke it with red and a lineWidth of 3, and then
03:32we fill and stroke the rectangle.
03:34Now if the rectangle has moved beyond the canvas width, if the X and Y position
03:40is greater than the width--in this case, it is just the X position--
03:43we then reset it back to being a negative value of the rectWidth, which will
03:48place the rectangle, again, back off the screen.
03:51And the reason we do negative width is because we want the X position to be
03:55far enough to the left that none of the rectangle peeks through on the left side of the canvas.
04:02So to recap, we've got some initialization logic.
04:06The first thing we do in the initialization function is draw the blank
04:09background, set up the initial rectangle, and then start the animation.
04:14The blank function just fills in the background, and then every time through the
04:19loop, we draw the background, draw the rectangle. And each time we were drawing
04:23the rectangle, we are moving in over by five pixels.
04:25So the effect that the user sees, because this is happening so quickly, is the
04:29blank background gets drawn, which paints over the rect.
04:32We move the rect by five pixels and then we fill it again.
04:35Now the example of animation that I am showing here is called single buffering,
04:38and the reason it is called that is because all the animation is taking place
04:42directly on the canvas that's in the page.
04:44There's no buffer where we are drawing everything and copying it onto the canvas.
04:49So let's run this in the browser, save, and we'll go to start. And you can see that
04:56what's happening is the rectangle is moving across the screen.
05:00So it's happening too fast for you to see it, but the blank background is being
05:04drawn each time. The rectangle is moved and then painted in its new location.
05:08Now this looks pretty smooth because there's only one moving object, but if this
05:13animation contained a lot of moving objects, we might start seeing things like
05:17flicker, because all of the objects are being erased, the background is being
05:21drawn each time, and then everything is being drawn on the canvas right here
05:25directly in the page where the user can see it.
05:28So what we see in this movie is an example of creating simple animation with
05:31what's called single buffering. But later on in this chapter, we will see an
05:35example of double buffering, which makes it easier to draw multiple objects on a
05:38canvas, and makes the animation appear much smoother to the user.
Collapse this transcript
Creating animation with double buffering
00:00In this movie, we're going to see how to create a smooth animation using a
00:04technique known as double buffering.
00:06Double buffering is called that because all the drawing takes place on an
00:10offscreen canvas, or buffer, before it is copied to the onscreen canvas.
00:16The reason you do this is because if you have a lot of objects that are being
00:19animated, if you're just doing all the animation directly on the screen, the
00:23user might see things like flicker or other unwanted artifacts that don't
00:28happen when you draw everything offscreen first and then copy the finished frame onto the canvas.
00:34So let's take a look at the example that we're going to build.
00:36I'm going to bring up my finished example, and you can see that what we have
00:41here is a nice nighttime sky with snowflakes of various sizes falling at various
00:47speeds and randomly drifting to the left at various rates.
00:51So this is the example that we're going to build.
00:54You can see that it's nice and smooth.
00:56There's no stuttering or anything like that.
00:58So this example is using double-buffering animation, so all the snowflakes are
01:02being animated on a canvas that you can't see off the screen, and then each
01:06frame, as it's completed, is copied onto the canvas.
01:10So let's go ahead and build that.
01:13I'm going to open up my start point here in the editor and in the snippets and
01:18at my Double Buffer Animation, so let's copy things over.
01:23So this is just some initialization code.
01:25So here's the canvas and context that's in the page, and that's this canvas
01:30right here. But we also have variables for the buffercanvas,
01:34and this is a canvas that to we're going to create offscreen.
01:36We have an array to hold all the snowflakes, we have a timer that is used to
01:41animate each flake, and then we have a variable that keeps track of the maximum
01:45number of flakes we're going to have on the screen. So let's save.
01:49Let's copy over the initialization function. So we copy that and we paste it.
02:01So the initialization function will get called when the document loads,
02:04and that's right here.
02:06So when the document loads, we're going to get a reference to the canvas in the
02:10context of the canvas that's in the page.
02:14And we're going to use that information to create a new buffer canvas.
02:18So you can see we're using the document's DOM right here to create a new canvas
02:22element, and then retrieve its context.
02:24Now this canvas is not in the page;
02:26it's floating in space somewhere, but we can still use it to draw on.
02:29So once we've created the buffercanvas, we set its width and height to the same
02:33width and height of the canvas that's already in the page.
02:36Once we've initialized that, we set an interval timer that adds snowflakes to
02:42the scene over time.
02:44So every 200 milliseconds, or pretty much every fifth of a second, we'll be
02:49adding a new snowflake.
02:50Then we have a Draw function, which draws the initial setting, and then we have
02:55an animate timer which gets called every 30 milliseconds, or about every
03:00thirty-ish frames per second or so. So let's save.
03:05Let's copy over the animation function, and the animation function is right here, paste.
03:16So the animation function follows a fairly standard pattern that you'll see
03:19throughout various animation techniques.
03:23Every time the animation function gets called which is about 30 times per
03:26second. The first thing it does is call Update function, then it calls Draw.
03:30Now Update is responsible for moving all of the animated objects on the screen.
03:36So it's going to move each one of the snowflakes according to its speed
03:42and drift and so on.
03:43Once all the objects have been updated to their new locations, we then call the
03:47Draw function which updates the scene and copies the contents of the
03:51buffercanvas onto the onscreen canvas.
03:55So now that we have that in place, let's save, and let's copy over
03:59the supporting logic.
04:03So we have these two functions, addFlake and blank.
04:07Let's copy that, and we'll put those in here. And let's copy over the Update and
04:18Draw functions as well, and we'll go through those and see what they do.
04:24So I'm going to put those guys down here.
04:30So as I mentioned earlier, we have Update and Draw, and now we copied over
04:34some supporting logic.
04:35The last thing we need to copy over is the logic that creates all the snowflakes.
04:40So let's copy that over, and you can see that right here in addFlake, we have a
04:45call to a new Flake object.
04:48So I'm going to copy that because that's up here at the top, and we'll to paste that in.
05:01So here's how this works.
05:03So remember, we have a timer here that adds snowflakes to the screen gradually
05:09over time, and that's this function.
05:12So we have an array; recall that we have an array of snowflakes.
05:16So each time this function gets called, we're going to create a new snowflake
05:20and put it in the array of snowflakes.
05:22And then once the length of the snowflake array has reached the maximum
05:27number of flakes we want, we then clear the snowflake timer so that no
05:32further flakes get added.
05:34So let's go back up and look at the initialization logic for each snowflake.
05:38So each snowflake on the screen is going to have some properties associated with it.
05:43So each snowflake has an x and y position, and that's these two lines right here.
05:48So the snowflake is going to start out above the top of the canvas, so we
05:52initialize that to be -10 pixels so it appears off the canvas initially.
05:57Then we want to distribute each snowflake randomly along the X axis of the
06:02canvas so that it has a different starting position when it falls down.
06:05So we're going to use the built-in JavaScript's Math library to create a random
06:11number, and the random function gives us a random number between 0 and 1.
06:16So we're going to multiply that by the width of the canvas.
06:19That will give us a random number that goes from zero up to the far right of
06:25the canvas, and then we'll just simply use the rounding function to round that
06:28to an n-digit number.
06:30So now we've initialized the x and y position of each snowflake, but we
06:34don't want each snowflake to just fall straight down--and that's kind of not very realistic.
06:37We want each snowflake to kind of drift a little bit.
06:40So we have a drift property, and again, we just have a little random number
06:44between 0 and 1, and we're going to add that to the x position each time to give
06:48it a little bit of a drift.
06:49Then we have the speed at which each snowflake falls.
06:54So again, to be realistic, we want each snowflake to fall at a slightly
06:58different speed, so we have a random number between 0 and 1, times 5.
07:03That will give us a random number between 0 and 5. But we don't want zero
07:07because we don't want any snowflakes just sitting there out in space, not
07:11falling in defined gravity.
07:12So we add the number one to ensure that every snowflake at least has some speed,
07:19so this will now give us a random number between one and six.
07:23Then we have to make the width and height of each snowflake.
07:26So we're going to give the width of the snowflake--
07:28again, we want it to be realistic, and snowflakes are varying sizes--
07:32so we'll have a random number between 0 and 1, times 3, so that'll give us a width
07:36between 0 and 3. But we can't have snowflakes of zero width, and we want to make
07:41sure that each snowflake is at least visible, so we'll add the number 2 to that.
07:45So now we have snowflakes of random width at least 2 and at most 5.
07:50And to make them square, we'll just set the height to be whatever the width is.
07:55So now that we've created each snowflake, let's go back down and see what the
07:58Update function does.
08:00So remember, each time through the animate loop, we're going to update, then
08:03we're going to draw.
08:04So in the Update logic, for all of the snowflakes in the snowflake array, we
08:09need to update their position based upon their properties.
08:13So we check to see if this snowflake, if the y value is currently less than the
08:18height of the canvas;
08:19in other words, it still hasn't reached the bottom of the canvas yet.
08:22And if that's true, then we update the snowflake's position.
08:26So we update its vertical position by adding the speed to whatever the y value
08:31is that will cause the snowflake to fall down a little bit more.
08:35If doing that has now caused the snowflake to fall off the bottom of the canvas--
08:39in other words, the y value is now greater than the canvas height--
08:42we reset the y value to be -5.
08:44That will reset it to be back up above the top of the canvas.
08:47So now we've updated the y position.
08:49Now we have to update the x position.
08:50Now remember, the x position gets updated because we don't want the snowflake
08:53to fall straight down;
08:54we want it to kind of drift a little bit randomly.
08:57So each time through this animate loop, we're going to add the snowflake's drift
09:01amount to whatever its x position is.
09:04Then just like for the y position logic, we have to see if the x position is
09:09now greater than the canvas width, because it's drifted off the right side of the screen.
09:13If that's the case, we simply reset the x position of the snowflake to zero.
09:17So this is going to happen for all of the snowflakes in the array.
09:20So now when this function completes, all the snowflakes have been moved to
09:24their new position.
09:26So that means it's time for the Draw function to run.
09:28So after Update, the Draw function is now responsible for drawing everything
09:33in its new location.
09:34So we have a save and a restore for the context--and these aren't mandatory, but
09:38it's a good practice to put them in.
09:40I just put them there in case any drawing comes before or after this particular
09:43function, if I have a complex animation that I'm working on.
09:46The first thing we do is call the blank function, and the blank function--
09:50let's just scroll back up--all this does is draw our night sky.
09:53So we draw the background first with a nice deep purplish color, and we fill
09:59the rectangle on the buffercanvas, starting at the upper left down to the lower right.
10:04And again, you can see that all the drawing is taking place on the offscreen
10:09buffercanvas, not on the onscreen one.
10:11So we just draw the background, and then we draw all the snowflakes.
10:19So once again, we have a loop that goes across the entire snowflake array, and
10:23for each one of the snowflakes, we set the fillStyle of the canvas on the
10:27buffercanvas to be white.
10:29And then again, on the buffercanvas, we just fill each rectangle represented by each snowflake.
10:35So we have the x and y position and the width and the height of each snowflake.
10:40So we do that for all 200 flakes.
10:43Then when we've drawn everything to the buffercanvas, we copy the
10:46entire rendered image,
10:48this frame, from the buffercanvas onto the canvas that's on the screen.
10:53So we do that using the drawImage function that's on the onscreen canvas to
10:59copy the source, which is the buffercanvas.
11:01And again, we copy from the upper-left corner, all the way to the lower right.
11:06So let's go ahead and save, and let's try it out.
11:09You can see now that we've got snowflakes beginning to fill the sky, and we've
11:12got a little drift going on, right?
11:14Some of them are drifting, some of them are falling at different a different speeds.
11:18So now let's get little bit fancy.
11:19Now let's add a clipping region, and remember, we learned about clipping regions earlier.
11:23So let's go back to the code.
11:25So what we're going to do now is scroll down here, and we're going to create a clipping region.
11:32I'm going to copy this and I'm going to paste it back in here.
11:37So remember that clipping paths define an area outside of which drawing does not
11:43take place, and inside of which drawing shows through.
11:47So we're going to create a clipping region by calling the beginPath function,
11:51again, on the buffercanvas--all the drawing takes place in the buffercanvas.
11:55So we fill the entire buffercanvas with a black rectangle, starting at the
11:58upper left and going to the lower right. Then we draw an arc, and the arc is
12:04going to be drawn at the middle of the buffercanvas, so we divide the width
12:07by 2, the height by 2.
12:08That gets at the center.
12:09We're going to give the arc a radius of 40% of whatever the canvas height is.
12:16So it's going to reach 40% in all directions. And since the radius is half the
12:21diameter, this will give us a circle of 80% of the canvas's height.
12:26And then finally we call clip which tells the canvas, only draw in the visible
12:31area which is represented by that circle.
12:33So let's save and let's see what this does. Let's refresh.
12:37Now we have a circle.
12:39It's kind of like looking through a telescope, right?
12:41So now the snowflakes are only visible within the circular area.
12:46They're still being drawn out here.
12:47You just can't see it because the clipping region is precluding that from happening.
12:51But the effect that we've created is looking at a snowfall through say a telescope.
12:57That's our finished example.
12:58So in this movie, we've seen how to create smooth animation using a technique
13:02known as double buffering.
13:04And for good measure, we added a clipping region to clip the animation to a
13:09visible area, providing a nice nighttime snowfall effect.
Collapse this transcript
Incorporating Canvas into a real page
00:00In this example, we're going to see how to incorporate a canvas into a real web page.
00:06And to do that, we are going to use the Explore California example site that
00:10comes with your exercise files.
00:12So, here I've got the ExploreCalifornia exercise files ready to go.
00:16Let me first show you the page that we are going to build.
00:19So, if I bring up the index page, this is the Explore California web site that
00:23we've been working with. And I am going to click on the TOURS section, and you can
00:28see down here there is a list of tours.
00:31What we are going to do is we are going to build a canvas-based tour finder, and
00:36here is what we are going to do. Let's go to the TOUR FINDER page.
00:39So, right now, you can see this example is empty, but let me show you the
00:43finished version so you can see what it is going to look like.
00:46Okay, it's going to look like this.
00:49So, we will have a canvas which displays a graph of some attributes of a given
00:56tour, and it will show us things like the duration, elevation, environment, and
01:00overall difficulty of a given tour.
01:03So you see, as we choose different tours, the graph is changing to show us what
01:08the overall difficulty is.
01:09In this case, if it's easy, it turns green and if it happens to be a
01:13moderate tour, it turns yellow.
01:15And in the case of really difficult tours, you can see that the difficulty bar turns red.
01:21And you notice how as I am choosing each one of these tours, the graph is
01:25changing right here in the page.
01:27So, to do this without using canvas, you would have a couple of choices.
01:30You would either have to use some other dynamic media solution, such as a
01:34plug-in like either Silverlight or Flash, or you would have to build each one
01:40of these as a separate graphic image and then swap out the image whenever a
01:44new tour was chosen.
01:46However, each time you added a new tour or if you changed some of the data
01:50associated with the particular tour, you would then have to either make a new
01:53image or go back and change the existing one, which is kind of labor
01:56intensive and is not really well suited to data intensive examples. Because
02:01again, let's suppose somebody goes and does some work on this particular tour and makes it easier.
02:06In the case of using the canvas, all you have to do is change one little data
02:09point and then the canvas graph is going to update automatically.
02:12To do this with an image or some other complex dynamic media solution, there
02:16would be a lot more work involved.
02:18So, this is what we are going to build, so let's go build it.
02:21So, we are going to close this.
02:22Let's go to the code.
02:25So, here are the snippets for the Explore California example here in chapter 08.
02:30And I am going to go open up the starting point file, and here we are
02:34in ExploreCalifornia.
02:36So, open up the tourcompare page, and we're going to go ahead and scroll on down,
02:43and I'll show you where we are going to put this.
02:45So, we are going to put this right down here where it says tourDescriptions.
02:51So, let's go back to our snippets and paste in the content we are going to need
02:56to let the user choose a tour, and that's down here.
03:02So, to do that, we are going to need this snippet of code, and I will paste it in
03:06and explain what it does. And we are going to put that right there.
03:11So, what I have done is I've pasted in some HTML code that has a select list in
03:15it, which is called tourSelector.
03:18And you can see that there's a series of options that allow me to choose the
03:21different tours. And then below that, I have my canvas, and you can see that my
03:26canvas has an id on it, and it's got a width and a height. And I put a little one-
03:30pixel solid border around it so we can see it in the page.
03:33So just doing that, let me just save and let's go back to the browser and see how that looks.
03:37So, let's just go ahead and bring the tourcompare page up.
03:41And you can see that what I have done so far is here is the canvas and here
03:44is that select list.
03:46So, we are already pretty well on our way. All you do now is draw the canvas
03:50and then respond to changes in this menu such that when the menu changes, we redraw the canvas.
03:56So, let's go back and do that.
03:57Here we are back in the code.
03:58So, let's scroll up to the script portion, because that's where the rest of this
04:03is going to take place, and go back over to the snippets.
04:07So, let's begin by copying the first few lines of code.
04:15And I will just copy this and explain it. And I'll put the closing script tag on there.
04:25So, what I have here is an array of tourdata, and inside that array, there is a
04:30series of objects, and there are five of them for the five tours.
04:34There is a few properties associated with each object.
04:36There is the tour name.
04:37There is the tour duration.
04:40And I just chose these numbers arbitrarily on some scale, so these are just
04:44going to happen to work out to the size of the bars on the chart, but if you had
04:49some other prior existing data, you could put whatever you wanted in a chart
04:53like this and then just do whatever conversion you need to do to make the chart
04:56draw the right size bars.
04:58In this case, just to make the example simple, I have just got a 1:1
05:01relationship between these numbers.
05:03So, for example, a duration of 200 means two days and so on and so forth.
05:07So, we have got duration.
05:09You got values for elevation, value for how extreme the environment is, and then
05:14an overall difficulty rating.
05:16So, there is five objects, and then I have got a couple of variables here
05:20that are going to hold a reference to the tour canvas and the context for that canvas.
05:25So, let's go back to the snippets.
05:27Now, let's copy over the drawChart function.
05:33This is the function that's going to get called every time the select list index changes.
05:38So, this will take care of drawing the chart backgrounds, drawing the labels,
05:41and drawing the data.
05:42So, let's copy over those.
05:44Let's copy over drawBackground first.
05:47So, I will copy this function over and we'll paste it.
05:54And for the time being, what we will do is we'll fill in little empty stubs for
05:59draw labels and draw tour data.
06:01So, we'll say function drawLabels (forWhichTour) and we will have a function
06:13drawTourData again (forWhichTour).
06:22So, now we have those functions stubbed out and we can go ahead and take a look at the code.
06:28Actually, before we do that, let me do one more thing.
06:31Let's copy over the initialization code that sets up the chart when the page
06:36first loads, and that's this code right down here.
06:44So, here I'm using the jQuery code to create a function that runs when the page
06:50loads, and for the moment,
06:52let's go ahead and comment this one out.
06:53What it's doing is it gets reference to the canvas, then gets the canvas's
06:58drawing context, and then it calls drawChart with 0 to initialize the chart to
07:03the first set of tour data.
07:04So, let's go ahead and save, and let's review this in the browser. Let's refresh.
07:11And you can see that right now we've got the canvas background drawing and the
07:15drawing area, so let's go to the code and see how that works.
07:18So, up here in the drawBackground, a couple of things happened.
07:22First, I save off the canvas context.
07:25Again, I just do that because it's a nice practice in case any drawing came
07:28before this function got called.
07:30So, the first thing we do is fill in the chart background.
07:32So, we set the fillStyle to that brownish color, and then we call fillRect
07:36starting from the upper left and doing it for the entire width and height of the canvas.
07:39That's pretty simple.
07:41Then we create the graph area.
07:42So, we change the strokeStyle to a somewhat darkish gray color, and then we
07:46call strokeRect, and that's what gives us the outline of the area where we are
07:50going to draw the bars. Then we need to draw the chart lines.
07:53So, we change the strokeStyle to a slightly lighter gray color, and then we have
07:57a loop that starts at a certain point on the canvas, at the x point, goes to a
08:02certain x point, and increments every 20 pixels.
08:05So, inside that loop, we begin a path, and then we just draw each line and
08:09stroke it, and that just creates that little bars across the drawing area,
08:13and then we are done.
08:14We restore the canvas context, and the function exits.
08:17So, now let's fill in the drawLabels function.
08:20The drawLabels function is responsible for two things:
08:25it draws the tour name and it draws the labels.
08:28So, let's copy that code and paste it in.
08:34So, again, we save and restore the context each time.
08:37Again, that's a nice little practice-- not mandatory in this case, but we
08:40are doing it anyway.
08:41So, now we draw the tour name, so we set the font to be 24pt Arial, and we
08:45set the fillStyle to be the blue text color, and then we just call the fillText routine.
08:51FillText takes the constant string tour name plus the tour data's name property
08:58for whatever the currently selected tour is and draws that text at this location
09:03on the canvas, so that's that part.
09:07And for the labels, we change it to 20pt Arial and the fillStyle for that color,
09:12and then we draw the labels for duration, elevation, environment, and difficulty.
09:16Again, we just use the fillText function at various points on the canvas.
09:20Let's save and let's refresh.
09:22So, we can see this being built up slowly over time.
09:25So, you can see that here's the labels that we drew on the canvas using the text function.
09:29Here's the tour name for the currently selected tour. And it starts out to 0, so
09:33that's the first data object.
09:35Now, what we need to do is draw the bars for the various data points and respond
09:40to changes in this menu.
09:42So, back in the code, let's go ahead and uncomment this function right here.
09:47So, what we're doing is we are using jQuery to listen for the change event on
09:53the select list. Remember, we had the id of tourSelector.
09:57So, we are listening to the change event, and whenever the change event fires, we
10:00are simply calling a function that calls drawChart and we are getting the
10:05selectedIndex of the select list.
10:08So, this will go from 0 up to 4 because that's how many options there are in the select list.
10:14So, now that we've got that working, we can save.
10:18And before we go ahead and draw the data, let's just go ahead and see
10:21the effects of that.
10:22So, we refresh and now you can see that as I change the menu, it's changing the
10:28currently selected tour, so the title is changing.
10:30All right, so now let's go back to the code, and now let's fill in the part where
10:35we actually draw the data and that's down here.
10:39So, what we are going to do is copy this, and we are going to paste it in to
10:49the drawTourData part.
10:51So, let's go ahead and refresh the browser and see what the effects of this was.
10:56So, now we are getting the data drawn as well, and you can see that each time we
11:00are changing the selection, the data changes.
11:03So, let's go back to the code and explain what happened.
11:06As you may have guessed, drawing each one of those bars on the chart is just a rectangle.
11:11So to do that, recall that we set the strokeStyle and the fillStyle for
11:15the rectangle, and then it is just a matter of drawing each bar for the four properties.
11:21And remember, the forWhichTour index gets passed in from the function for
11:26drawing the chart, so we use that as an index into the tourData array.
11:31So, we get each object and we just get the duration, elevation, environment, and
11:35then the difficulty for that particular tour.
11:38So, you can see that that's just a simple matter of calling fillRect and
11:41strokeRect for each one of those data points.
11:45At a particular point on the canvas starting here, they get this width.
11:49The value of that data field in that object just serves as the width, and each
11:54one of those bars is 30 pixels high.
11:56So, we fill each rectangle, and then we stroke it with a grayish color to
11:59give it an outline.
12:01So, we do that for each one of the data points.
12:03Now, notice for the other properties, it's always yellow. But for difficulty, we
12:09are actually going to draw different colors based upon whether the tour is easy
12:13or hard or moderate.
12:16So, we've chosen a green color for easy yellow, yellow for moderate, and red for hard.
12:20So, that's just a simple matter of changing the fill style based upon what the
12:24difficulty rating is.
12:25So, we check the difficulty rating, and if it's less than or equal to 150, we
12:29choose the green color.
12:30If it's between 150 and 300, we choose the yellow color. And if the difficulty is
12:37more than 300, we choose the red color. And then we just fill and stroke the
12:41difficulty rect and draw it appropriately.
12:44So, we save, refresh.
12:47And you can see now that as we choose each tour, we are getting a real-time
12:53chart drawn in the page.
12:55And let's just go ahead and try this in another browser.
12:57I am going to switch over to Firefox. Okay, here we are in Firefox.
13:02You can see, again, the same appearance, same behavior, right.
13:07So, we have built an interactive tour finder using canvas.
13:12So, let's just recap really quickly.
13:14So, using the canvas, we built an area here in the page and we hooked up a
13:19select list whose change event we used to get the selected index to choose which
13:24tour data we are going to draw.
13:26We used rectangles, text, we used some paths in or to draw the canvas, and that's
13:31a real live example of incorporating campus into a real web page.
Collapse this transcript
Conclusion
Goodbye
00:00All right! That brings us to the end of HTML5: Graphics and Animation with Canvas.
00:05I hope you enjoyed learning about the canvas element as much as I
00:07enjoyed teaching it.
00:08The canvas element really represents a huge leap forward in graphics
00:12capabilities for the web and finally enables web developers to build many of
00:17the same advanced and sophisticated effects that native application developers
00:20have had for years.
00:22In this course, we covered everything, from drawing basic shapes to using complex
00:26techniques like patterns, gradients, transformations, and clipping paths.
00:31We even saw how to create animation using the canvas and how to incorporate the
00:34canvas into a real-world web page.
00:37But this is just the beginning.
00:38You should take what you've learned in this course and use your creativity and
00:42imagination to build web pages that benefit from the techniques we've learned here.
00:46Happy coding!
Collapse this transcript


Suggested courses to watch next:

HTML5 First Look (4h 28m)
James Williamson

HTML5: Structure, Syntax, and Semantics (4h 34m)
James Williamson



Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading
cancel

bookmark this course

{0} characters left Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

You must be a lynda.com member to watch this video.

Every course in the lynda.com library contains free videos that let you assess the quality of our tutorials before you subscribe—just click on the blue links to watch them. Become a member to access all 104,069 instructional videos.

get started learn more

If you are already an active lynda.com member, please log in to access the lynda.com library.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Access to lynda.com videos

Your organization has a limited access membership to the lynda.com library that allows access to only a specific, limited selection of courses.

You don't have access to this video.

You're logged in as an account administrator, but your membership is not active.

Contact a Training Solutions Advisor at 1 (888) 335-9632.

How to access this video.

If this course is one of your five classes, then your class currently isn't in session.

If you want to watch this video and it is not part of your class, upgrade your membership for unlimited access to the full library of 2,025 courses anytime, anywhere.

learn more upgrade

You can always watch the free content included in every course.

Questions? Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com.

You don't have access to this video.

You're logged in as an account administrator, but your membership is no longer active. You can still access reports and account information.

To reactivate your account, contact a Training Solutions Advisor at 1 1 (888) 335-9632.

Need help accessing this video?

You can't access this video from your master administrator account.

Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com for help accessing this video.

preview image of new course page

Try our new course pages

Explore our redesigned course pages, and tell us about your experience.

If you want to switch back to the old view, change your site preferences from the my account menu.

Try the new pages No, thanks

site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked