Video hosted by Apple at devstreaming-cdn.apple.com

Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2011-508
$eventId
ID of event: wwdc2011
$eventContentId
ID of session without event part: 508
$eventShortId
Shortened ID of event: wwdc11
$year
Year of session: 2011
$extension
Extension of original filename: m4v
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2011] [Session 508] Understandi...

WWDC11 • Session 508

Understanding And Optimizing Web Graphics

Internet & Web • iOS, OS X • 42:31

There are several different types of graphics on the web today, and several different ways to create them. Understand the pros and cons of graphics technologies such as the HTML5 canvas element, SVG, and CSS, and learn how to choose the right tool for the job whether you're adding infographics, illustrations, or interactivity. Go beyond the basics and see how to integrate graphics with media, discover optimizations for increased speed and decreased memory footprint, and learn tips and tricks to create unforgettable visual effects.

Speaker: Dean Jackson

Unlisted on Apple Developer site

Downloads from Apple

HD Video (265.8 MB)

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Hi. Welcome to session 508, Understanding and Optimizing Web Graphics, or as I actually wanted to call it, Pretty Pictures with Dean. But marketing with their so-called rules said that that's not-- So I am Dean, represented in this image by the little girl standing with the red bow ties somehow on water.

Okay, web graphics. So we're pretty familiar with, I think, with what graphics on the web are today. Websites are very highly designed. They use a lot of imagery. They're creating a particular brand. They're very stylized. There's some types of images that react to the user somehow. There's even some images where there's some kind of animation just giving you an ambient feel. Wait a minute.

OK. But it wasn't always like that. In fact, here's a screenshot of the world's first web browser written by Tim Berners-Lee in the early '90s. And we'll notice I think two cool things about it. One is that it was written on a Next, which is the precursor to OS X. But also, probably more importantly, even though it's a graphical user interface, the actual web content, which is mostly down in the bottom right-hand corner, it's just plain text. There's different text styles. There's bold and there's different sizes. But the text is just plain.

Now, at this time, there were other technologies that were competing with the web, such as Gopher and Wase, and they, too, were text-based systems. And there was something that happened to the web that really made it kick off. And one of the things was the image tag. And this was added in 1993 to the Mosaic browser.

And you can still read the proposal online because, in fact, it's -- in fact, the same tag that we're using today. And it -- this allowed the author to have -- to point to a raster image file and embed it inline. Now, users absolutely loved this feature. They started putting images everywhere. The Mosaic browser became popular, and web took off for this and other reasons.

So when we talk about images on the web, one of the ones probably the most familiar with is photographs. And in fact, photographs aren't that interesting because they're pretty much the same type of image that was enabled in 1993. Most people in the world nowadays know what a JPEG file is.

What we've done since then is invented entirely new technologies to enable different types of imagery. An example is maps. Previously, a map on the web was pretty much the same as a paper map. It was just a static image. Now, maps, we can pinch and zoom. We can overlay different layers, see directions.

Similarly to maps, we've got charts. Now, these are interesting because as an image, they convey more data in a visual form than would be possibly cumbersome to describe in text. Similar to charts, we have diagrams. So I'm not an American. I think this is some form of religious diagram.

But the idea is here, the image itself is representing the relationship between objects. And the colors and the size. And we can take it a step further and add another dimension to the image. We're adding animation. And so now we show how the graphic changes over time, and that's giving more data to the user.

And there's one last type of image on the web, and that's games. Millions of people spend millions of hours a day playing games on the web. And we actually call these games video games because they are visual things. They're drawing lots of images. They're very interactive. And because of that, they're very exciting. So these are the types of images that we're talking about, or imagery we're talking about today.

So there's two technologies invented in the last few years that really form the basis of this talk. The first one is HTML canvas, and the second one is SVG. And this is what we're going to talk about for the remainder of the session. Now you might be asking, well, these technologies have been around for a while.

