Content and Media • 1:08:40
WebKit in Leopard introduces new features based on the latest open standards for delivering richer client-side and server-side web applications. Explore advanced development techniques for designing rich user experiences in your Web application. Learn advanced uses for incorporating CSS3, SVG, resolution independence, and rich media.
Speakers: Antoine Quint, Dean Jackson
Unlisted on Apple Developer site
Downloads from Apple
Transcript
This transcript has potential transcription errors. We are working on an improved version.
We've got an interesting in-depth technical presentation for you guys. It's going to be covering Developing Rich Media WebKit Applications. We have Antoine Quint and Dean Jackson here with us from Australia and Paris, France. So why don't I don't welcome up on stage Dean Jackson first, so a large round of applause.
( Applause )
[Dean Jackson]
Bon jour. I'm the Australian one. So you've noticed from the graphics and media state of the union and even actually before that that there's been a huge emphasis on very, very interactive rich media content. And every time I hear the word rich media, it's like hearing the word ontology, I want to leave the room. Rich media, I think well what do they mean? And what we're talking about today is web graphics because we're basing our WebKit, we're adding video, interactivity, scripting, some animation, something that moves, something that you can hear and something that you can see.
So the agenda is the first half is I'm going to be going through QuickTime and how you embed the QuickTime plug-in into the web browser and how you interact with it, and then after that Antoine will be finishing up with scalable vector graphics, but he'll also show how you can link video, QuickTime videos into SVG as well and actually interact through them with vector graphics.
Okay. So I'll start. So actually, as I start, I'm going to say clearly what isn't covered here. I'm not going to tell you how to check whether the plug-in's in the browser, I'm not going to tell you point the user to the plug-in page to download it. I'm not going to tell you much about the JavaScript library that Apple provides.
They provide a wrapper class for doing interaction with QuickTime. What I am going to do is refer you to the developer.apple.com site, which has a whole bunch of resources. And actually, if you just want it all collected into one easy set of slides, you look at session 611. that has everything you need for that.
So how do you actually embed QuickTime into an HTML page? So the way I think about it is that Apple has suggested that if you want to do interaction with video data rather than rely on the interactive features in QuickTime, which are there, you can still use them of course, you should be looking to the future where we're suggesting that you have your interactivity embedded into the webpage because the web's already very interactive media and have the video linking up with the scripts already in the page.
So you actually just start by using the embed tag, which is very similar to the way other plug-ins are embedded into the page. The important thing is you give it a media type here, the type attribute, which says video QuickTime. That allows the browser to know that the content's for the QuickTime plug-in and start the browser. And you give it a width and a height.
You also like the image tag, give it a source, which points to the movie you want to load. Once you have that, the movie should appear in your page in the position you allocated to it. That's not all the attributes you can apply on the embed tag. There's also some custom ones that are specific to the QuickTime plug-in.
The first one is whether or not you want to show the little mini controller. So I've got examples in my demo of both with the controller on and with the controller off. It's important, of course, to turn the controller off if you want to provide this really rich experience where you've built a custom controller with your own graphics and your own sliders or whatever Also, you have an attribute to decide to tell the plug-in whether or not you should start playing immediately the data is loaded That's pretty obvious.
Lastly is whether or not you want the QuickTime plug-in to really work as a part of the page or whether to be basically just drawing the video to the screen. I'll go into a little bit more detail in the next slide. But again, I'll just point you to the developer website where there's an article, Including QuickTime in a Web Page, that has everything you need, an explanation of all these attributes.
So what does it mean to have W Mode transparent? Well the great thing is that you can set the opacity on the video so that you can have things that show through the video or you can have things on top of the video that display on top of it.
So there's these great benefits that means it's actually a regular part of the webpage just like other elements in the webpage. Much easier to script. You can do a lot more with it. But what's really important though is that it is in fact a very large head on computation.
It's, what's happening is instead of taking the QuickTime fast path, where it can, it knows where on the screen the video's going to be and just goes straight to that point, it actually has to render into an image and then pass that image to a browser, where it'll composite it, depending on what other elements around it, that means below another element or on top of another element. We found it's okay on Intel Macs, but you should be definitely careful if you're going to be using it out on the web. And also, even more careful because this feature is only supported in Safari.
So now, let's say how do you actually interact with the QuickTime plug-in? Well, using JavaScript, you do the very well known JavaScript method, which is getElementByID. You get a reference to the embed tag that returns an HTML embed object. But that object has extra parameters or extra methods on it so that it's specific to QuickTime. So here I do a var movie, document.getElementID. Give it the ID of the embed element. You get multiple movie objects for every embed you have, so you can control different movies.
I'll just briefly discuss here the way you'd know what's happening with the, why'd that put me off? Now I can work out what I'm saying. Sorry. Where was I? Yeah. plug-in. So you need to know, as the movie is loading, you need to know what's happening with it? Is it still coming from the data? Is it enough to play? Is it actually playing?
There's a method called .GetPluginStatus, which returns a set of states so that you know within your script what the plug-in is actually doing and then you can update your script. There's a new way to do that, which you don't quite have access to, but hopefully you will soon, and I'll cover that soon. And of course, you can also access more data about the video. You can ask for the size and check whether you've got enough flow that you might want to start playing or that the video says that there's enough to start playing.
So let's have a look at the other methods on the JavaScript API. You'll see that in most cases, these mirror, the QuickTime API's, so that they're fairly familiar to QuickTime programmers, play, stop, obviously those are easy ones to understand, rewind just jumps back to the beginning of the movie. Step is, in fact, jumping the playback state forward by some number of frames that you've passed in as a parameter. It also pauses the playback.
GetRate and SetRate, if you're watching a movie by default we give it a rate of one. That means it's going to playback in normal time. You can query the rate, or set the rate to be two and the movies going to playback twice as fast as it was before.
You can specify whether it should loop, as whether it should loop once it hits the end it should go back to the start or it should go back to backwards, start playing backwards. You can also control the volume. This, of course, doesn't control the system volume, so you can't take over the user's volume control, set the volume to 11 and blow their speakers. But you can, basically that volume's the ratio within the plug-in itself and then the audio gets passed on to the system. You can also mute the plug-in which will keep the volume level the same, but just not output any sound.
So seeking around the video is a pretty useful thing to do. What you've got to be aware of is that the way you seek is using units, video units. And so in every second of video a number of units display to the screen. So you ask the time scale, which will tell you how many units per second the QuickTime movie has and then you can sit and get the time which tells you the, oops, have I done the right one? Yes I did. It gets the current time without effecting the playback pause state. So that's, if you're manipulating the, if you want to set to a particular time without turning the video back on if it was paused.
A QuickTime movie by itself has potentially a number of tracks in it. Typically you have a audio track, I'm sorry, a video track, which is what you're,seeing, an audio track, which is what you're hearing. But you can also have other audio tracks or metadata tracks or time text tracks, which might be some form of subtitling or whatever.
By default, the QuickTime plug-in will play all the tracks that are media related. So if you actually have multiple tracks you've got to be aware that for example, let's say that you have some video content with the regular soundtrack and the directors cut or something, they're both going to play by default. So in fact, it's kind of confusing. But you have to be careful if you have content like that the when the plug-in loads that you query the tracks and set the right track to be playing. There's another example soon.
So let's have a go through the code samples. First off, we got to ask for the duration of the movie in seconds. So I start by getting a reference to the video element, then again, as I said, I have to get a reference to the number of units of video that are played with each second and what the total duration of the movie is and that allows me to divide the total number of units by the total number of units per second and then I get the duration in seconds.
The second example, suppose I'm playing back and I want to skip back 10 seconds or skip forward 10 seconds, here I get a reference to the video element again. Or I could have kept it ran from the last time. I of course tell the movie to play, to skip forward or to step forward from the current time and then I want to rewind in this case by 10, which is the number of seconds, if I passed in times the number of units per second and then I tell the video to play again.
More examples, if I want to double the playback speed, which I've got an example later, I just basically set the rate to whatever the current rate was times two. If I want to enable a particular audio track, in this case I say let's say I want to enable the audio track of index two, I loop through all of the audio tracks until I find the one that's got the index two and just set it to be the enabled one.
Setting the volume of a video with range control so, in HTML since, since Safari was released for Tiger, there's been an HTML extension element called, an input tag where you can say type equals range down at the bottom of the screen. What that means is on every other browser, except for Safari at the moment, it appears as a regular input text field, but on Safari it recognizes that and gives you a slider control. As more browsers implement this extension, which is now part of the HTML 5 standard, you'll get browsers across interpolated with browsers having the slider control.
So in this example, I'm going to get the reference to the video element and I just set the volume as a fraction of the width of the range. It's a bit annoying with the range element, you actually have to know how wide it is to set it's proportion along the axis, but it's not necessarily you setting a percentage, you just have to work that out for yourself. It's important to note that volume goes from zero to 256, because we're all computer geeks.
Okay. So I discussed at the start what the old method of interacting with a plug-in was, which was querying it's state to work out what is actually happening. Well the way people normally program on the web is they use events, which means you register yourself, or you register your function as an event handler. And when something happens, whether the event is a mouse click, your function gets called and you do something with whatever you happen to want to do.
Now in the QuickTime plug-ins there's now coming up a set of events that you can listen to. They're based on something Apple proposed to the HTML working group within WHATWG and WC3, so that hopefully part of the standard and they'll be implemented by all browsers. These are much, much more convenient than using the state attributes that we were using before. So an example is I can register myself for the loaded event and I get told when the movie is loaded.
I get my callback invoked when the movie is loaded. Or I might get my callback invoked when the player is paused. So for example, I've got an HTML page, a custom controller and the user has clicked on the video, which is going directly to the QuickTime plug-in, it pauses itself because that's the way it behaves and it fires a pause event so that I, as a webpage, can capture that event and set my custom control to look like it's in pause state.
Another useful thing is you might want to do something like display some kind of message or have something happen at a particular point and time in the video. You could, for example, have custom subtitle tracks that you might have loaded from another source that you might want to overlay on the video that's come from a site that you don't have control over.
In which case, you could register points to say I want this function to be called at these particular cue points in this time variable that's passed on to the parameter and that callback method will be invoked when that time is being played in the video stream. You can also set in the parameters, say, when you hit this cue point, please pause because I might want to do something. Okay. So let me give you a demo of some of these things.
( Pause in speaking. )
So this is just a, here in this case I've loaded the feed of movie trailers that have come from the apple.com/trailers site. I can navigate through them. I can, let's peek one of my favorite movies here. And as I've told the plug-in not to play as it's loaded, so it starts in the pause state. And I can hit play. And the movie should play. Hopefully.
Now you see, what's happening here is the slider beneath the video is an HTML range element, I'm sorry, HTML input element with type = range. As the plug-in is playing video I receive an event that tells me what the updated position of time of video is and then I set the position of the dot along the slider.
Now unfortunately the build of QuickTime that's been shipped to you in Leopard and that's available on this computer doesn't capture the events as such. So in the newer builds as I press play I captured the play event and I can do a custom method that sets the name of that button back to pause, so I can control visually what the site of the controller is. So let's go back to trailers. Did I hit the right button?
And another movie, in this case I've told the plug-in not to, to respect the width and height of the video and to display the controller. So I'll show you here now. I'm initiating the playback of the video from within the plug-in controls and I'm still getting the same events, the same events are still getting passed to my HTML page. So, this video, apart from being really cool for teenagers, also has multiple audio tracks, so have the audio up just a little bit. Here I'll select a different audio track. Actually, this might be a bit loud.
And all I'm doing is using the source code that was there before to select a particular audio track that I've queried to plug-in to the movie is told me what it has. I can sneak around the plug-in. That's my favorite bit. Audio up a bit. I think the best way to watch a movie is like this. ( Loud music.
These guys have hooked up a slider to the volume of the plug-in. And again, in this case I don't have anything behind it, but you can see the background is showing through. This is actually.
( Loud music and movie playing. )
( Applause )
So again, I just want to reiterate that there's already been a number of sessions that have introduced this topic, so there's lots of data both on the Apple website and in the media that you can get, along with this conference once it's up on the website. Session 611, which was called AJAX and QuickTime, or had AJAX and QuickTime in the title, and also the apple.com, introduction to apple.com website has a lot of content. They've done an incredible amount of custom controls of QuickTime.
Not only that, you can use it as a reference. You go to apple.com, find a page that has some movies in it, it's both on the iPod and iPhone page or the iPod and iTunes page, you can see examples where they're replacing a movie with another movie, where they're controlling it with a customer control, where they use CSS to style particular sliders and buttons of the movie. It's really quite impressive stuff. So with that, I will pass it on to Antoine who will do similar things, but with SVG.
( Applause )
[Antoine Quint]
Hi everyone. So first of all, thanks to Dean for taking care of the stage so far. So the topic of this session was about rich media. And so far we've seen media, we've seen a certain amount of richness. But HTML and CSS, even though they're pretty powerful in terms of what you can do and people and authors have been taking CSS and HTML design to the next level, and bringing compelling experiences, such as on the apple.com website. But it's still not, at heart, a set of graphics and really technology is designed to do extremely powerful graphics and animations.
And it turns out that there's another technology out there that's just brand new to Leopard and Safari 3 and also the other platforms that Safari 3 is shipped on, so Tiger and lesser known operating systems. And it turns out that this specification new to Safari is actually made for graphics and rich media.
So let's go quickly about a first example of what SVG looks like. Before we get into more details, just briefly what it's meant to do. In this case I'm just trying to draw a rectangle with rounded corners, because that's what the web is like today. Everything has rounded corners.
And we'll going to fill it in with a gradient just to show we can do a little bit of graphics, not just about solid fields and etcetera. so an SVG graphics will have an SVG element as it's root. Just like in HTML you have an HTML element. You set its name space that a browser understands that this is an SVG markup that you're dealing with.
You set a view box to explain, to define a set of local units for your accordance system that you'll use in y our composition and from that point on everything will be specified as the child of the SVG element and will be directly handled by the SVG renderer in your browser.
In this case I want to define a linear gradient, a linear gradient element. Pretty straight forward. You give it an element ID so you'll be able to reference it later. Define it's direction using the X1 and Y1 and X2 and Y2 coordinates and then you can set as many number of stops as you wish. So in this case we have three stops. The first one's red, green and blue. Green in the middle with there's an arrow here, it should be an offset of 0.5. apologies for that.
And once we have defined our gradient this doesn't reassure anything. It's just a paint server that we'll be able to define and we'll be able to use later on. But now we're going to draw a rectangle just using the rect elements, set the width, height and the radius for the corners using the RX and RY attributes. In this case it would be 20 pixel radius for rounded corners.
Instead of transform to actually, translated to the center the accordance system will be centered on the object so at that point we can scale it down from its middle, rotate it 45 degrees and it's translated back to its origin. And finally we want to fill it with a gradient so we register a point to our gradients. My gradient is in the URL construct. So sure enough, it just shows a rounded rectangle rotated 45 degrees with a nice little gradient, red, green and blue.
So this is obviously very simple. But we'll get into more technical bits about SVG later, but I really wanted to spend a little time introducing what the SVG technology actually was in context on the web. So as SVG, just like HTML and CSS, the DOM and a lot of technologies that web designers and web application authors use today is the standard from the W3C, the World Wide Web Consortium This means that it's royalty free. You don't have to worry about people knocking on your door asking for crazy patenting money if you're implementing yourself. It also means that a variety of browsers are free to implement this specification without having to take into account the strategy of a given company's standard.
This is open, so just like HTML and CSS you'll find this supported in Safari, but also in FireFox and also in Opera. And I think what is extremely compelling about SVG is that with some technologies on the web today there are rich media and rich graphics and etcetera, they're often delivered as a plug-in. They're often actually proprietary technologies, so it's hard for browser makers to actually want to use those technologies because they don't really belong on the web with a concept of open standards.
But SVG is not like that. SVG is designed around markup just like HTML. It can use CSS for styling, just like HTML. If you want to program it you can use just JavaScript and the DOM. They're the same set of API's and programming language that we use with HTML and CSS.
So that means that if you already have content out there and surely anyone has built a web page or blog or use the web standards using WebKit and Cocoa applications, you do not have to start back from scratch. You can take what you already have based on markup, the same architecture, and just add graphics on top of that using SVG sporadically just for the places where you may need it. And I think this is what really makes it unique. SVG is really at it's core, a web technology.
So in terms of what SVG was designed for, besides integrating nicely with markup, other markup languages and web standards, it was really here to fill the need of rich graphics on the web. So the core of SVG, scalable vector graphics, sure enough it's going to be about 2D vector based graphics.
And on top of that, of course, everything is representing XML. That means you can structure your graphics any way you want it. There's concept of groups in SVG so you can group things together, convert to symbols so you can define reusable assets that you will use further on in your markup, etcetera. and just like HTML or XHTML, each part of the SVG structure will be directly exposed as a JavaScript object which you'll be able to program using the DOM APIs.
So this is a great difference compared to, for example, Canvas, which doesn't really have an XML structure. There's no way to document format. It's more of a problematic API for graphics. In this case you really have a documented model and something that is closer to what you're used to doing with web standard HTML.
So the future of supporting SVG, sort of basic is really what you expect from a modern graphics language, vector shapes, of course, this is SVG, Bezier curves, also. You need to be able to draw any kind of path that you want, quadratic Bezier, cubic Bezier, and etcetera. you also have really precise text layout.
You even have the possibility to define your own fonts using SVG constructs to ensure that your font will have the exact aspect that you want it to have on the web page when rendered. You can use linear radial gradients, you already have seen how we can use linear gradients.
Of course you have transparency. You can set transparency on the fill or on the stroke independently or everything as a group that's composited against the background as one graphical entity. You can, of course, import raster images either inline or by reference. So even though it's mostly a vector based language you can also apply the concepts of transforms, etcetera through your raster graphics buried inside your SVG composition.
And we also have more advanced features, of course. For example you can draw text on a curve, so if you need more of an artistic or more flexible text layout this is something you can leverage. Like I said earlier, I mentioned quickly you can use symbols. So any time you use a piece of SVG, if you give it an ID, like a symbol that you'll need to reuse, like a legend on a map, or something like this, you'll be able to reuse this using a simpler construct where you will not have to redefine all the drawing information about this piece of graphics.
And of course you can clip your graphics, you can mask your graphics with any other shape you can express in the SVG language. You can use patterns, once again, to define SVG to fill your shapes. You can use resolution independent filters or live rendered real time on the browser, which will react to scaling and etcetera.
you can do lightening effects, drop shadows, embosses and etcetera. and of course because it is an interactive language, it supports the DOM in JavaScripting, etcetera, you can also have animation working on all these properties. So we'll get to that a bit later, but first, we need to cover the basics and understand what you can do and how you draw things with SVG. So we've already seen an example of rectangle. This one is a square, I mean, not fully square in this case, but sharp edges rectangle. It's not rounded.
X and Y attributes, straight forward enough. We'll locate the top left corner of your rectangle. In SVG the coordinate system is top, bottom. So X20 and Y20 are up there as opposed to being at the bottom of your screen like you would expect from most desktop environments. But on the web, things draw from top to bottom.
So width and height, in this case, is set up with the width and height attributes. So nothing really fancy here. However, you've done a rectangle straight away. You wouldn't have to program anything. It's just directly done by the declarative markups. It's pretty handy. For a rounded rectangle, rx and ry, set the radius for the x and y axis.
A circle, define the circle center coordinate using cx and xy and then the radius. Ellipse, which is I guess more generic case of a circle, but as it also about semantics, so if you really deal with a circle you can identify a circle as a circle and not as an ellipse that has the matching parameters to define a circle. So in this case, the ellipse, just like the circle, takes a combination of coordinates to define its center and defines two different radius' for the y axis an the x axis, using rx and ry.
Polygon, this time we're using a list of points, so you'll notice here that we actually have, instead of using markup to define the list of points as other elements that could be a child of the polygon, we're actually stuff them all into one attribute as a string. So some XML purists have questioned this approach, but I personally feel that, given this is a really flat structure, it's just a list of points, boom, boom, boom, you go one after another, there's really no point in having a hierarchy and additional weight in the DOM to represent this. So you'll see a few instances like this in SVG full path data and transforms. You use micro synesis into, inside the attribute values.
In this case, a list of points and it will draw a lozenge. A path, once again, path elements like we expected. You can use all kinds of commands using the M command for move to, C for cubic commands, Zed to close your path. There are way more commands that you can draw any kind of path you can have an imagination for. And the kind of path you can draw of course is something very form like the Apple Logo. The code for the Apple Logo would be a bit longer, but you get the idea of how you could just draw a path on the screen.
So now you know how to draw things but you also need them to be filled with something so that they actually display on the screen. So far we kept that out of the mark-up and just focused on geometry. But you can control the fill and the stroke in SVG separately. We can use all kinds of ways to express your color values. So you can use a keyword like blue just the same as in CSS, you can use an RGB construct with absolute values going from zero to 255, or actually Ua percentage value.
You can use hexadecimal values. And so fill and stroke are set independently. And you can also set the opacity of fill and stroke independently, using the fill and stroke opacity. So for example, the top right, bottom right corner you can see a rectangle that has a stroke opacity of 0.5 and you can see the stroke is overlaid over another transparent fill. So you can see the effect of two things that are semi opaque.
Linear gradients, we're going to skip this one because I already said in the introduction how you can define a gradient in SVG. Radial gradients is very similar. Just change the name of the element to be radial gradient and not a linear gradient. We find the center from zero to one in the overall scale of the gradient and radius as well and there you go. You have your radial gradient.
Once again you could use many stops in a radial gradient and you can actually also use the stop opacity attribute to have your gradient have various opacity along the way. So, for example, if you wanted to do like a simple drop shadow you could have two black stops. The first one with a stop opacity of one and the last one with a stop opacity of zero.
So I mentioned that you could do clipping in SVG. You create first a clip method that does not render itself, but will define the shape of the clip path you'll be able to use later on. So in this case we use an ellipse illustrated in the middle of the screen and we'll apply it to a rectangle so the geometry of the rectangle is changed by the clip once we apply the clip attribute.
Point it to the original clip that it will find and it will clip it dramatically. So you can see at the bottom of the screen the results of the actual clipping operation. So once again, just like linear and radial gradients, you can define assets. Your clip path is an asset. If you want to clip several shapes on your document using the same clip path, no problem.
You can always use the URL construct to point to it. But as obviously I'm not going to cover all of the graphics future, you'll, developers and you'll, I'm sure very smart, so you'll be able to browse around the web, look at some examples, look at the specifications if you're really brave and courageous and you'll find out all about the vast array of graphics primitives in the SVG language.
But before moving on to scripting and more advanced features, I just want to show first of all how we can use CSS with this. So far we've only used XML to define paints and etcetera in the language, but in this case where it can define a class, just like it would in HTML or CSS. This class called mr-f, you define a fill and a stroke and a stoke width, they look the same as the XML attributes.
They're just mirrored as CSS properties that you can use in a class or you can actually use them in a style attribute as well. So in this case, we used the style attribute as opposed to a fill attribute we'd just use a fill property as a value for a style attribute.
So this is how we can draw text and this is how you can put text on screen, xy coordinates, pretty simple, which will define the bottom left corner, the baseline of your piece of text. This is how you can also apply a transform to your text. Of course it's all vector based and your text will be rendered with vectors in composition and you can apply scaling, rotation, whatever comes to your mind and whatever you need to achieve your graphical effect.
In this case we show how we can use a class we defined earlier on a rectangle, we just use the class attribute, just like in HTML. Very straight forward. So the rectangle you see on screen here is in that class. The fill and the stroke are respected and the stroke width as well.
And to show how we can use, define and use all these assets, in this case the first path will be the smaller Apple Logo displayed on the bottom left in white. And we use it afterwards with the use elements, which means that basically I'm not going to define a new set of graphics, I'm just going to reuse something that's already been defined.
So I point to the existing piece of graphics with the xlink:href We used a hash to locate a local resource, in this case going back to the Logo and from that point on I can change, its look and feel its transforms etcetera without changing the original piece of graphics. So I'll apply transform, scale it and rotate it a little bit, and I will also use the CSS class I've already used to define its look and feel.
So these are a few of the most basic features of SVG that I really wanted to cover. Because this is basically how you draw things and how you structure things. And once you understand what the SVG tree looks like and what SVG elements look like then you better understand how to use the DOM APIs and scripting, you can directly update things that are rendered on the screen.
So SVG scripting will allow you to basically add interactivity and animation to your graphics. It's not all about however nice it is to have this nice XML based language to draw graphics, this is not going to cut it for you. You want something that has a lot of impact, you want the user to have a new experience on the web and in your web application, and you really need JavaScripts and animated effects for that.
So the basic of the DOM scripting is that it's working against the XML structure. The DOM is a set of generic APIs against XML just to manipulate, update, read and write into your XML structure. So these are the same APIs that people use on the web today in their web applications. All the things you hear about AJAX and etcetera on the AJAX libraries, they'll wrappers against these kind of functionalities.
They will offer high level things but they undoubtedly will be using that as an interface with the XML tree rendered on the screen. So each part of the tree is represented by DOM objects. So if you have a rect element it will be an element in which you can set a width and height and etcetera to update the geometry of the element. This is all expose in JavaScript.
And you have different classes of APIs available to you in the core DOM APIs. The first one is navigation. Before you can reach something in your document to update it, you need to navigate to it and there are different ways to do that. If you want to iterate, if you want to find the parents of your current element, if you want to remove it, for example, or etcetera, you can use a parentNode field.
If you want to find a list of the nodes that will be a child of your current element, you can use the childNodes. You can use the first child to get to the first element and then you can iterate through them using the childNodes property. Oh, what happened there? I think I paused it.
Mishap. You can use the getElementByID method to point to an object that you already identified in markup using an ID attribute. Dean already showed that in his demonstration to get a pointer to a video element, for example. And you can also get a list of elements that match a certain criteria.
So in this case, with the getElementsByTagNameNS, if I set the name space to be the SVG name space and the name to be rect, for example, I would get a list of all the rectangles from that point on in the hierarchy and I would be able to iterate through them, for example if I wanted to change their look and feel, if I wanted to remove all of them in one go, etcetera, or add a new piece of interactivity to them, I would use these kind of APIs to navigate through each of them.
So once you have pointed to elements and you know how to navigate, you need to do something with the elements. You have a pointer, you have a handle, a rectangle, you want to change it's width or it's height, you want to read what its state is before you do anything to it and in that case you'll need to see what the attribute values are.
So you can use the getAttributeNS method, pressing once again a new space in attribute value, or you can use the setAttributeNS method to change the value. In that case you'll pass an extra parameter to set the value. And if you're dealing with text content you want to read what's inside for example a text element or to change the value of that text element, then you will use the textContent fill, which is a read write property.
But that's not all. SVG will not just be about what you already have in your document when you load scripts. It will be about you able to create a new document on the fly. So for example you could create a drawing app in SVG. What you originally have in SVG document that's completely empty and as the user interacts with it you can add new elements to the DOM Tree.
And the way this is done basically is you need to create a new element, a createElementNS method. Once again you'd give it a name space so you could create both HTML elements and SVG elements and you give it a name. once you've done that then you can also create text nodes which are different from elements. So if you want to have a text element, you also need to create a text node through presets text value.
And once you, so of course when you've created an element you can use the setAttribute method that I outlined above to set its values. And once you have it done you have to put it in the tree so it renders. So now you can use the appendChild method that will add a new piece of graphics in your tree, or you can remove something that's already in the tree using the removeChild function. So these really are the more basic, the most basic functions you will see used on the web today.
So some samples. In this case I'm creating rectangle elements. Now I'm getting a handle to what is probably a text element that is identified with the mytext id and then we'll update it's content to print Hello World, which I'm sure you're pretty familiar with. And in this case I will probably have a handle to a rectangle elements and it will change it's width to be 100. these are really simple ways that you can update or create content in the DOM.
In this case I have a function that creates a rectangle given x y, width and height, create elements, (inaudible) space and erects a string to give the element name of the element I'm creating, setting the attribute xy, width height with the parameters I'm giving it and then return that element then the user will be able to append to the tree at whatever location he feels happy to do so. Very simple.
But of course, if we're dealing with interactivity rich media, you want to be able to react to what the user is doing. And interactivity is all about this, it's about how you react to UI events. So the first way you can react to UI events is not actually using SVG script, JavaScripting at all.
Just like in HTML when you can use CSS pseudo classes to react to an over state or a focus state, you can have nice new hover effects on your links or whatever, in SVG you can actually use the same thing on any of the elements. It is using CSS just like any web technology should.
So this is really, you should really use this when you don't need to apply any logic really to your change of state, it's just really a behavior. So if you have a button that just highlights when the user has the mouse over it, then you can really very easily achieve that using CSS. No code required.
Just updating the property that will be applied to the element. You can, of course, just like in HTML once again, use marker based handlers. So if you know there's already a piece of script that you would have run on an element always, then you can just use that as opposed to adding it programmatically, which is what you'll really need when you start generating graphics and you need to attach a behavior call by script.
While in this case, you'll have the most flexibility, you'll use the addEventListener method, you'll be able to add many different handlers for the same events as opposed to changing it if you change the value of the onclick or onmouseover attributes, in this case you can just add just more handlers one by one, just adding them to your element. And this is really good when you need to deal with a really dynamic, and this is a user interface and this is really the real way to do it if you're a JavaScript programmer. This is what will give you more flexibility and most power.
But SVG is pretty different to what HTML is. In HTML most of the things are defined either using CSS or some of the HTML attributes will be directly rendered as is on the screen. It's easy to make a mapping between the actual value defined in markup than what happens on the screen. But with SVG it's actually, it goes beyond that.
If you're drawing a path, for example, you'll be giving the SVG implementation list of commands that will automatically handle and render on the screen for you. And if you want to know (inaudible) of this, well there is no width or height attribute that you could query directly. So you really need something that will abstract all of this to give you real graphics capabilities.
So the core DOMs only expose the string values, so this is an issue. The SVG language specificities, there's micro synesis like I talked about before, now complex types exposed really a core to graphics. And, well, if you're a graphic programmer you're not going to want to use just string based operation itself, you're going to want to have real graphics tools.
So for this, the SVG language also extends the DOM. It defines a new set of APIs called the SVG DOM that compliment the existing DOM. You can always use the preceding APIs I told you about. This is fine. But if you need a little bit of graphics oriented programming, you'll be able to resort to the other APIs from the SVG DOM.
So for example you'll have typed access to attributes, so if you want the width as an integer, you'll be able to access this directly as opposed to parsing a string. You'll be able to get access to computed values if you have, for example, transforms that add on one to another through the tree, first to translate then to scale and rotate.
You don't want to keep track of that and climb up and down the tree. And SVG will be able to query directly what happens there. It'll be the same when you need to know about a bounding box for example and etcetera. so let's see how that works. First of all there are built in data types in SVG. So vector language will have to define what a point is, for example. This is really basic in vector graphics. So we have an SVG point interface in SVG.
Very simple, give an x and a y attribute, nothing really fancy there. But it gives you also a matrix transform method. So other parts of the SVG DOM will feed you back a matrix from a computed transform matrix applied to an element or something like this and you will be able to apply such a matrix to your points if you need to change the coding points of your system for example, this is definitely what you'll be using, matrixTransform. So that's a first example of graphics features and computations that I exposed in the SVG DOM.
There's also the SVGRect data type. xy within height, pretty simple. And the SVGMatrix data type, which we can fit into a matrix transform call on SVG point and this is the type that will always be returned when you're dealing with a transformed, a computer transformed that goes all the way up to the screen, etcetera. it will always be obstructed behind a nice data type, on which you can call a sort of familiar operations so you no longer have to create your own methods about how you go about computing matrixes and changes to a matrix.
In this case, if you have the matrix of an element and just want to rotate it, you can just use a rotate method. And the same with scaling, translating, you can invert your matrix, you can multiply it with another matrix. It really caters to all the needs you have with matrix programming.
And to obtain those data types that you want to work with, they're all available in the SVGSVGElement interface represents an SVG element. All the interfaces in the SVG are prefixed with SVG, so in this case here's an SVG interface for the element with the name SVG. It's a pretty funny name, but. And you, on this object you'll be able to call createSVGPoints, quite, createSVGMatrix, createSVGRect and etcetera so you can create on the fly some of those instances of those classes.
There are more key graphics API building on top of this data type of course, and they're all located on this interface called SVGLocatable. SVGLocatable is a high level interface that's implemented by each element that will draw something on the screen. They're all part of the core functionality of graphics programming. And these functions, for example, getBBox, you have this element, you have a group of elements, it's very complex graphics. There may be hundreds of elements surrendered together. Call getBBox, it will feed back an SVGRect element with all the information you need to know about.
GetTransformToElement. This will take you from one piece of the tree to a higher piece of the tree and just give you the transformation matrix going from one point to another. So, for example, you're clicking in the high level coordinate space and you want to know exactly what that coordinate is with respect to a rectangle inside of a document using this method or actually against getScreenCTM which will go all the way up to the host pixel coding system will help you to convert units.
Very helpful. And this API is really key when you're building a scalable user interface. You don't want to have everything rendered in the same coordinates system. You want something rich and you want something you can manipulate with transforms and matrices and these kinds of methods will extract that all away from you so that you can just focus on graphics related tasks.
So for example making use of some of the functionalities highlighted. This function, getMouseCoordsInContext will allow you to click anywhere on the screen and get the coordinates of the mouse not related to the view port of the document, like you usually have using clientx and clienty, but actually getting it within the shape. So if you're sitting on the top left corner of the rectangle that's all the way down, translated and rotated and whatever, in your document, you will be able to get the coordinates that will be like one pixel up and one pixel down.
So the way you do that is first you create an SVG point. Because you will be able to create that point with a matrix, you've set the x and y coordinates to be the coordinates of the events that have been triggered on your elements and the context is the element that you want to have the coordinates returned local to.
So in this case you call a getScreenCTM function on this context it would give you the computer transform all the way up to the pixel based coordinate system. And once you have this matrix inversed, because you want to go all the way in the opposite direction, and you can apply the transformation to your regional mass coordinates past the matrix and return that object to the user. Very straight forward.
So this is how you can do interactivity and you can program graphically against your SVG content. But of course, which media will be about animation? This is the number one thing you'll want to do. You'll want to be able to react to the user, to the user's interaction and not just change graphic state discreetly, directly on the screen. You'll want to have transitions.
You'll want to have things fitting in, fitting out, popping out and etcetera. the kind of thing that you see on the web today, and that you probably didn't think were possible in a browser. Well, it turns out with SVG and JavaScript and the DOM you can really create a pretty compelling presentation.
So the key to doing animation is using the built in function in JavaScript called setInterval. This will allow you to call a piece of code repeatedly over time until you figure out the state you wanted has been reached and then you can cancel the timer using clearInterval. So, for example, a way you would go about fading an element, you would pass an element to this custom function called fade you would figure out the current time so you can tell how long the animation, when the animation starts.
In this case we'll set the duration to be 2000 milliseconds, so two seconds, and at that point we create our interval. We keep our pointer to that interval so that we can cancel later. So restoring the variable core interval and we pass to that set interval function a special function that will actually be called to perform that animation.
So each time we iterate we get the current time to do the down time between the start time and the current time and find out when we over the time. Once we over the time and we figure out a process is beyond one then when we clear interval, the animation will, this will be the last iteration of the animation. But each time we iterate through that animation, we will set the opacity attributes to be whatever our progress is subtracted from one. So basically you will be fading in from opacity one step by step all the way to opacity zero.
This is a more advanced effect In this one we won't just fade we'll also apply a snazzy little effect. We'll scale the element down and we'll rotate it so it'll look like it just disappears very neatly and graphically on the screen. So in that case we'll have to do a little but more work.
First of all, if you want to rotate things around their center in SVG, we'll have to figure out what the center is so you can translate the coordinates system to that point and translate it back so that it's rendered in place. So first of all, to find out what the center of that element is, whatever kind of element it is, it could be path, it could be a set of objects, it could be a rectangle, I don't need to know exactly the semantic of the object. All I know is there's a graphic object and it's good enough for SVG.
Well just give you the bounding boxes and the getBBox method. Once I know that I will divide the width and the height of these by two and add the x and the y coordinates so that I know what the center is, store these in tx and ty attributes, as I will be using them for translations later on.
And then I will get a pointer to the transform of our current element. Because the transform is an SVG transform object, I'll be able to perform special actions on it so the transfer will be updated directly without having to re-serialize in an XML form. I also get the matrix from that transform in consolidating whatever transform parameters you may already have.
That shape may well already have a translation to it, a rotation and etcetera. I do not want to get rid of that, I just want that to be available to me in a nice matrix. So I consolidate the transform and I get the matrix form of that transform.
And from that point on, I have subtracted , in this case, the animation code we saw in the previous slide in a class that will be called animator, which will abstract the iteration and checking on the time for me, so I can focus on the code here, but basically this animator will run for 2 seconds, 2000 milliseconds, and each time it will figure out what the new scale is, so it will be one minus the progress.
The rotation angle would be going from zero to thirty degrees, so we multiply 30 by the progre0ss and we will, at that point, reinitialize the transform to be whatever the matrix, our new matrix that we will apply by translating the object to its center then scale it, then rotate it to our new angles, and translate it back so it's nicely in place. This will give you an object that will just scale down and rotate at the same time. And of course we (inaudible) so just like in the previous example, we update the opacity attribute.
So now this is all about the theory and I'd like to show you basically what you can do with SVG both in a graphics aspect, so you can see first of all the core things you can do and then integrate it with multimedia using the same QuickTime APIs I told you about earlier to create a really compelling graphics presentation using HTML, CSS, SVG, JavaScript, DOM all together in one layer in WebKit. It's actually the second demo machine, please?
Thanks. So I'm just going to run those in Safari 3. just either of you can do the same by either using Leopard or Tiger or whatever operating system you may be interested in. I'd like to first start with a simple example to show how SVG can be used for creating scalable user interfaces. I just noticed, actually, that there was a section previous to this one about scalable user interfaces in Leopard. Unfortunately I missed it so I'm not really what he told the audience.
But SVG is another way to do that certainly using WebKit. And remember, WebKit can be used in your Cocoa application. It's not just about web sites here, it can be also be about the future of your application user interface. So in this case I have what looks like pretty much the same kind of fields that are natively supported in Safari, the input type search elements.
But instead of just using the HTML elements, because I like to replicate things and just study how people treat these nice interface widgets, I actually re-implemented it in SVG. And because it's all based on scalable vector graphics I can just update its size on the fly and it will always look crisp.
So when you're dealing with high DPI displays and you don't know, with high DPI displays things can get really tiny and you don't even see what you're dealing with any more. In this case you could just say this thing is going to be 3 centimeters width, whatever DPI is and etcetera. and you just get more details if the DPI is higher.
And I'm actually, I have a custom focus ring on this one expressed also in SVG in a nice little gradient and this piece here is actually an HTML input element. That's just transparent and rendered on top of the SVG. Because I don't want to re-implement everything in SVG. An input field is actually pretty complex.
There are internationalization issues to cater for and etcetera. and so in this case I'm like well I just want to take out the graphics and I'll just overlay this HTML elements, scale it at the same time as the SVG, rendering one layer, so it'll always look nice and sharp. So this is very simple demo of how you can create scalable user interface widgets using SVG.
In this case we're just creating a standard (inaudible) document, not mixed with SVG and HTML. This is one is just SVG. And it's a way to visualize traffic data from Google Analytics, so I call on a website called svg.org, which is a community website for the SVG community and I have a Google Analytics account.
I've loaded the different, the last few months on this desktop from the XML feeds they provide us and you can see this graph is rendered on the fly using XML HTTP requests to load in the data and the DOM functions to create the graphic representation on the fly. So obviously this is SVG so you can scale it up and down, add a little over states on these buttons expressed in CSS, like I told you about earlier, because there's nothing really too fancy going on here, no point in writing scripts.
But I will say I've more advanced interactions, so I have a little info bubble that will briefly animate to the new points so that it's really smooth. It will display the new data directly represented in the XML field I gathered information from. You'll see that I've dated the dates and all of that on the fly. We can also move to the next month.
Have a nice little transition between objects, or use animation expressed with a DOM. So basically for each point I'm going through I create a new animation object and I just change it's new y value to be using animation. So this is all pretty simply and to get more detail we can run the animation in slow motion, we can see how we can rotate text, change to fading, translate things on the fly and etcetera. All pretty neat, we can resize on the fly. It's all done independently. The scaling is done automatically. You don't have to worry about it. You don't have to tell SVG this is the width and height I want or etcetera, it just scales automatically.
But this is a session about rich media, right? So we have to show video. We have to show something more compelling. And this is actually a demo that I already showed earlier in the week on the Vector Graphics and WebKit presentation, but I took it to the next level by adding a QuickTime instance in my presentation that will be directly integrated with HTML, CSS and SVG.
So basically this is a front end to my Delicious Library database on my system. Delicious library is a really neat tool for measuring your library. And it's really nice because it allows you to have your content available as an XML file so you can do all sorts of data mining on this or whatever. And in this case, I just load the XML database into my scripting context using XML requests. Just the AJAX Web 2.0 way.
And I'll be able to query different things on there. So for example if I want to find out, looking for, I think I have records from Wilco. Just typing in directs, runs Xpath queries on the model and it will return a set of objects that will translate to an SVG rendering. So in this case all these little objects are SVG objects.
But they're also wrapped into an HTML div and they're laid out using CSS. So, for example, each of them isn't in my block. That means instead of having to compute a grid layout, and express it in SVG, I can just read it in CSS, because that's pretty good at doing this. So when I resize the window, there it is.
And on top of that you will see that I can even have my own scroll bar also defined in SVG because I like to have my own look and feel. Rich interaction. No problem. I have little drop shadows here to overlay the other bits of SVG. This is also defined in SVG so it doesn't clip to harshly where you can see it fading in and out.
And, of course, because it's SVG, I can just change the states and width and height of objects. So in this case, I've just changed it using this little slider and just because I like doing that kind of stuff I can run gratuitous little animation on each object when I click on them. This is the object that we coded up earlier when it's scales and rotates at the same time and scales back up. So that's all pretty neat.
But also can search for movies, so for example I know a bunch of Kubrick movies. There they are. And actually I've got a bunch more movies. I can see a lot of data. Everything's pretty smooth even though I have a lot of data in this case. And I might choose to actually watch one of those. So I don't have the rights to display everything here in it's full length, so Apple actually hooked me up with a nice little video they made, which will just show exactly the same thing. In this case I will click on object trigger video.
It will scale up together and it will display straight ahead on top of my presentation, we've got a nice little border and just like any object, I can actually resize it on the fly directly. Pretty simple. I can go in full screen mode like so. I can scroll within the video.
Go back and forth in the movie. Bring it back to zero level. And if you turn the volume up, please, a little bit. When I turn it down, when I scale it down, I will also gradually mute it. No real reason for that, you know, for kicks. It's something you can do.
It's really a demo, right? So of course, scaling things up and down. A couple of bugs in my code, I'm sorry. But there you go. It's pretty powerful. Pretty simple, I think. This really shows how you can integrate things all together. Put it back in full screen. Background fitting in. slow motion between the different frames, etcetera. very simple. So, interesting.
So that's it for me today, actually. This is all I had to show you. And I just wanted to remind you before I left the stage that this is not just web technologies. Granted you can use Safari 3 to do all of these really snazzy things. And we have the QuickTime team and the WebKit Teams and the Safari Teams to thank for that.
But it's also, WebKit is also just another took kit for you to use in your Cocoa applications. And even though Cocoa has great foundations for widgets and really cool graphics, APIs and etcetera, sometimes you might want to do something a little bit different and those kind of interfaces are really, really pretty cool to work with and I really hope you feel a little bit inspired to try out these things in your own application. So I will give it back to George who took care of organizing this track and he will wrap this up for us. Thanks.
( Applause )
George: Okay. There's about 10 minutes left. Got some housekeeping to do. Raise of hands, we've got to show this slide. How many of you guys have seen the iPhone development websites for iPhones session? Pretty much everyone. All right. Let's just quickly brass through this then. This is a recap.
When you're developing AJAX applications for iPhone, we are encouraging good design disciplines. And what do we mean by that? We encourage you to use a column based layout. Use divs. Use a grid system for laying out your content. Size matters. So take that into consideration with the content that you will potentially be providing through and for your AJAX application.
Media queries. We are highly encouraging you to adopt the CSS based design methodologies for modern web design, which means please don't use tables, use everything in CSS. And in particular, use CSS media queries for defining the actual layout, the feel and the sort of aesthetic for your site. Additionally the media queries will be able to translate the size and height and width of your content as the device renders it onto the actual phone. Optimizing for iPhone. Viewport.
Take into consideration the actual total, you know, region of the actual web page or the web application that you're developing. That will help the actual device itself and anticipate how to do the scaling when it actually renders the content within Safari 3 for iPhone. Double tap. When you're working with your content, when you break stuff into the column based layout structure it helps also the device to designate what area are you actually adding focus onto and using the scaling capabilities to actually do the zooming up on the actual device. Text size adjustment. Please also don't, try not to or refrain from having full width of the actual window text flows. Put them into divs, again, using the column layout.
Events. Read up on, or when we actually release the audio, and the session and the slides from the developing websites iPhone session, study what actual JavaScript events we actually support on the actual device. And then media. Be sure to encode for both Edge and WiFi networks using QuickTime ref movies, using H.264 baseline profile.
More information contact Mark Malone, who is the Internet and Technologies Evangelist for WWDR. Handy links, these will also be available in the slide deck once we publish it to the ADC website as well as these links here are currently available with a lot of documentation on WebKit.org for user agent detection.
You can read up sort of on CSS3 media queries via the W3C website as well as some of the work that we're doing and pushing the audio tags back within the WHATWG group as well as the new W3C HTML 5 specification. Sample code for the session you just saw, Developing Rich Media Web Applications, is going to be available at this URL shortly after the session. Probably sometime over the weekend.
Anything audio and video related to iPhone development, please contact Allan Schaffer, he is the point of contact for that. And if you need the tool to start developing movies for handling the Edge versus a WiFi sort of detection, you'll need the ref movie tool maker as well as contact QuickTime seeding to get seeded for the version of QuickTime that will have the encoding capabilities for iPhone. That is currently not delivered with the Leopard CD's that you all have. [email protected], submit your application for admission into the actual beta program.
The next session, we have the pleasure of having Sam Stevenson from 37 Signals and also the creator of Prototype here. And he's going to be down on Russian Hill at five p.m. this evening. And then in this room here, we have Alex Lindsay from PixelCorp going to be providing a session on Effective Sophisticated Podcasts, which is highly relevant towards anyone who wants to create content for iPod, Apple TV, as well as iPhone.