Why are you talking about them now? And I think there's three main reasons. The first one is resolution. So we've got now devices with massive screens and powerful graphics processors that can decode, say, four high-definition video streams at once. We also got smaller devices or devices with smaller screens.

Now the interesting thing here is you might have a user that's pinched to zoom into your image, and they might be viewing it on the 3.5-inch screen of an iPhone or iPod touch. But they're in fact seeing a higher resolution version of your image. And they would on a desktop browser. So resolution independence in graphics formats is very important.

If we just consider the iOS family of devices, in the keynote on Monday, it was mentioned there's now 200 million iOS devices, and none of these support Flash or any other plugin. So if you're an author and you want to produce interactive graphics, you need to use a technology that's both supported on iOS, and you want to, of course, enable it for other users, other browsers. And the answer here is HTML5. It provides these technologies. It's an open standard. It's giving you some future proof that you know that the other vendors are going to implement the same technology.

Now there's one, there's a third, there's a third point, and the third point is actually so cool and I'm excited about it, I'm not going to talk about it, we're just going to show you. So I'm going to swap to... Now this is an iPad running-- iPad 2 running iOS 4.3.

So I'm going to just launch this-- This is a demo I wrote, and it's just exercising the canvas element. You can see it's sort of got five different types of tests. One's drawing rectangles. We've got some shapes that are stroked and filled. We're scaling some images. We're doing 2D transforms on rectangles, and we're doing some image compositing.

Now, we're getting 17 frames a second here. The graphics look great, but there's sort of some restrictions with that level of performance that, you know, people are writing great web apps that use these technologies, but it could be a little bit better. So now I'm going to swap to the same hardware running iOS 5.0. Okay, so same hardware. Got to run the same test.

And this time -- So about 70 frames, about four and a bit times faster. Now, this is on the same hardware, and it's in iOS 5. Cool. So those three things: resolution, HTML5, and performance, are the reasons we're talking about graphics today. So what are we going to cover? We're going to cover the basic concepts of Canvas and SVG, how to draw shapes. We're going to add some interaction -- animation and interactivity. And we're going to finish with some tips and special effects.

So let's start with the basic concepts. The HTML5 Canvas element. So the way I think of Canvas is that it's actually like an image tag, but it's blank. And instead of pointing the source element at a raster file to get the pixels, you, in fact, have a JavaScript API and you control what the pixels in the element is.

One thing to note about the Canvas is this JavaScript API, which we'll get into in a minute, every drawing command is immediately rendered into the Canvas. So if you're familiar with doing animations and things in -- in -- in the -- in the JavaScript, you know, you can actually do that. You can do that in the JavaScript. You can do that in the JavaScript.

You can do that in the JavaScript. So you can do that in the JavaScript. So if you're familiar with doing animations and things in -- in the JavaScript, you can do that in the JavaScript. So if you're familiar with doing animations and things in -- in the JavaScript, you can do that in the JavaScript.

So if you're familiar with doing animations and things in HTML content where if you have a development and you move it about, the browser's got to take charge of redrawing it. In Canvas, if you draw something in one place and you want to move it, you actually possibly have to erase it from that new location and draw your entire scene again.

How do you use canvas? Well, it's just a regular HTML element. So here I've got a canvas element, and I've given it a width and a height, and it's just a rectangular region in the page. So this bit's so boring, let's actually start using it. So I wanted to draw something that's fairly easy but recognizable. So let's draw the HTML5 logo.

Now, if you look at this logo, it's in fact three different shapes at once. So there's a background, there's a shield, which is the orange background. There's a white shape that's shaped to be, looks like a five. And then what looks here like a gray polygon is in fact a white polygon that's partially transparent so that when you draw them on top of each other, you get this highlight effect. So let's draw this shape.

I'm going to start by having a canvas that's 512 pixels in each dimension. I could have picked any size. Now, the first thing I want to do is I've got to get this API that I talked about, which is the HTML5 canvas element. And I'm going to do that by using the HTML5 element.

So the object, the JavaScript object that you issue the drawing commands on. So I've got a reference to my canvas element, and I call the get context with a parameter of 2D. And that gives me the, what we call the context of, I've got the variable CTX here.

Once I've got that context, I probably want to erase what was already there. Like I said, something might have drawn into it, some previous frame of what I've drawn. I'm going to erase what's there and I just clear all the pixels. Now I want to draw this shape. Now the way we draw shapes in Canvas is we first define geometry, and then once we've got that geometry, issue the actual drawing commands. So I start by declaring that I'm going to now start giving you geometry commands, beginning a path.

And then I define the five points in the path of the shield. So I start at the point 71, 460, then I move up to 30, 0, and so on around. Finally, I'm going to close the path, which is going to draw a straight line from the last point to the end point, sorry, the last point to the first point. Now I've got the geometry, I'm going to actually issue the drawing commands. The first thing I set the fill style to be the particular shade of orange. And then I call fill. And Canvas goes and fills in that shape with the orange color.

Drawing the five is very similar. I'm starting a new geometry, a new path, begin path. I add all the points. There's a few more of them here, so I haven't listed them all. In the end, I set the fill style to be almost white, a slightly bright gray, and then call fill, and we get the five on top. The highlight is again very similar. Start the geometry, begin path, define the outline. And here, it's something slightly different is that because I wanted to draw a transparent color, I set my fill style to be RGB white that's 30% opaque.

So how are you going to use that? You've got the object now. You've drawn into Canvas. Well, I already mentioned that it could be just an element already in the page. That's pretty simple. There's another way to use Canvas in WebKit in Safari, and that's via CSS. So let's say anywhere you can use an image in CSS, such as background image or border image, you can set your property value to be WebKit Canvas, and you give a name for that Canvas object. And this gives you a canvas that's not actually part of the content of the page, but it's kind of like an off-screen buffer that you can draw into.

So I've defined the WebKit Canvas, and then somewhere else in my JavaScript, I call document getCssCanvasContext 2D, and I use that same ID, the name that I used in my CSS, and I give it a size. And then I've got this context object that I can draw into, and it immediately goes into the CSS engine.

So we drew that logo, and if we look at it, it's a fair bit of code. Most of it's the geometry, but embedded in there, mixed in, is some styling commands or whatever. It's all JavaScript. It might be slightly hard to maintain that, especially if you're not a programmer. So we're going to look at how similar technology, SVG, would have done the same thing.

So SVG, it's a markup format for graphics. The way I like to think of it is it's kind of like HTML for graphics. So instead of having P paragraphs and heading elements, you've got circles and rectangles. This makes it really human readable and easy to edit by hand. It's vector based.

So what that means is that instead of actually drawing, ultimately it's going to end up with pixels, but you are defining the sort of parameters to the shapes that you want, and the browser's going to take care of the rendering. It's going to render the object at the best resolution possible for whatever zoom factor the user might be.

Lastly, it actually has a lot of tool support. It's been around for a while. It's an open standard, and there's some commercial tools like the Adobe Suite that export to SVG, and there's a whole bunch of open source tools that edit and export to SVG. So how do we do it? An SVG is a file format just like HTML, and HTML starts with an HTML tag. SVG starts with an SVG tag, and you put your content in between. Very simple. There is one little difference in that, remember we said that SVG is resolution independent.

It means that the browser's got to take care of how big it's rendered, but within the actual content itself, we need to give a hint to the system as to what type of coordinate system we're looking at. So in this case, I've added a viewpox attribute, and what I said is this SVG assumes that I'm drawing in a sort of arbitrary viewport of starts at zero zero and is 512 pixels high and wide.

So let's start. So there's my SVG viewport. And I'm going to add a polygon. And a polygon is actually just a polygon tag. And it has an attribute fill. So in this case, I've got the tag name, then what I call a styling attribute. So it says the fill color to be this particular orange. And then the other attribute on the element is-- is the points, and that's giving you the space-separated list of x, y pairs that define the geometry of the shape.

The HTML5 logo is very similar. Again, a little bit more points, but I've said fill to be that bright gray. And now we're just mentioning that SVG draws in document order. So if I put the orange polygon in the document before the white five, then they get a render in the right order. Otherwise, the five would be obscured.

Dean Jackson The last highlight again is very simple. It's another polygon. The difference here is I could have used an RGBA color like I did in canvas, but instead I said I want the fill color to be white, and I set another property opacity to be 30%. And there's the logo.

Okay, so that's the entire file for that graphic. What's great about that is that just that amount of code gives you an image that could be drawn at any scale. It could be used, you know, 10 pixels by 10 pixels or a million pixels by a million pixels zoomed in. The total file size It's 497 bytes. And that's actually uncompressed. When you send it over HTTP with GZIP compression, you're at 272 bytes. That's probably smaller than most HTML head elements.

So you can use it as an image element. The way it takes a JPEG or a PNG file, you can also point at an SVG file and it'll render the SVG file. Also in CSS, you can use an SVG file anywhere. Again, you would use an image in CSS such as borders or backgrounds.

There's one important thing to mention when you're using it in CSS is, again, SVG doesn't really have a resolution itself, so you have to tell the CSS engine how big you want that file to be rendered when you're using it. So in this case, I set a background size.

There's a new way to use SVG which is enabled in Safari Online and on iOS 5, and that is you can actually embed SVG inline within HTML. In this case, it's very similar to the canvas element. I just put the SVG file in and it's a rectangular region on the page, and then my SVG content goes in between.

So we have that file, but there's something probably missing if we're web authors, and that is we've been taught for years to separate our sort of styling from our data. And this isn't doing it, sort of mixing it all in one. So we can actually have another pass at this file. It's hard to read, so I'll just make it full screen, and I'm going to highlight the bits that have changed. So instead of all these fill attributes, I've instead put CSS class attributes on the element. So there's the shield, the five, and the highlight.

And then I've added a style element, and I've added the CSS for those three things. I could have equally had it as a link to an external style sheet. Now, the great thing here is that if I take this very simple style rule and change it to something like this, I've highlighted the changes, we can take that same graphic and produce a dramatically different visual appearance. You haven't changed the coordinates in any way. You've just changed the style sheet. So you could, in fact, have the same graphic styled by different parts of your website or different media queries for different things. different devices just through CSS.

So we've got this file. Now we've seen canvas and SVG, both the basic shapes. Let's have a look at where we stand in comparison. So I mentioned canvas draws immediately into its 2D image. SVG is a structural format, as in you add elements into the document. Basic shapes, pretty much the same.

You can use them both as background images. You can embed them both inline. So we're going on pretty similarly now. It starts to get different when we talk about accessibility. SVG by its nature is a little bit more accessible because there is actual structure in your document. There is content there.

You can side it with CSS, as I mentioned. And there's authoring tool support. There's less authoring tool support for canvas. But before I give you the impression that SVG is just better, there is one very important use case that canvas wins at, and that's when either speed or memory is essential. And the reason for that is, SVG has this overhead of adding elements to the document.

So there is some sort of processing involved in navigating that tree and styling it and rendering it. There's also like the memory overhead. If you're going to draw a million points, you don't necessarily want to have a million objects in your document. You just want to draw it once and have it as that 2D image. And so that's why canvas is used for many web games because it's great performance. So that's the basic concepts. Let's start shaking and baking and add some animation interactivity.

Now, we've got, to this point, we could draw a graph like this pretty easily. It's just a polyline, a few shapes, some text, would have done that. So the next step would have been make it a little bit better. This is about the best I can do because I'm not a designer.

But we could take it one step further and maybe add some kind of animation to this chart. And this would allow you to do things like, you know, make it really clear that sort of one value is bigger than the other because it animates longer or just maybe even just looks cooler. So let's look at how we would add this kind of animation to our graphic.

So animating with canvas is in fact very similar to what used to be called DHTML techniques or what plenty of JavaScript libraries do today, which is they render the scene once, and they run a bit of JavaScript, and they draw things again, or they move things across the page, and just draw again and again. And you're in charge of each frame of the animation.

So there's plenty of ways to do this. Like I said, there's plenty of libraries. Let's just look at an example that I came up with. Imagine I've defined this function that takes-- that I'm going to-- it's going to be used to animate a shape in my canvas, and it takes the starting value and the ending value, when I started, and how long I want the animation to run for. The first thing I'm going to do is work out where along-- you know, how far along the animation I am. Then I'm going to evaluate based on that proportion where the element I want to draw is.

Then I'm going to redraw the scene. I think it's a bit tricky that, you know, I've done it once. I've now got to test, well, have I hit the end of my animation? Should I have elapsed? And if I haven't, then I've got to set up a JavaScript callback to, you know, recall this function at a later state or as soon as I can to get a smooth animation. So we're getting a fair bit of code there, but it's not so bad. But if you want to take it a little bit further, let's say most animations look wrong if you're just sort of doing a straight linear interpolation.

If you look at many of them, they sort of start slow and speed up and then maybe end slow again. So if you want to do something like that, you're going to have to write extra code to control basically mapping that proportion value in time to a proportion value in the animation.

Maybe you want to animate a whole bunch of things and you want to synchronize them. So you want to have one thing start and then another thing start a second later or something. You have to write extra code to keep this all arranged. And then maybe you want to animate some things that are a bit more complex than just a single floating point value.

For example, it could be a transform, which is a matrix. So it doesn't necessarily always work to do the interpolation of all the elements in the matrix. Or it could be animating between two different shapes or path types, polygons. So you're going to have to write extra code to do things like that.

But this is all okay. I mean, if you're familiar with this, and this technique is, again, used very often in HTML. It applies just as well to SVG. You can use the same scripting techniques. But there is a form of SVG animation, which I think is worth mentioning, that definitely makes these simple animations a lot easier to code.

And the way you do animation in SVG is that instead of doing the frame base where you're calling yourself, you just give the intent of the animation. I say I want to start from this value and I'll end at this value, and the browser's going to be the one that does the redrawing. Very similar to the way transitions and animations work in CSS.

It's pretty easy to add to your file. So let's imagine I've got a circle element. It's drawn at 100, 100 with a radius of 8. And I just want to animate it. So I add an animate tag. I say that the attribute that I want to animate is CX, which is the X value of the center point. And I want to start at the point 100 and go to the point 200.

And my duration is two seconds. And all I do then is when the document loads, that animation's going to fire. And the browser's going to control the-- draw this animation. Pretty easy. So I want to do more animations. I just add more animation tags. So in this case, I've got two animations. I first want to animate that slide along the x-axis and then move up in the y-axis. But I want to do it a little bit tricky. I've added an id attribute to the first animation.

So I've given it the name slide. And then the second animation, again, takes cy from 100 to 80 over two seconds. But I've told it to begin at this expression. And this expression is the name of the animation, in case slide, when it ends. So now what will happen is the browser will do that animation and then immediately do the y animation.

This is really cool because in JavaScript, you would have to sync this up yourself. And we can go beyond this. So that expression, in fact, can take a little bit of arithmetic operation. So in this case, I've done the same animation. But I now want to start two seconds after. So one Mississippi, two Mississippi.

And you count Mississippi a little bit faster when you're on stage, obviously, and then the animation fires. So you can see that was pretty easy. There's another type of sort of animation, or what I call interaction, and that's a little bit more like-- imagine you have a chart, and you've got a point on the chart, and you want the user to tap on it and get a reading of the current value.

So it might pop up this thing. Pretty common, very cool thing to do. Let's have a look at how we would actually do it in Canvas. Now, one of the problems with Canvas is, like I said, it's one element in the DOM. So when you're doing an interaction, you're only getting the DOM event on that one element. So if you touch somewhere on the canvas, it's the canvas that gets the event with the next Y location. And it's up to you to work out where inside your canvas the shape that you're actually drawing or whether the user is tapped on a particular shape.

So here I've written a helper function. It's going to ask, is my point in a particular shape? And I pass in the context and the XY location of the user touch. Now, I could do the math to work out the geometry myself, but I don't want to do that. What I'm going to start by is, again, the same process that I did to draw the shape.

I'm going to define the geometry with beginPath and add all the points. And then I'm going to call as a helper function on context, which is isPoint in path. And that's going to do it. Now, this seems really easy. In fact, it is really easy, except it does get a bit more complicated when you've got a graphic like this.

So here there's, what is it, 40-odd states or something? And some of them are pretty complex. And so every time a tap or a drag happens, you're going to have to run that code for each one of these shapes. Add all the geometry. Am I inside? No. What about the next one? Am I inside? No. And you can optimize this. But again, it's pretty cumbersome.

So there is a way to do this a little bit easier in SVG. And the reason is that the actual shapes that you put into the document are elements in the document. And they can get event listeners just the way any other element in HTML can get event listener. So here we've got a polygon. I want to add an event listener to it. So I get the element by ID myShape. And I've got the pointer to this SVG element, which is a polygon. And I just add an event listener click.

And it'll call this myClickHandler when the user clicks on it. I haven't had to do the hit testing. It's not going to do it at all. The browser's done it for me. I've probably reduced hundreds of lines of code. And it's probably faster, because the browser can optimize this.

So again, I've hinted that there was some types of animation or interactivity that SVG's better for. But there is one type of animation that Canvas-- well, there's definitely one type of animation that Canvas is totally awesome for. And it's not supported in SVG. In order to describe that, I'm going to start by explaining how you draw images in Canvas.

So the first thing I want to do when I'm drawing an image is actually get a reference to the image. I could have queried for an image element in my document. In this case, I'm just doing it through JavaScript, so I've created a new image object, and I've set the source to be some URL.

And we have to imagine here that I've actually waited for the image to load. I probably would have added a load event handler and made sure the image has actually appeared. And once I've got that image, I'm going to call one of three functions, the three variants of the drawImage function. The first one, if I just call drawImage with that image and I give an xy location, it's going to draw the image at its native resolution into the canvas, and that's its native resolution. Let's call that 500 by 500.

The second type is, imagine I don't want the native resolution, I give it the image and the point I want to draw it at, and this time I've said that I want it to be 300 pixels wide and 600 pixels high, and it scaled it. Now the third type is where it gets really interesting. The third type, again saying I want to draw it, it's the last four parameters, it's 0, 0, 500, 500, but instead I've got these extra parameters, I'm defining a region within the image that I want to crop.

So in this case I've said that I'm defining a rectangle that starts at 230 pixels into the image, 130 pixels down, and it's 250 pixels square, and then when I draw that image it's going to take that cropped region and draw it at the 500, 500 resolution, so I get this full image. Now you might be thinking, well that's not that cool, but there is some useful things to it.

So the guys that write this game called The Incident are really kind, they make great use of this technique. This is not a web game, it's a game that's available on the iOS store and the Mac App store, but again it gives a great example of what we're trying to do. So here is the trailer for the game. Take a look at the guy down in the bottom. So you can see he blinks, looks left, looks right, says what the, and then runs out of the way, he's running around and jumping.

So this is actually how it's done. They've got one image element, and then this image has an 8x8 grid of beautifully hand-drawn pixel frames. And so let's look at the row down the bottom, and you can see there is Frank, the character, and there's the frames where he has eyes open, blinking, looking left, looking right. What's going on? And that -- so we could -- then also scroll up to this row, and we see the running animation.

So what we would do, we would use that draw image command that we did with the cropping, and we could do things like if we drew this frame, this cropped frame, then this cropped frame, then this cropped frame. It looks a bit better when we see it in full screen with Frank stationary, so I'm going to draw this, this, this, this, this, and you can see Frank's running.

So let's have a look at this in practice. So again, the guys that wrote the game kindly gave me the assets to use. And here I'm going to do it. You see, here I am drawing the walking frame. He's got a bit faster and he's starting to run. Again, I just mocked this up pretty quickly. Do not take this as any indication of how it would happen in real life.

Yes, okay, so then we jump. So, again, I'm just gonna scroll along. It's slowly speeding up, and... So, it's failing there. But anyway, that's an example of how you would get that animation in Canvas and how you would possibly write a similar game, obviously with a little bit more graphic design skill than my rectangular squares.

So that's animation and interactivity. So I think actually by now that I would consider you know how to draw shapes and how to add some cool effects that you're almost like web graphics experts. But before we send you back, we want to show you some more tips and tricks that really maybe take it to the next level.

I hate using that phrase. So through this talk, I've mentioned multiple times that Canvas is, in fact, a-- well, it's a vector API, and you're drawing resolution independent. Once it's rendered, it is, in fact, pixels. And we sort of describe that as if it's a bad thing. Well, actually, it's time to stop disrespecting the pixels. Because these effects that we're going to show here are enabled purely because Canvas is based in pixels.

[Transcript missing]

So step one is I'm going to declare a variable called input, and I'm going to get the currently rendered version of the canvas. And I'm going to get the full width and height. And then next I'm going to declare a variable which is my output, which is where I'm going to actually set pixel data into. And again, I've done it the same width and height, but I've called Create Image Data because I'm not getting it from an existing canvas.

Then I'm just going to iterate over every pixel in the image. It doesn't really matter what the code is here, what I'm actually doing. You could do things like change the brightness, multiply each one of the RGB values by add 10% to make it a little bit brighter, or do some edge detection or whatever. Or in fact, you could just set the pixels directly. You might not be reading them.

But it's important to note here that because every pixel has four units, that's why we get this offset where we're multiplying pixel number i by 4 and then adding 1 and then adding 2 to get 3 to get the alpha version. So once we've manipulated that output array, we've got to draw it back into the existing context. And I can either draw it as an image or I can say put image data, and I basically replace whatever's currently in the canvas with my manipulated data.

Hey, Dean. Remember last week when you told me, like, I could manipulate pixels? Well, now I've written this game, and I'm drawing the same image lots of times, and the performance isn't quite what I like. So let's imagine here we're drawing this shape with canvas, and you'll notice it sort of looks simple, but if we look a little closer, it is pretty simple, but it's not completely basic.

You can see it's got a colored stroke, which is, you know, we've got to change the curves into a lot of points and render it. It's got a couple of different shadings of red and a gradient in there, and then it's got this white highlight. And if you're going to draw this hundreds of times, then, you know, there is actually a fair bit of processing behind that.

So the way you do this typically in graphics program is you would render to an offscreen buffer and do the curve to pixel operation once, and then draw that pixels into the canvas. And as I mentioned before with the IE9 demo, drawing images into canvases is super fast now. So this is a really great technique.

So let's say I'm going to draw this heart. I know that I'm going to draw it lots of times at 100 pixels by 100 pixels. So I'm going to create a new canvas element. I'm not going to put this canvas into the document. I'm just keeping it in memory in JavaScript. I set its width and height to be 100 pixels by 100 pixels.

And then I get the context for that new canvas element, and I'm going to call my function drawHeart, taking that context and the size. So now that I've got this, I've now got this canvas object that's my rasterization of the heart, then I can just use it as drawImage the same way we showed with previous slides, at some XY location.

Now, it's important to remember that you are actually rasterizing that graphic so that if you decide to draw it at some other size other than 100-100 in this case, what you define it to be, you probably get some kind of artifact, and that might not be good. Or if you potentially want to transform it or rotate it. But this is a great performance tip, so well worth using if it does suit your code.

So now you've really got this attitude as the expert. So, "Hey, Dean, you let me draw these awesome canvas things, but, like, once the page is gone, the image is gone, and I want to save that image." I'm glad you asked. So the Canvas element has one method. It's very simple, two data URL and you pass a mime type. In this case, I've said image ping because what this does is gives you back a string which is an encoded version of a ping file that represents that Canvas.

Pretty simple call. What can you do with it once you've done that? What would you do? So now that you have this string, it's just like any other string in JavaScript. So I could potentially put it in local storage so that the next time the user comes to your page or my site, I can extract it and they don't have to recreate the image. I could send it back to the server.

It's important to note here that there is some security restrictions there because obviously a Canvas can have access to images that are from a different domain. So if you do draw images from a different domain or data from a different domain into a Canvas, you can't get the image data back out of it.

But if you could, you could send it back to a server. Or lastly, this seems like a pretty obscure case, is you could actually create a new image element and set that -- set the source attribute of that image element to the data URL that you just created. And you're thinking, well, wait a minute.

I've got the image in the page. So why would I want to do this? So this, I've got basically a full screen canvas here, and let's say I want to draw on it. So here I'm just drawing some radial gradients with a little compositing mode. And I can actually-- because it's a scripted image, I can actually-- I've taken a record of what I drew so I could replay it, for example, to the user. Oops. So let's do something cool.

I want to write-- So, okay, now I've got this. Now I want to actually make use of this image, so I'm going to hit save. Now what I did is this technique here where I've created a new image element with the value of the canvas, and now, thanks to iOS, I can tap and hold on this image and save it.

[Transcript missing]

Boom. And the next session we'll get a nice surprise. I said both.

So we, we, I talked about manipulating pixels. Let's have a look at this. You don't actually, one of the things with this, being able to manipulate the pixels is the sort of range of possibilities is endless. You can actually do whatever you want. So here's an example. And in this case I've got a video element in the page and this is the canvas. And where I call draw image on an image element, I can actually still call draw image. So I can actually draw image on a video element and it's going to draw the current frame of the video into the canvas.

So here it is drawing the feature. Now, you notice that there's a lot of white background here. So I can actually check the, check the pixels and detect when I'm getting a block of white images and in fact composite that over another image. In this case they're on, the iPad is floating in midair in Hawaii. So I can do other things. It was easy to find those gray images. I could actually maybe now manipulate the pixels here. I've upped the green. And I have risked my career by making Phil Schiller look like Shrek.

But I can go even further than this. I can sort of do a whole of mirrors effect. So here I am getting the pixels. It'll start over again. And I'm drawing them again multiple times with sort of varying opacity. Yeah, you can do all sorts of stuff with this. It's pretty cool.

So that's finished section three, and so now it's what you have learned. You've done some basic shapes. We've done some interaction activity, and then we've shown that you can actually do some amazing stuff if you take it a little bit further, even though the operations that enable this are quite simple. So to wrap up, so maybe some of you came to this talk thinking, oh, well, I really hope that he talks about something and tells me which of these two technologies is the winner because there's people on the web that say, oh, this sucks and that.

Well, unfortunately, the answer is they're both winners, and it's really more a case of looking at the problem that you have and asking questions like, does it need to be accessible? Do I have programmers that are more familiar with JavaScript than maybe designers? Or do I need to style it with CSS? But the real point is that, you know, you've got these two technologies that are really, as far as 2D graphics are, are almost limitless.

You can do whatever you want. And if you combine that with the amazing speed increase that's available on Safari Online and iOS 5, now, like, the web platform in terms of graphics is really -- we're looking forward to seeing what stuff you come up with. So there's some other sessions. Unfortunately, the iBooks one, which is a place where you can use lots of these technologies, was earlier, so you'll have to catch that in the replay. But coming up next right here is how to use -- what's new in CSS effects and animations.

We're not competitive here, but we like to think in the Safari team we have the best evangelist that Apple has to offer, and that's Vicky Murley, who you'll see on stage in a minute. Both of these technologies are from the W3C, so while there's the Safari Developer Center on developer.applecom, there's also the specifications on W3C, and the joke I always make is they will come out with an English language translation one day. And with that...