You are on page 1of 102

appliness

#2 - MAY 2012

Pamela

Exclusi

ve inte rview

(

Fox

The digital magazine for web app

DEVELOPERS

TUTORIALS

HTML5, BACKBONE, jQUERY, PHONEGAP, BOOTSTRAP, CSS3...
HTML5 & JS

PHONEGAP FILE API, MULTIMEDIA COMPONENTS, APP-UI JS

appliness

THE FIRST DIGITAL MAGAZINE FOR WEB APPLICATION DEVELOPERS
welcome to appliness. the contributors of this free magazine are all professional and passionate developers. if you want to write a tutorial, showcase your application, contact us on our website appliness.com. we hope that you enjoy reading the second issue of this magazine.

(
FOCUS GROUP INTERVIEW SHOWCASE video tutorial VISUAl and juicy WTFJS BLEEDING EDGE TEAM

TABLE OF CONTENTS SHAPE TOMORROW TODAY

EXPRESSING RICH LAYOUTS WITH SIMPLE, DECLARATIVE CSS
by Deepa Subramaniam

DON’t WORRY, BE APPLI

DRAG & DROP WITH JQUERY UI
by Michaël Chaize

Javascript object creation: learning to live without “new”
by Keith Peters

Crafting native looking ios apps with html
by Christophe Coenraets

using backbone.js with jquery mobile
by Christophe Coenraets

demo of handlebars, and why you should consider a templating engine
by Raymond Camden

REAL-TIME data exchange in html5 with websockets
by Ryan Stewart

swipe to delete items with jquery mobile on touch devices
by Michaël Chaize

LIBRARY OF THE MONTH

app-ui, a javascript library
by Andrew Trice

HTML5 AND MULTIMEDIA: VIDEO, AUDIO AND COMPONENTS
by Ian Devlin

INTERVIEW OF PAMELA FOX
by Maile Valentine

Three great PHONEGAP APPLICATIONS
by Michaël Chaize

WHICHELEMENT.com

pull quote and comments
by Terry Ryan & Ray Camden

phonegap and the file api
by Raymond Camden

decision path to phonegap
by Michaël Chaize

false advertising
by Toby Ho

generating color palettes from html5 video
by Raymond Camden

css variables draft
by Terry Ryan

HELTER SKELTER NEWS

NEWS about html and javascript
by Brian Rinaldi

who’s behind the magazine
by the team

NAVIGATION GUIDE READ

NAVIGATE
GO BACK TO THE LIBRARY MOVE TO THE PREVIOUS ARTICLE DISPLAY THE TABLE OF CONTENTS VISUALLY BROWSE ALL THE ARTICLES

MOVE TO THE NEXT ARTICLE BY A HORIZONTAL SWIPE

READ THROUGH THE ARTICLE BY A VERTICAL SWIPE

appliness

SHAPE TOMORROW TODAY

Expressing Rich Layouts with Simple, Declarative CSS

Along with the community, ADOBE ENGINEERS ARE developing new standards and advancing existing standards. IN THIS ARTICLE, they introduce CSS REGIONS AND CSS EXcLUSIONS which are two proposals for the w3c. thanks to these new additions, a designer or developer can create high-quality, magazine-style layouts for the web using HTML5 and CSS3.

a rich digital format
It is hard to deny that it’s an exciting time for innovation on the web. Some of the powerful proposals coming out of working groups in the W3C are letting designers and developers build standards-based rich content with HTML5, CSS3 and JavaScript in a much easier way. One area that is ripe for innovation is around how to better translate classic print designs to a rich digital format. The reality is that several of the capabilities that are taken for granted when designing content for print are still very difficult to implement using web standards. When print designs are converted to an HTML-based form for digital consumption, one of the current limitations is that expressive layouts do not translate well. This is an area that Adobe has a lot of experience with and a problem we want to help solve. To start, we have worked with partners to introduce two proposals to the W3C CSS Working Group: CSS Regions and CSS Exclusions. In addition to championing two new standards, we’re implementing these proposals directly in open browser engines like WebKit. With both CSS Regions & CSS Exclusions, a designer or developer can create high-quality, magazine-style layouts for the web using HTML5 and CSS3.

CSS REGIONS
Let’s first discuss CSS Regions. HTML and CSS today allow you to place text in a box, and has support for flowing text through identical column boxes contained in a single box. If you want to size and position
3/7

(

separate boxes for your text to flow through, you can only approximate your desired layout by breaking up your text and assigning which text goes in which box. This results in a fixed layout that breaks down at the slightest change of font or window size. With the introduction of CSS Regions, you can flow unbroken text fluidly from box to box without any restrictions on size or position. Designers & developers are free to use columns and gutters with different widths and flow text through whatever expressive layout they choose to create. CSS Regions makes achieving this easy. With this new feature, you can specify how text or images should flow across multiple regions with simple, declarative CSS. In the video below, three distinct regions are specified and as the browser resizes, notice how the text flows naturally from one region to the other.

VIDEO CSS Regions shows how browser resizing causes fluid reflowing of text

The code for this is quite simple. The text source is named using the new vendor prefixed -webkitflow-into CSS property on the element that contains the content. This naming causes the content to be removed from the normal CSS layout flow and allows it to be inserted into specially defined regions by setting the -webkit-flow-from property. The code for the video above looks like this: CSS: #source{ -webkit-flow-into: main-thread; } .region{ -webkit-flow-from: main-thread; } HTML: <div id=”source”> <p>Lorem ipsum dolor [...]</p> </div> <div id=”region1” class=”region”></div> <div id=”region2” class=”region”></div> <div id=”region3” class=”region”></div>
4/7

In fact, regions can be positioned anywhere. Using this same syntax, you can have multiple threads of text or images flow into separate chains of regions. The video below shows two threads of text flowing into non-contiguous regions because the order in which text is flowed is explicitly controlled by the -webkit-flow-into property.
VIDEO Multiple text threads flow naturally into non-contiguous regions with simple CSS properties

Here is a video of a more complex example created by Adobe engineer, Christian Cantrell. In this sample, a short story is formatted using CSS Regions. You’ll notice that the story is divided into two columns, which is more of a print-like layout and friendly to read. The power of CSS Regions becomes obvious when you see that the text is actually flowing from one column to the other. Notice that as the browser resizes, the text flows from column to column and the page concept is maintained. Without CSS Regions, you would have to write a fair amount of JavaScript to break the text into appropriately sized pieces (and re-run the script any time the font or window size changed). Now it’s just a matter of setting a few CSS properties!

VIDEO Multiple text threads flow naturally into non-contiguous regions with simple CSS properties

5/7

What is even better is that CSS Regions can be experimented with now! All of the above examples were shown in recent builds of Chrome. CSS Regions is also available in the Developer Preview of Internet Explorer 10 and nightly builds of WebKit. While there has been great progress, CSS Regions is still a cutting edge feature so in some cases it is protected by both vendor prefixes and runtime flags. To play with CSS Regions in Chrome you will need to enable the feature through the --enable-css-regions runtime flag. There are instructions on the web about how to easily do this in Chrome. We are thrilled with how CSS Regions is progressing and are working on some new features to add. These include making it even simpler to style regions, auto-setting the height for regions, and introducing a page template model to create boxes in CSS and better handle pagination. To stay informed of the evolution of CSS Regions and get access to sample code and new demos, keep an eye on the CSS Regions page on html.adobe.com.

CSS EXCLUSIONS
A complementary feature to CSS Regions is CSS Exclusions, which allows the creation of custom text exclusions to wrap text with shapes or images. Again, with simple CSS properties, you can define a custom shape as the container for text, like so:

Or cause text to flow around a custom shape like so:

6/7

This behavior is simple to achieve with just a few new properties CSS Exclusions introduces. The –webkitwrap-shape property defines the boundary in which to flow text content and also defines the area to be avoided when laying out content. The -webkit-wrap-shape-mode property controls how the content responds to a shape and flows the content appropriately. In this video, using the –webkit-wrap-shape and –webkit-wrap-shape-mode CSS properties, you can see several things. Notice that as the browser resizes, text flows around the custom shape and if the shape size changes, the text continues to flow as one would expect of a responsive layout. Additionally, the custom shape can be dynamically swapped to any polygon and text layout and reflowing capabilities are maintained!

VIDEO Dynamic shapes can be used to cause text to flow naturally with CSS Exclusions

Adobe is actively working on CSS Exclusions and while it is not yet fully available in current browsers, it should be available in Chrome and WebKit nightly builds soon. The CSS Exclusions page on Adobe & HTML will be updated as the feature progresses but till then, it is there you can access a custom WebKit build to play with the feature now. We think the power that both CSS Regions and CSS Exclusions offer designers and developers is very exciting! Expressive, liquid layouts are achievable with just a few CSS properties and a clever eye. We’re thrilled that the features are being used to create compelling digital experiences, like in the following example where both features are used to cause text to flow around the mountain and car images as the user scrolls the arrow to pan around. Keep an eye out for CSS Regions and Exclusions to land in your favorite browser and we hope you consider using them as you develop rich layouts on both desktop and mobile devices.

ABOUT THIS ARTICLE
Deepa Subramaniam is the Group Product Manager for Adobe’s Web Platform team – a team focused on making the web more awesome by collaborating with the community to champion new standards and contributing to open source projects like WebKit. She loves sun, coffee and good-looking code. http://html.adobe.com @iamdeepa

ONLINE RESOURCES The Adobe & HTML website http://html.adobe.com CSS Regions W3C Specification http://dev.w3.org/csswg/css3-regions/ CSS Exlusions W3C Sepcification http://dev.w3.org/csswg/css3-exclusions/

appliness

DON’T WORRY, BE APPLI

Drag and Drop with jQUERY UI
WHY USE DRAG AND DROP ON A TABLET?

Drag and drop is a classic gesture in desktop applications. Learn how to code it on touch devices such as your tablet using jQuery UI and some hacks.

As a RIA (Rich Internet Application) developer, I try to introduce meaningful and efficient user interactions in my apps. A classic and natural way to associate items is to use drag and drop. It’s a classic action in desktop applications. With the introduction of touch screens, it’s even more natural on mobile devices. When you need to order items, assign items to categories or to an action, drag-and-drop makes sense. In this tutorial, I’ll play with a list of “team members” and a list of “tasks”. As you can guess, the enduser will be able to assign a specific member to a task member using drag-and-drop. Desktop frameworks have implemented Drag and Drop management based on mouse events. That’s why a lot of these libraries are not effective on touch devices. We’ll see in this tutorial how to hack these libraries and simulate touch events. On the next page, you can start playing with the final application. Drag users on tasks using your finger and read this tutorial to understand how to code it.

P

d n u o laygr

(

Difficulty
- rookie - intermediate - expert

- jQuery I U y r e u Q j - CSS

Todo list
- drag stuff - drop things - wash fingers
by Michaël Chaize
8/14

PLAY WITH THE FINAL APPLICATION

Some cool features that you should notice: - If you don’t drop a user on a task, then he will automatically move back to his original place. - Users snap to the edges of the task boxes while dragging them on the stage. - Once a user is assigned to a task, you cannot drag him anymore, and you cannot drop another user on this task.

Enable Drag and Drop on touch devices
There are several ways to enable drag and drop for items in a web page. For this application, I wanted to use jQuery UI because it provides robust abstractions for low-level interactions and animations. It’s built on top of jQuery, so you can easily reuse that library for your desktop and mobile apps. Once you import the jQueryUI library in your web project, you just need to give an id to a <DIV> element and call $(‘#idOfMyElement’).draggable(). Unfortunately, jQueryUI has been designed for desktop apps and mouse events. David Furfero (furf.com) has developed a small hack that consists of mapping touch events to their mouse event analogs. It works perfectly on iOS and Android devices. He shared his code on gitHub in a library called Touch-Punch for jQueryUI. It’s160 lines of code library that can become very useful. First, David starts by detecting if the device supports touch events.

9/14

// Detect touch support $.support.touch = ‘ontouchend’ in document; // Ignore browsers without touch support if (!$.support.touch) { return; } Then he gets a reference to the mouse prototype: var mouseProto = $.ui.mouse.prototype; For every touch event, he will simulate the corresponding mouse event. He rewrites the touchMove handler: mouseProto._touchMove = function (event) { // Ignore event if not handled if (!touchHandled) { return; } // Interaction was not a click this._touchMoved = true; // Simulate the mousemove event simulateMouseEvent(event, ‘mousemove’);

};

The simulateMouseEvent contains the hack and the classic event.preventDefault() call. function simulateMouseEvent (event, simulatedType) { // Ignore multi-touch events if (event.originalEvent.touches.length > 1) { return; } event.preventDefault(); var touch = event.originalEvent.changedTouches[0], simulatedEvent = document.createEvent(‘MouseEvents’); // Initialize the simulated mouse event using the touch event’s coordinates simulatedEvent.initMouseEvent( simulatedType, // type true, // bubbles true, // cancelable window, // view 1, // detail touch.screenX, // screenX touch.screenY, // screenY touch.clientX, // clientX touch.clientY, // clientY

10/14

);

false, false, false, 0, null

// // // // //

altKey shiftKey metaKey button relatedTarget

}

// Dispatch the simulated event to the target element event.target.dispatchEvent(simulatedEvent);

This touch-punch library is on github. Just download it and include it in your web project in addition to jQueryUI and jQuery. <head> <script src=”jquery-1.7.1.min.js”/></script> <script src=”jquery-ui-1.8.18.custom.min.js”/></script> <script src=”jquery.ui.touch-punch.min.js”/></script> </head>

DRAG...
Now you can use the draggable() plugin on your elements and start dragging them on the stage. <html> <head> <title>Drag</title> <link rel=”stylesheet” type=”text/css” href=”css/ui-lightness/jquery-ui-1.8.18.custom.css” rel=”stylesheet”> <link rel=”stylesheet” type=”text/css” href=”style.css”> <script src=”jquery-1.7.1.min.js”/> </script> <script src=”jquery-ui-1.8.18.custom.min.js”></script> <script src=”jquery.ui.touch-punch.min.js”></script> <script> $(function() { $( “#draggable1” ).draggable(); }); </script> </head> <body> <div class=”titleStyle” style=”width:600px”> DRAG ME </div> <div id=”members” style=”width:600px; height:150px”> <div id=”draggable1” class=”ui-widget-content displayBloc”>

11/14

<img src=”mchaize-sf-low.jpg” width=”100”/>Michaël C. </div> </div> <div class=”titleStyle” style=”width:600px;margin-top:50px;”>DROP HERE</div> <div id=”tasks” class=” bigBox”> <div id=”droppable_1” class=”ui-widget-header dropyBloc titleStyle”> <p>Task 1</p> </div> </div> </div> </body> </html>

...AND DROP
Let’s define a “drop zone” for our user. The jQuery UI Droppable plugin makes the elements of your choice droppable, which means that they accept being dropped on by draggables. In this application, the <DIV> element with the id ‘droppable_1’ will be our target. A drop event will be triggered when the draggable will be dropped ‘over’. In the callback, we’ll find the paragraph <p> element and modify the text from “Task 1” to “Task assigned”. <script> $(function() { $( “#draggable1” ).draggable(); $(‘#droppable_1’).droppable({ drop: function( event, ui ) { $( this ) .find( “p” ) .html( “Task assigned”) } }); }); </script> </head> <body> <div class=”titleStyle” style=”width:600px”> DRAG ME </div> <div id=”members” style=”width:600px; height:150px”> <div id=”draggable1” class=”ui-widget-content displayBloc”> <img src=”mchaize-sf-low.jpg” width=”100”/>Michaël C.
12/14

</div> </div> <div class=”titleStyle” style=”width:600px;margin-top:50px;”>DROP HERE</div> <div id=”tasks” class=” bigBox”> <div id=”droppable_1” class=”ui-widget-header dropyBloc titleStyle”> <p>Task 1</p> </div> </div> </div> </body>

SNAP MODE
The method has some very cool built-in options. To guide the user, you can choose to snap a draggable to the edges of a specific element. In this case, I want the user to snap the inner edges of the task box while dragging it. In the draggable plugin options, I specify the selector as a snap target and I set the to (possible values are , and ). I also want to add a visual feedback if a user is not dropped on a task (on a valid droppable element). That’s why I set the option to . $( “#draggable1” ).draggable({ snap: “.ui-widget-header”, snapMode: “inner”,revert:true }); By default, the draggable object will always return to its original position when dropped. I need to disable the behavior when the item is dropped on a correct place. To do so, I just need to extend the drop callback setting the option to . I’m also setting the final coordinates of the draggable element once dropped using the options. $(‘#droppable_1’).droppable({ drop: function( event, ui ) { $( this ) .find( “p” ) .html( “Task assigned”) ui.draggable.draggable(‘option’,’revert’,false); ui.draggable.position({of: $( this ),my: ‘left bottom’, at: ‘left bottom’ }); } });

13/14

DISABLE AND STYLE WITH CSS
Lastly, I need to disable the draggable and the droppable behaviors on my elements. I can also set new styles using the addClass() method to change the visual appearance of my draggable item and of my task box. $(‘#droppable_1’).droppable({ drop: function( event, ui ) { $( this ) .addClass( “ui-state-highlight” ) .droppable(‘disable’) .find( “p” ) .html( “Task assigned”); ui.draggable.draggable(‘disable’); ui.draggable.addClass(‘correct’); ui.draggable.draggable(‘option’,’revert’,false); ui.draggable.position({of: $( this ),my: ‘left bottom’, at: ‘left bottom’ }); } }); /... style.CSS .../ .correct{ opacity:1; background-color:#C2FF84; }

GET THE SOURCE CODE
If my final application, I have four users and four tasks. Using jQuery loops, you can easily reproduce the techniques I’ve used in this tutorial. In a ‘tasks’ DIV element, I have several ‘droppable_n’ elements (droppable_1, droppable_2…), so I can use the generic iterator each() function of jQuery. $(‘#tasks div’).each(function(idx, item) { var idTask = parseInt(idx) + 1; $(‘#’+item.id).droppable({ drop: function( event, ui ) { $( this ) .addClass( “ui-state-highlight” ) .droppable(“option”, “disabled”, true) .find( “p” ) .html( “Task “+idTask+” assigned” ); ui.draggable.draggable(‘disable’); ui.draggable.addClass(‘correct’); ui.draggable.draggable(‘option’,’revert’,false); ui.draggable.position({of: $( this ),my: ‘left bottom’, at: ‘left bottom’ }); } }); });

MORE INFORMATION

>

>

appliness

DON’T WORRY, BE APPLI

In this article, I’m going to discuss object creation in JavaScript using prototypal inheritance as an alternative to the new operator.

JavaScript object creation: Learning to live without “new”

embrace the javascript language
One significant aspect of JavaScript is that there is rarely a single right way to do any particular task. JavaScript is a loosely-typed, dynamic, and expressive language, which means that there are usually many different ways to accomplish the same task. I’m not saying that the methods described here to create objects are the only correct ways to do so or even the best ways, but I do feel that they are closer to the true nature of the language and will help you to understand what’s going on under the covers if you choose to use other methods. To help you better understand these concepts, this article describes the creation of a basic particle system with multiple rendering targets. This is a complex enough task to represent a real world test of the concepts I’ll be demonstrating, rather than a simple hello world type of application.

P

d n u o laygr

(

t - JavaScrip e p y t o t o r P - Canvas

Difficulty
- rookie - intermediate - expert

Todo list
forget class code reuse particles
by Keith Peters
15/27

Object creation basics
The crux of this article is the creation of JavaScript objects. Most tutorials you see will tell you to create a constructor function, add methods to the function’s prototype property, and then use the new operator like so: function Foo() { this.name = “foo”; } Foo.prototype.sayHello = function() { alert(“hello from “ + this.name); }; var myFoo = new Foo(); myFoo.sayHello(); The newly created object now has all the properties that were defined on the constructor function’s prototype. This creates something that looks much like a class in a class-based language. To make a new “subclass” that inherits from that “class”, you’d set the prototype property of the “subclass” to a new instance of the original “class”. (I’m using quotation marks here because the entities are not actual classes or subclasses.) function Bar() { } Bar.prototype = new Foo(); Bar.prototype.sayGoodbye = function() { alert(“goodbye from “ + this.name); } var myBar = new Bar(); myBar.sayHello(); myBar.sayGoodbye(); The problem is that because this structure looks so similar to real classes in other languages, people start expecting it to behave exactly like real classes behave in other languages. But the more you work with these types of “classes”, the more you see that they don’t behave that way at all. So people get upset with JavaScript, and start thinking it is a bad language that can’t be used for anything serious. Others go about trying to fix these class-like structures, tacking on various bits of functionality and building up very complex frameworks to get constructor functions and prototypes to look and behave more and more like classes. Personally, I see this as a bit of a misguided effort. It’s not necessarily wrong, but the energy being spent would likely produce better results if it was in another direction.

Embracing prototypal inheritance
JavaScript is not a class-based language, but a prototype-based one. Code reuse is done not by making class templates that are used to instantiate objects, but by creating new objects directly, and then making other new objects based on existing ones. The existing object is assigned as the prototype of the new object and then new behavior can be added to the new object. It’s quite an elegant system and it’s beautifully implemented in the Io language, which I encourage you to look into.
16/27

Before going any further, I want to clarify the term prototype. First, there is the prototype property of a constructor function as shown in the last section’s example. There is another hidden property that is the actual prototype of an object. This can be very confusing. The ECMAScript proposal refers to this hidden property as [[Prototype]]. This is exposed in some JavaScript environments as the __proto__ property, but this is not a standard part of the language and should not be counted on. When you create a new object using new with a constructor function, that new object’s [[Prototype]] is set with a reference to the constructor function’s prototype. In addition to this naming confusion, there were two design decisions made in the language that have added to the confusion ever since. First, due to the concern that some developers might not be comfortable with prototypal inheritance, constructor functions and the new operator were introduced. Second, there was no direct native way to create a new object with another object as its [[Prototype]], except through the new operator with a constructor function. Fortunately, most browsers now support the Object.create method. This method takes an existing object as a parameter. It returns a new object that has the existing object assigned as its [[Prototype]]. Even more fortunately, this method is quite easy to create for those environments that do not support it: if(typeof Object.create !== “function”) { Object.create = function (o) { function F() {} F.prototype = o; return new F(); }; } So, how would you rewrite the earlier example using Object.create? First you create a foo object that has a name property and a sayHello function: var foo = { name: “foo”, sayHello: function() { alert(“hello from “ + this.name); } }; foo.sayHello(); Then, you use Object.create to make a bar object that has foo as its prototype, and add a sayGoodbye function to it: var bar = Object.create(foo); bar.sayGoodbye = function() { alert(“goodbye from “ + this.name); } bar.sayHello(); bar.sayGoodbye(); It’s also very common to create an extend function that simplifies the adding of methods and properties to the new object. The following method simply copies over any properties from props onto obj: function extend(obj, props) { for(prop in props) { if(props.hasOwnProperty(prop)) { obj[prop] = props[prop]; }}}

17/27

This enables you to create bar like so: var bar = Object.create(foo); extend(bar, { sayGoodbye: function() { alert(“goodbye from “ + this.name); } }); Not such a big deal here, but it simplifies things greatly when you are adding several more properties or methods. OK, now that you have the basics down, you can start putting them together in a real world scenario.

Creating particles using Object.create
The particles used in the example project are going to be very basic: black dots that move around in a two-dimensional space and bounce off the walls. They also support gravity and friction as needed. You’ll define a particle object that has all the properties and methods it needs, and place it in an adc object to avoid polluting the global namespace. Here is the running example:

18/27

var adc = adc || {}; adc.particle = { x: 0, y: 0, vx: 0, vy: 0, gravity: 0.0, bounce: -0.9, friction: 1.0, bounds: null, color: “#000000”, context: null, update: function() { this.vy += this.gravity; this.x += this.vx; this.y += this.vy; this.vx *= this.friction; this.vy *= this.friction; if(this.x < this.bounds.x1) { this.x = this.bounds.x1; this.vx *= this.bounce; } else if(this.x > this.bounds.x2) { this.x = this.bounds.x2; this.vx *= this.bounce; } if(this.y < this.bounds.y1) { this.y = this.bounds.y1; this.vy *= this.bounce; } else if(this.y > this.bounds.y2) { this.y = this.bounds.y2; this.vy *= this.bounce; }

},

} };

render: function() { if(this.context === null) { throw new Error(“context needs to be set on particle”); } this.context.fillStyle = this.color; this.context.fillRect(this.x - 1.5, this.y - 1.5, 3, 3);

Next, you’ll need a particle system to keep track of all the particles and handle updating and rendering them.

19/27

var adc = adc || {}; adc.particleSystem = { particles: [], addParticle: function(particle) { this.particles.push(particle); }, update: function() { var i, numParticles = this.particles.length; for(i = 0; i < numParticles; i += 1) { this.particles[i].update(); }

},

};

render: function() { var i, numParticles = this.particles.length; for(i = 0; i < numParticles; i += 1) { this.particles[i].render(); } }

And finally, you’ll need a main file that creates the system, creates and adds all the particles, and sets up the animation loop. (function() { if (typeof Object.create !== “function”) { Object.create = function (o) { function F() {} F.prototype = o; return new F(); }; } var system, numParticles, canvas, context, bounds; function initSystem() { system = Object.create(adc.particleSystem); numParticles = 200; canvas = document.getElementById(“canvas”); context = canvas.getContext(“2d”); canvas.width = window.innerWidth; canvas.height = window.innerHeight; bounds = { x1: 0, y1: 0,

20/27

}

};

x2: canvas.width, y2: canvas.height

function initParticles() { var i, particle; for(i = 0; i < numParticles; i += 1) { particle = Object.create(adc.particle); particle.bounds = bounds; particle.context = context; particle.x = Math.random() * bounds.x2; particle.y = Math.random() * bounds.y2; particle.vx = Math.random() * 10 - 5; particle.vy = Math.random() * 10 - 5; system.addParticle(particle); } } function animate() { context.clearRect(bounds.x1, bounds.y1, bounds.x2, bounds.y2); system.update(); system.render(); } initSystem(); initParticles(); setInterval(animate, 1000 / 60); }()); The code in this file is contained in an immediately invoked function expression, again to avoid global namespace pollution. It includes the Object.create shim for browsers that might need it. This is all pulled together in the following HTML file: <!DOCTYPE html> <html> <head> <title>Particles v1</title> <style type=”text/css”> .html, body { margin: 0; padding: 0; } </style> </head> <body> <div> <canvas id=”canvas”/> </div> <script type=”text/javascript” src=”v1/particle.js”></script> <script type=”text/javascript” src=”v1/particleSystem.js”></script> <script type=”text/javascript” src=”v1/main.js”></script> </body></html>

21/27

The important lines, for the purposes of this article, are those that create the particle system: system = Object.create(adc.particleSystem); and that create the particles themselves: particle = Object.create(adc.particle); particle.bounds = bounds; particle.context = context; particle.x = Math.random() * bounds.x2; particle.y = Math.random() * bounds.y2; particle.vx = Math.random() * 10 - 5; particle.vy = Math.random() * 10 - 5; You haven’t implemented any kind of extend function yet, but you can see here where it would be useful – calling extend a single time, rather than line after line of assigning properties. In the next iteration, you’ll add that and then some.

Adding extend and init
For the second version of the particle system, rather than having the main file create and extend each and every particle by itself, it would be better to have the particles know how to create, extend, and initialize themselves. To support that, you can use two new functions, extend and init , which are added to adc.particle : var adc = adc || {}; adc.particle = { x: 0, y: 0, vx: 0, vy: 0, gravity: 0.0, bounce: -0.9, friction: 1.0, bounds: null, color: “#000000”, context: null, extend: function(props) { var prop, obj; obj = Object.create(this); for(prop in props) { if(props.hasOwnProperty(prop)) { obj[prop] = props[prop]; } } return obj; }, init: function() { this.x = Math.random() * this.bounds.x2; this.y = Math.random() * this.bounds.y2; this.vx = Math.random() * 10 - 5;

22/27

};

}, // … // rest of methods are the same as version 1

this.vy = Math.random() * 10 - 5;

The extend method takes care of creating a new object, passing this as a parameter to Object.create. Thus, it makes a copy of itself. It then takes any properties that were passed into extend, copies them onto the new object it created, and finally returns the new object. Now, rather than calling Object.create(adc.particle) and setting and tweaking property after property, you can call adc.particle.extend, passing in an object with the properties you want to set, and then call init on the newly created particle. When you add the extend method to the particle system, the main file becomes a bit simpler. In initSystem, you call adc.particleSystem.extend() to create the new system. You don’t need to add any properties to the system, so extend is called with no parameters. Not much of a change there: function initSystem() { system = adc.particleSystem.extend(); numParticles = 200; canvas = document.getElementById(“canvas”); context = canvas.getContext(“2d”); canvas.width = window.innerWidth; canvas.height = window.innerHeight; bounds = { x1: 0, y1: 0, x2: canvas.width, y2: canvas.height }; } In the initParticles method, though, you see an improvement: function initParticles() { var i, particle; for(i = 0; i < numParticles; i += 1) { particle = adc.particle.extend({ bounds: bounds, context: context }); particle.init(); system.addParticle(particle); } } Now you can call adc.particle.extend to create each particle, passing in an object that contains the bounds and context, which are then copied to each particle. Finally, you just call init on the new particle, which takes care of randomly setting up its position and velocity. This version works exactly the same as the last, but the creation of individual particles has been greatly simplified.
23/27

Adding inheritance
The third version of the particle system supports inheritance. This is key to code reuse. You have one type of object and you want to make another type of object that is slightly different. You don’t want to completely recreate the first object with just a couple of changes. Code reuse has two important benefits. First, there is less code to write. You certainly don’t want to write the same code twice. You also don’t want to copy and paste code, as this can lead to things getting out of sync, with a function implemented one way over here and the same function implemented a bit differently over there. The second benefit is better performance. When you have the same code duplicated in your live application, it takes longer to download, eats up more memory, and can cause your code to be slower, particularly in object instantiation (because it is instantiating the same code again and again). The particle system currently renders to an HTML5 canvas. Now, you may want to make a different particle type that renders itself as a DOM object. Ideally, almost all of the particle code would be reused, with only the render method differing. So, with great confidence, you can just take particle.js and remove the render method from it. Next, make two new files, canvasParticle.js and comParticle.js. The canvas version will be similar to what you’ve just done: var adc = adc || {}; adc.canvasParticle = adc.particle.extend({ render: function() { if(this.context === null) { throw new Error(“context needs to be set on particle”); } this.context.fillStyle = this.color; this.context.fillRect(this.x - 1.5, this.y - 1.5, 3, 3); } }); This code is quite simple. You just call adc.particle.extend, passing in an object that contains your old render method. This will create a new object that has particle as its [[Prototype]], and render as a new method directly on the object. Next you’ll have to change main.js a bit to allow for your new object types. Create a mainCanvas.js file for setting up the canvas-based particles. It will only differ in one line, where it uses the adc.canvasParticle type to instantiate particles, rather than just adc.particle: function initParticles() { var i, particle; for(i = 0; i < numParticles; i += 1) { particle = adc.canvasParticle.extend({ bounds: bounds, context: context }); particle.init(); system.addParticle(particle); } }
24/27

The particleSystem.js file can remain unchanged, but of course the HTML file will have to reflect new source files you’ve created. This example should function identically to the first two versions. Now you’re ready to create the DOM version. The domParticle.js file will be almost as simple as canvasParticle.js. It assumes that there is an element it can position, and positions it using style properties: adc.domParticle = adc.particle.extend({ render: function() { if(this.element === null) { throw new Error(“element needs to be set on particle”); } this.element.style.left = this.x; this.element.style.top = this.y; } });

But in this example, the HTML file and main.js file will need to change significantly. In addition to referencing different source files, the HTML file can eliminate the canvas element and add a container div in which to put all the particle elements: <html> <head> <title>Particles v3</title> <style type=”text/css”> .html, body { margin: 0; padding: 0; overflow: hidden; } </style> </head> <body> <div id=”container”> </div> <script <script <script <script </body> </html> type=”text/javascript” type=”text/javascript” type=”text/javascript” type=”text/javascript” src=”v3/particle.js”></script> src=”v3/domParticle.js”></script> src=”v3/particleSystem.js”></script> src=”v3/mainDom.js”></script>

The main.js file will become mainDom.js and will obviously need to change a bit to create domParticles and give them individual elements instead of references to the canvas’s context.

25/27

(function() { var system, numParticles, container, bounds; function createElement() { var el = document.createElement(“div”); el.style.position = “absolute”; el.style.width = 3; el.style.height = 3; el.style.backgroundColor = “#000000”; container.appendChild(el); return el; } function initSystem() { system = adc.particleSystem.extend(); numParticles = 200; container = document.getElementById(“container”); bounds = { x1: 0, y1: 0, x2: window.innerWidth, y2: window.innerHeight }; } function initParticles() { var i, particle; for(i = 0; i < numParticles; i += 1) { particle = adc.domParticle.extend({ bounds: bounds, element: createElement() }); particle.init(); system.addParticle(particle);

}

}

function animate() { system.update(); system.render(); } initSystem(); initParticles(); setInterval(animate, 1000 / 60); }());
26/27

This makes use of a new function, createElement, that simply creates a div, styles it, and adds it to the container div. This is what the particle will position when its render method is called. This final example should be nearly identical to all the other versions. Of course, there are lots of optimization and enhancements that you can do to improve all of these examples. I purposely kept it simple to better illustrate the inheritance aspect.

Where to go from here
You may still prefer constructor functions and the new operator. I’m not going to twist your arm about it. I personally find this method of object creation to be very clean and in accord with the basic prototypal nature of JavaScript. I encourage you to explore the source code provided in the sample files for this tutorial and try out the particle system in a browser that supports HTML5. As your needs for more complex apps grow, you can add features onto this basic setup far more cleanly than you can with an pseudo-class based system. For more information, see the following resources: - Douglas Crockford’s Prototypal Inheritance in JavaScript - Douglas Crockford’s Classical Inheritance in JavaScript - WOODY2SHOES’s 005 JSJ Javascript Objects

ABOUT THIS ARTICLE
Keith Peters is a JavaScript and Flash / ActionScript developer in the Boston area. He writes books, speak at conferences, blogs and is an avid jogging & fitness expert. Keith is well-known for several books including Foundation HTML5 Animation with JavaScript http://www.bit-101.com @bit101

ONLINE RESOURCES Prototypal Inheritance in JavaScript http://javascript.crockford.com/prototypal.html Classical Inheritance in JavaScript http://javascript.crockford.com/inheritance.html JavaScript Objects http://javascriptjabber.com/005-jsj-javascript-objects/

appliness

DON’T WORRY, BE APPLI

I’ve been blogging a lot about Backbone.js recently. Backbone.js is a lightweight architectural framework that brings structure to your Web applications. Backbone is not, however, a user interface framework that helps you with the way your application looks.

Crafting Native LOOking IOS APPS WITH HTML, BACKBONE.JS AND PHONEGAP

So, where do you turn to for help when you need to make your application look good?

BACKGROUND
For traditional web apps (delivered through a browser), Twitter Bootstrap can help (read here). But what about Mobile apps? I explored Backbone.js + jQuery Mobile here. Depending on what you are looking for, it may or may not be the right solution: jQM provides mobile skins, but they don’t look native. It’s also more of a full stack framework than a lightweight UI toolkit that you can easily layer on top of your app. The alternative to using an existing UI toolkit is to roll your own styles to make your application look and behave like a native app. Sounds easy enough, but when you consider all the details and want to achieve “pixel perfection”, it becomes a daunting task.

P

d n u o laygr

(

p - Bootstra ile b o M y r e u - jQ p a G e n o h P -

Difficulty
- rookie - intermediate - expert

Todo list
- look native - perform - fire Jim
by Christophe Coenraets
28/29

As I was getting ready to tackle the challenge, and build a new native looking version of my Employee Directory app, I came across this great blog post by Chee Aun where he documents the process he went through to build his own Hacker News mobile app. His post is a real gem, and I ended up reusing a lot of the Hacker News app styles. Compared to the Hacker News app, the Employee Directory page flow is more random. Here are a few examples: 1. *-SearchPage -> EmployeePage -> ReportsPage -> EmployeePage -> … 2. SearchPage -> EmployeePage -> EmployeePage (manager) -> Reports -> … 3. SearchPage -> EmployeePage -> EmployeePage (manager) -> EmployeePage (manager’s manager) -> …

As you can see, the page flow includes “same page transitions”, when the user navigates from one employee to his/her manager. To accommodate the Employee Directory page flow requirements, my Backbone.js infrastructure creates and destroys pages as needed with the appropriate slide-in/slide-out transitions. The implementation of these transitions was inspired by Wesley Hales’ article.

PhoneGap
Even though you can run this application in a browser (here), I built it with the intention of packaging it as a native app with PhoneGap so that you could start it like any other app from your iPhone home screen. If you are not familiar with PhoneGap, I’ll provide more details on packaging this app as a native app in my next post.

Source Code
I updated the backbone-directory GitHub repository to include this version: It is available in the iphone directory.

ABOUT THIS ARTICLE
Christophe Coenraets is a Technical Evangelist for Adobe where he focuses on Mobile and Rich Internet Applications for the Enterprise. In his previous role at Macromedia, Christophe worked on JRun, the company’s J2EE application server. http://coenraets.org/ @ccoenraets

ONLINE RESOURCES
JQuery Mobile official website http://jquerymobile.com/ Backbone.js official website http://documentcloud.github.com/backbone/ Backbone-JQuery mobile https://github.com/ccoenraets/backbone-jquerymobile

appliness

DON’T WORRY, BE APPLI

using backbone.js with jquery mobile
bakcbone.js is an architectural framework that helps you write well-structured web applications. it is not, however, a user interface framework and it therefore doesn’t help you with the way your application looks.

Backbone’s confined scope is a good thing: it’s lightweight, non-intrusive, not coupled to things you don’t need, and it lets you use the UI toolkit of your choice or simply roll your own styles and widgets. In my previous post, I demonstrated how to use Twitter Bootstrap on top of Backbone.

QUEST FOR A MOBILE UI TOOLKIT
After that post, I wanted to create a mobile version of the same application; a version that I could package with PhoneGap and that would look and behave like a native app. Twitter Bootstrap can probably be tweaked for that purpose as well, but I was looking for a UI toolkit dedicated to providing native looking controls and behaviors on mobile devices.

P

d n u o laygr

(

- Backbone e l i b o M Q j M O D L M - HT

Difficulty
- rookie - intermediate - expert

Todo list
- catch event - use bootstrap - structure code
by Christophe Coenraets
30/33

ANOTHER WAY TO USE JQUERY MOBILE
jQuery Mobile (jQM) is one option that I’ve explored before (here and here), but it fits more in the category of full-stack frameworks that tie together architectural structure and UI controls and behaviors. John Bender, my colleague at Adobe and member of the jQuery Mobile team, recently pointed out to me that you can disable the routing and navigation capabilities of jQM, and essentially use it as a pure UI framework on top of other architectural frameworks like Backbone.js.

SAMPLE APPLICATION
I ended up spending a decent amount of time trying different things to get the two frameworks to play well together without stepping on each other. To save you some headaches if you are trying to do the same, I put together a simple application with the basic setup to combine Backbone (for the application structure and “routing”) and jQuery Mobile (for its styles and widgets). NOTE: Another approach would be to use jQM’s “routing” instead of Backbone’s. Ben Nolan has an example of this approach here. I prefer to use Backbone’s routing because I find it more flexible and less “page-centric”. Here is the app:

Click here to run the application in a separate window. The source code is available in this GitHub repository.
31/33

HOW IT WORKS
The key to this approach is to disable jQuery Mobile’s “routing”: In other words, you need to tell jQuery Mobile not to handle links, hash tag changes, and so on. I isolated that code in jqm-config.js: $(document).bind(“mobileinit”, function () { $.mobile.ajaxEnabled = false; $.mobile.linkBindingEnabled = false; $.mobile.hashListeningEnabled = false; $.mobile.pushStateEnabled = false; }); If jQuery Mobile is not in charge of page navigation, you also have to manually remove the pages from the DOM when they are not used anymore. Here is one way to do it: $($(‘div[data-role=”page”]’).live(‘pagehide’, function (event, ui) { $(event.currentTarget).remove(); }); With this configuration in place, you use Backbone’s routing as usual: $.mobile.hashListeningEnabled = false; var AppRouter = Backbone.Router.extend({ $.mobile.pushStateEnabled = false; routes:{ “”:”home”, “page1”:”page1”, “page2”:”page2” }, home:function () { this.changePage(new HomeView()); }, page1:function () { this.changePage(new Page1View()); }, page2:function () { this.changePage(new Page2View()); }, changePage:function (page) { $(page.el).attr(‘data-role’, ‘page’); page.render(); $(‘body’).append($(page.el)); $.mobile.changePage($(page.el), {changeHash:false}); } });
32/33

IS THIS THE RIGHT STACK?
I like the idea of a lightweight architectural framework combined with a UI toolkit. Backbone + Twitter Bootstrap felt right because the two frameworks have different areas of concern and complement each other very well. I was happy to see you could decouple jQM from its navigation infrastructure. However, that’s probably not the main “design center” at this point. I think it would be interesting for jQM to focus on that utilization scenario as well. At the end of the day, frameworks are often a matter of personal preferences, and not all applications are equal. So try it, see if it works for you, and share your experience. What UI toolkit are you using?

SOURCE CODE
The source code is available in this repository on GitHub.

A MORE REAL-LIFE APPLICATION
In my next post, I’ll share a Backbone.js + jQuery Mobile version of the Employee Directory application first explored with Backbone.js + Twitter Bootstrap.

Backbone & Twitter

JQuery & PhoneGap

JQuery Getting Started

John Bender

Ben Nolan

Sample App

MORE INFORMATION

>

ABOUT THIS ARTICLE
Christophe Coenraets is a Technical Evangelist for Adobe where he focuses on Mobile and Rich Internet Applications for the Enterprise. In his previous role at Macromedia, Christophe worked on JRun, the company’s J2EE application server. http://coenraets.org/ @ccoenraets

ONLINE RESOURCES
JQuery Mobile official website http://jquerymobile.com/ Backbone.js official website http://documentcloud.github.com/backbone/ Backbone-JQuery mobile https://github.com/ccoenraets/backbone-jquerymobile

>

appliness

DON’T WORRY, BE APPLI

I had heard about Handlebars from various people. It’s also the templating engine that Ember.js uses. Handlebars works by allowing you to define templates using simple script blocks

Demo of Handlebars, and why you should consider a templating engine

a JavaScript templating engine
For a while now I’ve been thinking I need to pick up, and start using, a JavaScript templating engine. I had used a jQuery-based one a few years back, but that project was abandoned and I’ve yet to really look what - if any - solution would work good for me. Another reason I’ve not found the time is that a majority of my JavaScript examples are small little demos built for blog posts. When I blog, I try my best to keep my code as simple as possible. I don’t go all MVC just to demonstrate date formatting. It may not be real world, but it also keeps you focused on the topic I’m trying to discuss. Today I made the time - and more specifically - made a demo. The demo is stupid. It’s not even important. What is important is this: If you’ve ever used JavaScript to build strings of HTML, you never realized just how much of a pain that is until you don’t have to. You never realized how resistant you are to adding new features - or tweaking the design. You never realized how much you held back - just because of how much of a pain in the rear it was!

P

d n u o laygr

(

s - Handlebar s e t a l p m e T - Ember

Difficulty
- rookie - intermediate - expert

Todo list
- shave - MVC - use gravatar
by Raymond Camden
34/40

I’m probably being overly dramatic, but to me, it feels a lot like ORM. Yeah, it’s simple to go into a database client, open a table, and add a new field. But when you can do all of that via code... it feels incredibly freeing. You feel yourself trying new and interesting things. In fact, the demo I’m going to show has about twice the features I was planning just because it was so damn easy to add. That’s how I feel today - and any day where my computer makes me smile is a good day. Ok, enough rambling. I had heard about Handlebars from various people. It’s also the templating engine that Ember.js uses. Handlebars works by allowing you to define templates using simple script blocks, so for example, you can write your template in your document like so: <script id=”result-template” type=”text/x-handlebars-template”> <div class=”entry”> <h1>{{title}}</h1> <div class=”body”> {{body}} </div> </div> </script> You then use the Handlerbars API to create a template out of the block, apply data to it, and then render it to screen. It’s all relatively simple, but the docs don’t necessarily do a great job I think of demonstrating simple examples in “full” pages so you can see things in context. Here is a trivial example: <html> <head> <title>Test 1</title> <script src=”js/handlebars-1.0.0.beta.6.js”></script> <script id=”result-template” type=”text/x-handlebars-template”> <h2>Your Bio</h2> <p> Your name is {{firstname}} {{lastname}} and you are {{age}} years old. </p> </script> <link rel=”stylesheet” href=”style.css” type=”text/css” /> </head> <body> <h2>Render Simple Bio</h2> <input type=”text” id=”firstname” placeholder=”First Name”><br/> <input type=”text” id=”lastname” placeholder=”Last Name”><br/> <input type=”number” id=”age” placeholder=”Age”><br/> <button id=”demoButton”>Demo</button>

<div id=”resultDiv”></div> <script> document.addEventListener(“DOMContentLoaded”, function() { //Get the contents from the script block var source = document.querySelector(“#result-template”).innerHTML;

35/40

//Compile that baby into a template template = Handlebars.compile(source); document.querySelector(“#demoButton”).addEventListener(“click”, function() { var fname = document.querySelector(“#firstname”).value; var lname = document.querySelector(“#lastname”).value; var age = document.querySelector(“#age”).value; var html = template({firstname:fname, lastname:lname,age:age}); document.querySelector(“#resultDiv”).innerHTML = html; }); }); </script> </body> </html> Notice how I’ve got a simple template block on top. If you’ve never seen Handlebars before, or any JavaScript templating engine, you can probably guess which portions of the block represent dynamic portions and which represent static text. I’ve got a simple form with a button bound to a simple click listener. Looking at the JavaScript, you can see that first I have to grab the HTML from the template block. I then compile this. This gives me a template that I can reuse to generate output. My form has a simple click handler. When you hit the button, I pass the values to my template and grab the HTML out of it. You can play with this demo here:

36/40

dynamic templates
Of course, not every template will be a simple set of keys and values. Your template may also need to be dynamic based on the values passed in. Let’s look at another example that makes use of both lists and conditionals. <html> <head> <title>Test 2</title> <script src=”js/handlebars-1.0.0.beta.6.js”></script> <script id=”result-template” type=”text/x-handlebars-template”> <h2>Your Favorite Things</h2> {{#if things}} <ul> {{#each things}} <li>{{this}}</li> {{/each}} </ul> {{else}} <p> Apparently, you like nothing. Poor you. </p> {{/if}} </script> <link rel=”stylesheet” href=”style.css” type=”text/css” /> </head> <body> <h2>List of Things</h2> <p> Enter a comma-separated list of things you like. </p> <input type=”text” id=”things” placeholder=”Things you like...”><br/> <button id=”demoButton”>Demo</button> <div id=”resultDiv”></div> <script> document.addEventListener(“DOMContentLoaded”, function() { //Get the contents from the script block var source = document.querySelector(“#result-template”).innerHTML; //Compile that baby into a template template = Handlebars.compile(source); document.querySelector(“#demoButton”).addEventListener(“click”, function() { var things = document.querySelector(“#things”).value;

37/40

if(things.length) var arrThings = things.split(“,”); var html = template({things:arrThings}); document.querySelector(“#resultDiv”).innerHTML = html; }); }); </script> </body> </html> In our template, we’ve got two things going on here. First is a conditional that checks if “things” is a truthy value (truthy being one of the things that make JavaScript so fun). Within the true part of the conditional we use an each block to enumerate over a set of values. If you scroll down to the HTML/JavaScript, you can see I’m just asking for you to enter a list of things you like. That value is split into an array and passed (if there were values) to the template. Demo is below:

38/40

custom functions
Let’s look at one more example. One of the cooler aspects of Handlebars is that you can add custom functions to the engine. For example, you could write a cowbell function that wraps your results in the beautiful rocking sounds of the cowbell. Ok, maybe not that. But what about something a bit complex - like converting an email address into a MD5 hash that could be used for Gravatar? Yeah - no way that would work... <html> <head> <title>Test 3</title> <script src=”js/handlebars-1.0.0.beta.6.js”></script> <script src=”js/webtoolkit.md5.js”></script> <script id=”result-template” type=”text/x-handlebars-template”> <h2>You and Your Gravatar</h2> <p> Your email is {{email}} and your gravatar is:<br/> <img src=”{{gravatarurl email }}”> </p> </script> <link rel=”stylesheet” href=”style.css” type=”text/css” /> </head> <body> <h2>Enter Email Address for Awesomeness</h2> <input type=”email” id=”email” placeholder=”Email goes here...”> <button id=”demoButton”>Demo</button> <div id=”resultDiv”></div> <script> document.addEventListener(“DOMContentLoaded”, function() { //Tip on using Gravar with JS: http://www.deluxeblogtips.com/2010/04/getgravatar-using-only-javascript.html Handlebars.registerHelper(‘gravatarurl’, function(email) { return ‘http://www.gravatar.com/avatar/’ + MD5(email) + ‘.jpg?s=250’; }); //Get the contents from the script block var source = document.querySelector(“#result-template”).innerHTML; //Compile that baby into a template template = Handlebars.compile(source); document.querySelector(“#demoButton”).addEventListener(“click”, function() { var email = document.querySelector(“#email”).value; if(!email.length) return;
39/40

var html = template({email:email});

document.querySelector(“#resultDiv”).innerHTML = html; }); }); </script> </body> </html> Notice in the template we have one simple value, email, and then this: gravatar email. This isn’t something built into Handlebars, but rather, injected via the registerHelper function you see in the main script block of the page. The demo is below:

ABOUT THIS ARTICLE
Meet Raymond Camden. He is a 38 year old married father of three living in beautiful Lafayette, Louisiana. Ray is a developer evangelist for Adobe where his primary technical focus is ColdFusion, jQuery, Flex, AIR and the mobile space. http://raymondcamden.com/ @cfjedimaster

ONLINE RESOURCES Full tutorial with code http://www.raymondcamden.com/index.cfm/2012/4/19/Demo-ofHandlebars-and-why-you-should-consider-a-templating-engine Handlebars http://handlebarsjs.com/ Ember http://emberjs.com/

appliness

DON’T WORRY, BE APPLI

Real-time data exchange in html5 with websockets

the websocket api is one of the more powerful new features in the html5 specification because it opens the door to real-time communication and pushing messages. This article describes a basic chat program that shows the basics of websockets and how to implement them on the client side.

USING WEBSOCKETS
The WebSocket API has been somewhat volatile over the past year as the W3C specification has been solidified. It has finally been completed and the specification can now be implemented consistently across browsers. Why use WebSockets? Instead of using the HTTP protocol, WebSockets use their own protocol. There is a significant amount of overhead incurred whenever communication over HTTP happens. Because of the request/response mechanism and all of the information that HTTP stores in header information, exchanging even basic information can result in lots of data being sent back and forth. WebSockets, by contrast, are full duplex, which means they can communicate back and forth at the same time without the request/response overhead. The header information is also much smaller, so the bulk of the data being exchanged is the actual data from the application.

P

d n u o laygr

(

- real-time s e g a s s e m - sockets

Difficulty
- rookie - intermediate - expert

Todo list
- hike - build a chat - read the spec
by Ryan Stewart
41/47

Browser Support for WebSockets Most of the major browsers now support some version of WebSockets. Firefox, Chrome, and the latest version of Internet Explorer all have added support for the WebSocket API. Safari and Opera offer partial support for the API. One of the major issues is understanding which draft of the WebSocket spec is supported by the browsers. Wikipedia has a good entry that lists the specifications by version number and which browser versions support them; for details, visit http://en.wikipedia.org/wiki/WebSocket#Browser_support. Going forward, the final version of the specification, RFC 6455, is the one that will be implemented. Setting Up a Server When working with WebSockets, you need to have a server that supports them. Complete instructions for configuring a server that adheres to the WebSockets specification are beyond the scope of this article, but it’s an important enough topic to address at least briefly. There are a few different ways to potentially implement WebSockets. PHP ships with built-in support for WebSockets, so you could write your own PHP socket server that handles the requests and responses from the client code. There are also Java and Ruby projects that provide WebSocket support for those languages. One of the more interesting ways to get up and running is a project called Socket.io that runs on Node. js. It has server-side and client-side libraries that make using WebSockets very easy. Node.js lets you use JavaScript on the server so the client- and server-side languages can be the same. For basic socket testing, websocket.org hosts a test server at http://websocket.org/echo.html that will simply send the transmitted data as a response back to the client. The server I use comes from Kevin Hoyt who wrote a socket server using Adobe AIR. For details, see the AIRWebSocket project on Github.

Connecting to a WebSocket Server
The core of the WebSocket API is the WebSocket class, which provides the methods and events that handle all of the communication with the server. It is important to have your code first check that the browser supports WebSockets. The quickest way to do this is to see if window.WebSocket exists. A more powerful solution is to use the Modernizr library, which helps detect support for WebSockets while providing a graceful fallback for older browsers. The example chat application provides a Connect button that the user can use to initiate the connection to the socket server. This process is implemented in a connect() function: var connection = {}; function connect() { if(window.WebSocket != undefined) { if(connection.readyState === undefined || connection.readyState > 1) { connection = new WebSocket(‘ws://localhost:1740’); } } }
42/47

The first line of code above defines the connection object that will be used by the rest of the application. When you make it a global variable, the connection object can be used in other functions. After checking to make sure that the browser supports WebSockets, the code checks to make sure there isn’t already a connection active. The WebSocket object provides a readyState property that indicates the connection’s ready status. The values are as follows: const const const const unsigned unsigned unsigned unsigned short short short short CONNECTING = 0; OPEN = 1; CLOSING = 2; CLOSED = 3;

As long as the readyState is greater than 1, the connection isn’t open so the application can connect to the socket server. Connecting to the server is just a matter of instantiating the WebSocket class and passing in the URL and port number of the socket server. The browser then makes a connection with the server. Handling the WebSocket object in Firefox The WebKit browsers and Opera handle WebSockets in the same way, but in Firefox the WebSocket object has a prefix; it is referred to as MozWebSocket. Beyond that, the APIs are the same, so an easy way to keep everything simple is to check for the existence of window.MozWebSocket and then set it to the regular WebSocket object. if (window.MozWebSocket) { window.WebSocket = window.MozWebSocket; } The open event If the connection is successful, the browser will fire an open event. To make sure this gets caught, the WebSocket API includes an onopen property, which is assigned to a function that will run code for every open event. The code below sets the onopen property to a corresponding onopen() function that sets a couple of variables so that the UI is updated to indicate that the user is logged in. window.WebSocket Here is the onopen() function: function onopen (event) { document.getElementById(‘connected’).innerHTML = “Connected”; document.getElementById(‘chat’).innerHTML = “You have joined the chat<br />”; } Note that most people don’t actually assign those methods to named functions but rather include them in anonymous functions right where they are first defined. I have implemented it this way because I like having the separation, but it may seem a bit redundant to you as you dig into more WebSocket examples.
43/47

Managing Data
Now that your client is connected you can start dealing with actual chat messages. The server I have set up for the moment just cycles through all of the currently connected users whenever it gets a message and then sends that message out to all of those users. Though it is a pretty basic chat server, it illustrates many key WebSocket concepts. Sending messages With WebSockets you can send text, or UTF-8 data, as well as binary data such as pictures or videos. They both use the same API on the client side, but it will largely depend on the server to actually handle the data types correctly. To send a message to the socket server the chat application simply invokes the send() method of the connection object. It takes a single parameter, the message being sent, which it passes to the socket server. When the user clicks on the Send Message button in the chat application, the sendmessage() method sends the message typed by the user along with the username. The socket server will then loop through all the clients, including the sender, and deliver the message to them. function sendmessage() { var messagetext = document.getElementById(‘chatmessage’).value; messagetext = username + “: “ + messagetext; connection.send(messagetext); }

Receiving messages To handle incoming messages, the WebSocket API uses the onmessage property of the connection event. Just like the onopen property covered earlier, this property takes a function that will be called whenever a new message arrives. So the first step is to set up the event handler in the original connect() method right before the onopen definition: connection.onmessage = onmessage; Once that is set up, define the onmessage() function: function onmessage (event) { var chatdiv = document.getElementById(‘chat’); chatdiv.innerHTML = chatdiv.innerHTML + event.data + “<br />”; } The event that is received by onmessage is of type MessageEvent . It includes a data property that has the value of the message being received. In this case, that is used to display the chat text. This data property includes the username of the chat participant along with the message they sent. This value is appended to the chat div window.
44/47

Handling errors Error handling is an important topic to cover, even if only quickly. Along with onopen and onmessage, the WebSocket API also includes an onerror property, which takes a function that runs any time an error occurs. The error event includes a data property that provides some information about the error. Here is the basic error handler used in the chat application: function onerror(event) { console.log(event); document.getElementById(‘chat’).innerHTML = “There was an error: “ + event. data; }

Going binary
By enabling the exchange of real-time data, the WebSocket API opens some interesting possibilities when combined with the rest of the host of new HTML5, JavaScript, and CSS3 features. One of the cooler demos I’ve seen is a collaborative whiteboard using the canvas element. Every time someone connected to the socket draws on it, a message gets sent out to the connected clients so everyone can see what is being drawn. It’s a neat idea, but all that’s really happening under the hood is that the socket server and application are exchanging a set of x and y coordinates in text. To illustrate the binary capabilities of the WebSocket API, I implemented a similar application that uses binary data. Specifically, I implemented a quick canvas painting feature that the user can use to draw something on a small canvas area. When the user clicks a button, the application does not send a set of coordinates to the socket server, but rather takes a snapshot of the image and sends it as binary data to the socket server. The socket server sends the data back as an image, which will appear in the chat window of all connected clients. This demo will only work in the latest version of Chrome because binary WebSocket support is still somewhat on the cutting edge. Creating binary data To send and receive binary data correctly you need to set up a binaryType for the WebSocket API. The binaryType can be either arraybuffer or blob , which are the two basic binary types that JavaScript supports. You can use either one depending on what you’re sending and how you want to access it. I found arraybuffer to be ideal for this example because it’s easy to iterate through an array, and I found that I had to copy a lot of data back and forth between arrays. So the WebSocket setup code becomes this: connection = new WebSocket(‘ws://localhost:1740’); connection.binaryType = “arraybuffer”; connection.onopen = onopen; connection.onmessage = onmessage; connection.onclose = onclose; connection.onerror = onerror;

45/47

Now you need to get binary data out of the canvas. I wrote a sendphoto() method that does the work of pulling the binary data out of the canvas element on the page. It uses the getImageData() method to get the actual binary array data and then it loops through the data and inserts it into a Uint8Array. The code accesses the buffer property of this array and sends it using the WebSocket API. function sendphoto() { imagedata = context.getImageData(0, 0, imagewidth,imageheight); var canvaspixelarray = imagedata.data; var canvaspixellen = canvaspixelarray.length; var bytearray = new Uint8Array(canvaspixellen); for (var i=0;i<canvaspixellen;++i) { bytearray[i] = canvaspixelarray[i]; } connection.send(bytearray.buffer); context.fillStyle = ‘#ffffff’; context.fillRect(0, 0, imagewidth,imageheight);

}

That data goes to the socket server and the socket server sends the binary data back out to all of the connected clients. If you’re interested in seeing how the server does that, you can take a look at the Github project for the code. Receiving a binary message To handle incoming binary messages, you’ll need to modify the onmessage() function. Because you’ll have to handle two types of data, the ArrayBuffer and the String data, you’ll want to check the instanceof property of event.data and route the data accordingly. Once you do that, the process will be to translate the ArrayBuffer data into a typed JavaScript array. Then, create a temporary Canvas element that is used to insert the ArrayBuffer data by manipulating the image data of the canvas. Finally, with the image stored in the temporary canvas, use the toDataURL() method to get a URL string that you can set as the source of an img element, which then gets displayed on the screen. if(event.data instanceof ArrayBuffer) { var bytearray = new Uint8Array(event.data); var tempcanvas = document.createElement(‘canvas’); tempcanvas.height = imageheight; tempcanvas.width = imagewidth; var tempcontext = tempcanvas.getContext(‘2d’);
46/47

var imgdata = tempcontext.getImageData(0,0,imagewidth,imageheight); var imgdatalen = imgdata.data.length; for(var i=8;i<imgdatalen;i++) { imgdata.data[i] = bytearray[i]; } tempcontext.putImageData(imgdata,0,0); var img = document.createElement(‘img’); img.height = imageheight; img.width = imagewidth; img.src = tempcanvas.toDataURL(); chatdiv.appendChild(img); chatdiv.innerHTML = chatdiv.innerHTML + “<br />”;

}

And with that, you’re sending and receiving text and binary messages with the WebSocket API.

Where to go from here
This tutorial provided an introduction to the WebSocket API and how to use it. Even though the API itself is pretty straightforward, there are a surprising number of great uses for it. Everything from basic chat to real-time games or enterprise dashboards that need real-time data can all rely on the WebSocket API for their communications. Mozilla’s Developer Network has some great content on WebSockets that applies to both WebKit and Firefox; visit https://developer.mozilla.org/en/WebSockets for details. Also take a look at Socket.io, which is great way to get started with WebSockets without having to write much code on the server to make the connections happen. Explore the sample files for this article for the client-side source code. You’ll need both it and the AIRbased socket server from Github to get the application to work. The client-side code by itself should give you a good idea of how to use the WebSocket API for any socket server that supports binary data.

+ This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.

MORE INFORMATION

>

>

appliness

DON’T WORRY, BE APPLI

Swipe to delete items with jquery mobile on touch devices
getting closer to native behavior

The swipe gesture has been broadly used on list to remove items, especially in native ios applications. let’s code this behavior with jquery mobile.

Hybrid applications raise a lot of UI and technical challenges. Using web standards, developers are working hard to reproduce native UI behaviors without impacting the global performance of their application. The swipe gesture is one of them. Today, jQuery Mobile handle swipe events which are triggered when a horizontal drag of 30px or more occurs within 1 second duration. But these thresholds can be configured. To play with this event, we’ll use a simple jQuery Mobile list and manage a two-step deletion task. First, the user will swipe on an item. Then, an active delete button appears to confirm the deletion. The swipe gesture is ideal for actions that requires an user confirmation.

P

d n u o laygr

(

e l i b o m y r - jQue s s a l C e l g g - To - Events

Difficulty
- rookie - intermediate - expert

Todo list
- swipe left - buy milk - try on iOS
by Michaël Chaize
48/52

PLAY WITH the final application
Here is the running sample of this tutorial. It’s a simple HTML page that creates a list of items from an XML file. If you swipe your finger on an item, a delete button appears. If you press the delete button, the row will fade out and be removed from the list. Try it! How does it work? The delete buttons are hidden with a height of 0px. We’ll use the toggleClass method to modify the style of a delete button when a swipe item is triggered. The project contains two files, an HTML page and a JavaScript file. Click on this icon to get more details about a section of the code:

try
i

me

Ready for some code? Go to the next page of this tutorial.

LOADING THE APPLICATION

49/52

THE HTML PAGE

<html> <head> <meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8” /> <title>swipe</title> <link type=”text/css” rel=”stylesheet” href=”http://code.jquery.com/mobile/1.1.0-rc.1/jquery.mobile-1.1.0-rc.1.min.css”/> <script src=”http://code.jquery.com/jquery-1.7.1.min.js”/></script> <script src=”http://code.jquery.com/mobile/1.1.0-rc.1/jquery.mobile-1.1.0-rc.1.min.js”></script> <script type=”text/javascript” src=”myScript.js”> </script> <style> div.menu{ height: 0px; overflow:hidden; position:absolute; top:0; right:0; -webkit-transition: all 0.2s ease-in-out; } div.menu.active { position:absolute; top:0; right:0; width:160px; height:50px; } .myItem{ height:40px; vertical-align:middle; } .ui-btn{ width:140px; } .myItem.active{ color:#CC0000; } </style> <meta name=”viewport” content=”width=device-width; initial-scale=1.0; maximum-scale=1.0; userscalable=0;” /> </head>

i

i

i

i

<body> <div data-role=”page” id=”page1”> <div data-role=”header” data-position=”fixed”> <h1>Swipe events</h1> </div> <div data-role=”content”> <div class=”list-questions”> <ul data-role=”listview” id=”listQuestions”> </ul> </div> </div> </div></body></html>

i
50/52

THE javascript code

$( document ).delegate(“#page1”, “pageinit”, function() { $.ajax({ type: “GET”, url: “questions.xml”, dataType: “xml”, success: function(xml){ var i=0; var myItems = “”; $(xml).find(“question”).each(function() { var titleQuestion = $(this).find(‘title’).text(); myItems += ‘<li id=”listItem’+i+’”><div class=”myItem”>’+titleQ uestion+’<div class=”menu”><a id=”myButton’+i+’” data-role=”button” dataicon=”delete” data-inline=”false”>Delete</a></div></div></li>’; i = i+ 1; }); $(‘#listQuestions’).html(myItems); $(‘#listQuestions’).listview(“refresh”); $(‘#listQuestions’).trigger(“create”); addBinding(); } }); });

i

i

i

function addBinding(){ for(var j=0; j< $(“#listQuestions li”).size();j++){ $(“#listItem”+j).bind(‘swipe’,function(event) { $(‘div.menu’, this).toggleClass(‘active’); $(‘div.myItem’, this).toggleClass(‘active’); }); $(“#myButton”+j).attr(‘index’,j); $(“#myButton”+j).bind(‘tap’,function(event) { theIndex = $(“#” + event.currentTarget.id).attr(‘index’);

i

i

$(“#listItem”+theIndex).fadeOut(500,function(){ $(“#listItem”+theIndex).remove(); }) ; }); } }

i

51/52

tips from this tutorial
I hope that you enjoyed the tips inside the source of this tutorial. The main ones used to achieve this sample were: - ToggleClass() This is a very useful jQuery method to manipulate class attributes. The easiest way to define transitions between states in your HTML apps is to declare two CSS styles, declare a transition in the default one and use ToggleClass() on your elements. - .trigger(“create”) When you add elements dynamically within your code, you may want to force jQuery to start again the analysis of your DOM elements. - .attr(‘index’,j) It’s an easy to flag your dynamically added HTML elements. attr() sets attributes to a set of elements. - Use pageInit(), not $document.ready() The first thing you learn in jQuery is to call code inside the $(document).ready() function so everything will execute as soon as the DOM is loaded. However, in jQuery Mobile, Ajax is used to load the contents of each page into the DOM as you navigate, and the DOM ready handler only executes for the first page. To execute code whenever a new page is loaded and created, you can bind to the pageinit event. - Swipe event (from the jQuery mobile documentation) Triggers when a horizontal drag of 30px or more (and less than 20px vertically) occurs within 1 second duration but these can be configured: - scrollSupressionThreshold (default: 10px) – More than this horizontal displacement, and we will suppress scrolling - durationThreshold (default: 1000ms) – More time than this, and it isn’t a swipe - horizontalDistanceThreshold (default: 30px) – Swipe horizontal displacement must be more than this. - verticalDistanceThreshold (default: 75px) – Swipe vertical displacement must be less than this. - More swipe events You can also use the swipeleft and swiperight events. The swipe gesture is a classic on iOS, but the UI pattern is completely different on Android for instance. For each mobile platform, you need to learn the best UI best practices and discover how to code them using web standards. That’s a big challenge, but a funny one.

ABOUT THIS ARTICLE
Michaël Chaize is a Developer Evangelist at Adobe where he focuses on Rich Internet Application and Mobile applications. Based in Paris, he works with large accounts that need to understand the benefits of rich user interfaces. He’s the editor in chief of Appliness. http://riagora.com/ @mchaize

ONLINE RESOURCES JQuery Mobile official website http://jquerymobile.com/ PhoneGap official website http://www.phonegap.com Using JQuery mobile themes http://www.adobe.com/fr/devnet/dreamweaver/articles/themecontrol-jquery-mobile.html

appliness

GET THE SOURCE CODE

(

Download the source code of all the tutorials ON YOUR DESKTOP:

http://appliness.com/code/02.zip

appliness

LIBRARY OF THE MONTH

(

app-UI is a collection of reusable “application container” user interface components that may be helpful to web and mobile developers for creating interactive applications using HTML and JavaScript, especially those targeting mobile devices.

APP-UI by andrew trice

app-UI is a continual work in progress – it was born out of the necessity to have rich & native-feeling interfaces in HTML/JS experiences, and it works great with PhoneGap applications (http://www.phonegap.com). app-UI can easily be styled/customized using CSS. All of app-UI was created using HTML, CSS, & JavaScript. All animations are rendered using CSS3 translate3d, so that they are hardware accelerated (where supported). app-UI works well on iOS, Android and BlackBerry browsers (others not tested), and works well on the latest releases of most desktop browsers (I know it does not work on old versions of IE).

54/58

Why a new navigator?
You might be wondering “why create this?” when there are other open source alternatives like jQuery Mobile. The primary motivation for creating app-UI was to have reusable application containers that are highly performant, and do not force any prescriptive development paradigms. With respect to animations/transitions, app-UI outperforms the alternatives, particularly on mobile devices. app-UI can be used with many different existing frameworks – app-UI only requires jQuery as a solution accelerator framework. It will work with existing UI widget frameworkss (jQuery UI, Twitter Bootstrap, etc…), and will work with existing templating frameworks (Moustache, Knockout, Handlebars, etc…).

Application Containers
app-UI currently has three application containers, and at this time it is not intended to be a complete UI widget framework.

ViewNavigator
The ViewNavigator component allows you to create mobile experiences with an easily recognizable mobile UI paradigm. You use this to push & pop views from the stack.

55/58

The ViewNavigator component allows you to create mobile experiences with an easily recognizable mobile UI paradigm. You use this to push & pop views from the stack. Some code used in the sample: $(document).ready( function() { //Setup the default view var defaultView = getView(); defaultView.backLabel = null; //Setup the ViewNavigator window.viewNavigator = new ViewNavigator( ‘body’ ); window.viewNavigator.pushView( defaultView ); } ); function pushView() { //create a view and push it onto the view navigator var view = getView(); window.viewNavigator.pushView( view ); } function popView() { //pop a view from the view navigator window.viewNavigator.popView(); } function getView() { //create a view descriptor with random content var bodyView = $(‘<div>’ + Math.random().toString() + ‘<hr><li href=”#” onclick=”pushView()” class=”viewNavigator_backButton”>push view</li> <li href=”#” onclick=”popView()” class=”viewNavigator_backButton”>pop view</li><hr>’ + getMeat() + ‘</div>’); var links = bodyView.find(‘a’); return { title: “Default View “ + parseInt(Math.random()*1000), backLabel: “Back”, view: bodyView }; }

56/58

SplitViewNavigator
The SplitViewNavigator component allows you to create tablet experiences with an easily recognizable mobile UI paradigm. The SplitViewNavigator allows you to have side-by-side content in the landscape orientation, and the sidebar is hidden in portrait orientation.

57/58

function getSidebarView() { var viewHTML = “<ul>” + “<li onclick=’pushSidebarView()’ class=’viewNavigator_ backButton’>Push Sidebar View</li>” + “<li onclick=’window.splitViewNavigator.popSidebarView()’ class=’viewNavigator_backButton’>Pop Sidebar View</li>” + “<li onclick=’pushBodyView()’ class=’viewNavigator_backButton’>Push Body View</li>” + “<li onclick=’window.splitViewNavigator.popBodyView()’ class=’viewNavigator_backButton’>Pop Body View</li>” + “</ul>”; return { title: “Sidebar “ + parseInt( Math.random() * 100 ).toString(), backLabel: “Back”, view: $(viewHTML) }; } function pushSidebarView() { window.splitViewNavigator.pushSidebarView( getSidebarView() ); }

SlidingView
The SlidingView allows content to slide to the side using a horizontal swipe gesture, revealing a navigation container “underneath”. This is very similar to the behavior in Facebook’s iPad application. Just swipe horizontally with a finger:

DOWNLOAD AND CONTRIBUTE
No software is ever bug-free. If you encounter an issue, have feedback, or have feature requests, please log them at: https://github.com/triceam/app-UI/issues or fork it, fix it, and send me a pull request. You can see this framework in the following real-world apps: US Census Browser: http://itunes.apple.com/us/app/us-census-browser/id483201717?mt=8 http://tricedesigns.com/census Get started with appiUI today! Just browse to http://triceam.github.com/app-UI/, read the details, download a copy, and start building your own apps! If you’re building something cool with it, then let me know! I’d love to hear about it.

MORE INFORMATION

>

>

appliness

(

APPLINESS FOCUS GROUP

HTML5 multimedia components Part I: overview
Interview of Ian Devlin
Hi Ian. You’ve been working on web technologies for more than 10 years. Can you introduce yourself to our readers? Hi Michael and thanks. Well I haven’t always worked with web technologies as I initially started off as a software developer for a speech recognition company where I was working with the C programming language. During my time at that company I did become interested in web technologies though, as we were creating team intranet sites and I was a part of that. It led me to look for a more web development role for my next job (after being made redundant) and I ended up working for the games company Jagex as a web developer working with Java and of course HTML, CSS and JavaScript. I then (erroneously) moved away from web development for a short while before realising that it was where I wanted to be and I’ve been doing it ever since. I first became interested in HTML5 at the end of 2009, and have been using it since then. I was also lucky

IAN DEVLIN, THE AUTHOR OF “HTML5 Multimedia: Develop and Design” explains how to use the HTML5 VIDEO AND AUDIO ELEMENTS, AND HOW TO CREate custom playback components.

enough to write a book on HTML5 Multimedia with Peachpit. What are you currently working on? Nothing special est. I’ve re c e n t moved Germaso I’ve b e e n concentrating on settling in here and trying to improve my German. That said, I did find the time to redesign my to be hono n l y l y t o ny

website, including a custom built Wordpress theme (based on HTML5 Starkers though which sped up the process!). In addition my job requires learning some new technologies such as TYPO3 which is used a lot in Germany so I have that to do too. I am trying to find some personal project to work on though, so if anyone needs a co-conspirator... You’re a recognized HTML5 expert, especially when it deals with Multimedia elements such as video and audio. Why did you focus on this topic? It happened by accident! I curate for HTML5 Gallery and Peachpit, now my publisher, who were looking for someone to write a book on HTML5 multimedia and they approached us. Writing a book was something I had never thought about doing before but I thought that this would be a good opportunity so I went for it. I knew the basics of using HTML5 multimedia already of course, but there were other related topics that I had to learn in order to be able to write about them. This was ideal though as I would read about something, test it, and then write about it in an orderly fashion while it was still fresh in my mind. So it wasn’t planned and I focused on it as I had a book to write! Apple encouraged the use of the HTML5 video tag when they launched devices without Flash. What has evolved since this positioning that happened 2 years ago? Do you feel that HTML5 is rapidly growing and evolving to broadcast multimedia content? I think a lot of developers were already aware of HTML5 multimedia and the <audio> and <video> elements, but Apple’s announcement probably increased this number (of developers) but also brought it to the attention of nondevelopers who suddenly had to find another method of delivering video and audio to Apple devices. A number of related JavaScript APIs which utilise HTML5 multimedia are currently being developed that allow more advanced audio manipulation and also the ability to access a device’s web cam (e.g. Opera have re-

leased a demo of this). Eventually it will probably be possible to have video conferencing in the browser using HTML5 alone. In your opinion, what should be improved in the current HTML5 specifications for multimedia content? The issue of DRM is a big one for some companies who have a business requirement for protected content. Not everyone agrees with this requirement, but I feel that’s a moot point as you won’t change that mindset for a long time. This has restricted these big companies from using HTML5 multimedia and I think that something to facilitate these companies’ requirements should be added. That said, there is currently a proposal to explore this topic and potentially either add it to the HTML5 specification or create a separate but related specification that supports it. Whether you agree with DRM or not, its addition would increase take up. Do you have in mind an amazing HTML5 multimedia experience that we could share with the readers? I don’t know about amazing, but I think there will come a time when the afformentioned video conferencing with configurable sound and automatic subtitles (if required) will be possible and quite useful. HTML5 already helps with subtitles via WebVTT and I think it’ll be possible to either have someone translating on the fly (in the same way subtitles are added to live TV programmes) and entering values that way. With some of the sound APIs being worked on, browser games and videos in general should hopefully be able to take advantage of all the capabilities of advanced sound systems (e.g., surround sound) through the browser. You blog, you also wrote a book... Would you say that sharing your knowledge is essential for you and for developers in general? Sharing knowledge is not essential, but definitely very useful. I can’t count the number

of times I’ve come across a problem, gone to Google and found that others have had the exact same issue and solved it. Even if the solution isn’t presented, blog and forum posts can lead to discussions that will set you on the right track, or even off on a tangent to creating something else. As web develoeprs we’re constantly learning, especially from each other. I’m a big fan of the music band called Justice. Now that we get the Audio and the Video elements in HTML5, should we get the Disco tag pretty soon? My first thought on reading that was that it would be similar to the <blink> tag that was deprecated in HTML5! I’d envision it taking a number of images and flashing them to the screen with various filters...and that can’t be a good thing! Interview by Michaël Chaize

HTML5 Multimedia: Develop and Design
By Ian Devlin
One of the most exciting and talked about aspects of the HTML5 specification is the introduction of in-browser multimedia. Websites no longer have to rely on a third-party tool such as Flash or Silverlight to play video and audio. This book is an easy, approachable guide to building native HTML5 multimedia into a website, from the simplest addition to more advanced features. It’s written in a simple, straightforward style that’s not too techy, yet advanced enough for the more experienced coder who just needs to get up to speed on these powerful new capabilities. The book’s companion website provides all the examples in a working format for easy access and enhanced visualization for the reader.

Topics include: - Using Audio: How to add audio to web documents using the HTML5 audio element. - Using Video: How to add video to web documents using the HTML5 video element. - JavaScript API and Custom Controls: How to use the HTML5 Media JavaScript API to create custom controls for HTML5 audio and video. - Styling Media Elements with CSS: Shows how HTML5 media elements can be styled with CSS2.1 and CSS3. - Using Video with SVG: Shows how SVG and HTML5 video can work together. - Using Video with Canvas: Introduces the HTML5 canvas element and shows how HTML5 video and canvas can work together.

appliness

HTML5 multimedia components Part II: VIDEO

This new ability for browsers to provide native video has made it easier for web developers to add video content to their websites without having to rely on the availability of external technology.

THE VIDEO ELEMENT
As you are no doubt aware by now, one of the most popular and most talked about features of HTML5 is the ability to embed video content directly into your web pages without the need for a third-party plug-in such as Flash Player. This new ability for browsers to provide native video has made it easier for web developers to add video content to their websites without having to rely on the availability of external technology. With the limitations Apple has currently imposed on Flash technology for iPhones and iPads, the ability to deliver HTML5 video has become even more important. This tutorial introduces you to the video element, its attributes, and the different types of video that can be used with it. It is the first tutorial in a three-part series that covers the video element, the audio element, and custom controls for working with both elements.

P

d n u o laygr

(

APPLINESS FOCUS GROUP

Difficulty
- rookie - intermediate - expert

- HTML5 - Video - Codecs

Todo list
- encode - play - fallback

by Ian Devlin

62/68

Serving a video: A quick comparison of two techniques
If you were to set up a simple MP4 video to be played on a website using Flash Player, you might use the following code: <object type=”application/x-shockwave-flash” data=”player.swf?videoUrl=myVideo.mp4&autoPlay=true” height=”210” width=”300”> <param name=”movie” value=”player.swf?videoUrl=myVideo.mp4&autoPlay=true”> </object> Using HTML5, you can use the following code: <video src=”myVideo.mp4” controls autoplay width=”300” height=”210”></video> Of course this HTML5 example is extremely simplified, but the functionality is the same and you can see just how much easier it is.

VIDEO CODECS
Video codecs are software that encode or decode video for a specific file format. Although the HTML5 specification initially mandated support for the Theora Ogg video codec, this requirement was dropped from the specification after it was challenged by Apple and Nokia. Sadly, this means that different browsers support different codecs, which sounds like a bit of a pain and it is. Recently, however, the situation has improved so that you actually only need to provide your video content in two different formats: MP4/H.264 for Safari and Internet Explorer 9, and WebM for Firefox, Chrome, and Opera. Firefox also supports Theora Ogg, but it has supported WebM since version 4. There is, of course, a way to define more than one video file for your video content, but I’ll cover that a bit later.

VIDEO ELEMENT
The video element, which you use to embed the video into your web page, can include several different attributes, some of which are outlined in this table. Attribute src autoplay controls muted loop Description Provides the URL of the video file. Indicates that the video should be started automatically, where possible. Tells the browser to display its default video control set. Sets the video’s initial audio state to muted. (This attribute is currently not supported by any browser.) Indicates that the video should be played continuously in a loop. (Firefox currently doesn’t support this attribute.)
63/68

Attribute poster width height preload

Description Sets a default image to display instead of the video’s first frame. Specifies the width of the video element in pixels. Specifies the height of the video element in pixels. Suggests to the browser how it should attempt to preload the video in question. It can have three possible values: - none: don’t perform any preloading - metadata: only load the video’s metadata, for example, duration - auto: lets the browser decide for itself (this is the default)

For example, if you want a video to play automatically and for the browser to provide the controls, you simply use: <video src=”myVideo.mp4” autoplay controls></video>

THE SOURCE ELEMENT
The examples used in the previous sections use only one video file in one format, MP4. So how do you go about also serving a WebM video file? This is where the source element comes in. A video element can contain any number of source elements, which let you specify different sources for the same video. The source element has three attributes, as shown in this table. src type media The URL of the video source. The type of the video source; for example, video/mp4 or video/webm. The actual codec used can also be specified within this string. The intended media type of the video. Specified using CSS3 Media Queries, this attribute enables you to specify different videos (that are smaller in size and resolution, for example) for handheld devices.

To specify both an MP4 and WebM source for the same video, you could use the following code: <video autoplay controls> <source src=”myVideo.mp4” type=”video/mp4”> <source src=”myVideo.webm” type=”video/webm”> </video> When a browser attempts to play the video, it will check the list of sources until it finds one that it can play. So Firefox will skip the MP4 source as it is unable to play it, but it will happily play the WebM source file. Note that in the previous example I’ve removed the src attribute from the video element itself since the src attributes in the source element are being used instead. If you did specify the src attribute in the video element, it would override any src attributes in the source elements. If you wish, you can specify the exact codec that was used to encode the video file. This helps the brows64/68

er decide whether it can play the video or not. It’s generally a better idea to simply provide the type and let the browser decide for itself, as often you’re not sure of what codec was actually used. Should you wish to include the codec, you can do so as follows: <video autoplay controls> <source src=”myVideo.mp4” type=’video/mp4; codec=”mp4a.40.2”’> <source src=”myVideo.webm” type=’video/webm; codec=”vp8”’> </video> Note how the codec is added to the type attribute, specifically the quotes used and the separation of the type and codec by a semicolon. When adding the codec to the type definition, it’s relatively easy to misplace the quotes, which will make the video unplayable because the browser will be unable to parse the source element. So, if you decide to specify the codecs explicitly, be careful.

LEGACY FALLBACK
Of course, you’ll also need to provide a solution for those users who continue to use a browser that doesn’t support HTML5, such as Internet Explorer 8 and below. Since browsers ignore what they don’t understand, legacy browsers such as Internet Explorer 8 will ignore the video and source elements and simply act as if they don’t exist. You can take advantage of this behavior to provide an alternative method of displaying your video, either via a simple download link, or a third-party plug-in such as Flash Player. Building on the earlier example, you might provide a link to the same video as follows: <video autoplay controls> <source src=”myVideo.mp4” type=”video/mp4”> <source src=”myVideo.webm” type=”video/webm”> <a href=”myVideo.mp4”>Download the video</a> </video> The legacy browser will only display the link to the video file download. Adding support for Flash Player is just as easy: <video autoplay controls> <source src=”myVideo.mp4” type=”video/mp4”> <source src=”myVideo.webm” type=”video/webm”> <object type=”application/x-shockwave-flash” data=”player. swf?videoUrl=myVideo.mp4&autoPlay=true”> <param name=”movie” value=”player.swf?videoUrl=mVideo mp4&autoPlay=true”> </object> <a href=”myVideo.mp4”>Download the video</a> </video>

65/68

With this example, an older browser such as Internet Explorer 8 will display the video in Flash Player (if Flash Player is installed on the system) and also the download link. By providing a download link as well as a Flash Player fallback, you’re giving users who don’t have Flash Player installed a way access the video by downloading it and viewing it from their desktop.

Digital rights management
If you’re concerned about people being able to download and freely share your videos, then HTML5 video may not be right for you. When you use any of the methods described in this article, you enable users to access the direct URL to your video files, which they can then freely download. There is currently no way to prevent this with HTML5. At some point in the future a standard method may emerge to handle digital rights management (DRM) in HTML5 itself, but currently there is no such method. For more information on HTML5 and DRM see the W3C’s HTML FAQs on this topic.

Video subtitling
The provision of subtitling for HTML5 video was initially part of the HTML5 specification. A file format called WebSRT was defined, and this format could be used to specify video subtitles using the popular SRT file format. Later renamed to WebVTT (Web Video Text Tracks), the subtitling specification was taken out of the HTML5 specification and given a specification of its own. A WebVTT file is a specially formatted text file with a .vtt file extension. The file itself must be UTF-8 encoded and labeled with the type/vtt MIME type. The file must begin with a WebVTT string at the top. Lines within the file are terminated by a carriage return (\r), a new line (\n), or a carriage return followed by a new line (\r\n). The file consists of a number of cues, which are used to specify the text and timing location within the video file of the subtitle in question. The basic format is as follows: WEBVTT [unique-cue-identifier] [hh]mm:ss.msmsms --> [hh]mm:ss.msmsms [cue settings] Subtitle text 1 [Subtitle text 2] ... The unique-cue-identifier is optional. It is a simple string that helps identify the cue within the file. The cue timing is given in a straightforward format, with the hour portion optional. Each cue can also have a number of cue settings, which are used to align and position the text. These are described in more detail below. Next follows the actual text of the subtitle, on one or more lines.
66/68

The individual cues for different time locations within the video file are set up in this way, with each cue block separated by a new line. Here is a short example: WEBVTT 1 00:00:10.500 --> 00:00:13.000 Elephant’s Dream 2 00:00:15.000 --> 00:00:18.000 At the left we can see... You can use the cue settings to specify the location and alignment of the subtitle text that is overlaid on the video. There are five such settings, as shown in this table. Cue setting D:vertical | vertical-lr L:value A:start | middle | end T:value S:value Description The text direction: vertical right-to-left or vertical left-to–right. The line position, either in percentage values or a specific line number. The alignment of the text relative to the line. The text position, in percentage, relative to the video frame. The text size, in percentage.

For example, to position text at the end of the line, 10% from the top of the video frame, you would use the following cue settings: 2 00:00:15.000 --> 00:00:18.000 A:end L:10% At the left we can see... You can see how the WebVTT file can be built up in this way to add subtitles to an entire video. You may be wondering how you link your WebVTT file to your video. The answer is the track element. This element, which was also introduced in HTML5, lets you specify external text tracks for media elements such as video. Its attributes are shown in the following table. Attribute kind src srclang Description The type of content for the track definition. Can be one of: subtitles, captions, descriptions, chapters, metadata. The URL to the text track, in this case the WebVTT file. The language of the text track data.
67/68

label default

A user-readable label for the text track. If present, indicates that this text track is the default.

For example, consider a WebVTT file named english-subtitles.vtt that you want to attach to the video example used above. You could do this using the following code: <video autoplay controls> <source src=”myVideo.mp4” type=”video/mp4”> <source src=”myVideo.webm” type=”video/webm”> <track src=”english-subtitles.vtt” kind=”subtitles” srclang=”en” label=”English subtitles”> </video> This ties the WebVTT file with English subtitles to your video. You can, of course, have multiple track elements within the video element. With the srclang attribute you can specify multiple WebVTT files that are in different languages to add subtitle support in multiple languages. (The default attribute can then be used to identify the track to use if the user’s preferences to not indicate a more appropriate track.) Unfortunately, no browsers currently support WebVTT directly, but there are a number of JavaScript libraries available that enable you to use the WebVTT file format and provide subtitles for your videos, including: - Playr - Captionator (CaptionCrunch version) - LeanBack Player - MediaElement.js All of these solutions support video subtitles, and some offer additional features. Browsers are beginning to add support with both Safari and Firefox making advancements towards support, and Microsoft have recently posted a demo on WebVTT which shows how serious vendors are about supporting WebVTT in the near future. You have seen how easy it is to add HTML5 video to your web pages and provide a fallback method using Flash Player to serve video content to legacy browser users. As powerful as it is, HTML5 video is not currently advisable for those wishing to protect their video content, as it provides no DRM capability. You also saw, briefly, how you will be able to add subtitles to your videos in the future, and how you can do it now via JavaScript libraries.

appliness

HTML5 multimedia components Part III: AUDiO

In this ARTICLE I cover the audio element, its attributes, and the different types of audio files that can be used with HTML5. Many of the concepts and techniques covered in the previous article for video apply to audio as well.

THE AUDIO ELEMENT
In the first article of this three-part series on working with HTML5 multimedia components, I focused on embedding video in web pages using HTML5. Of course, most videos include audio, and if you want to embed audio files into your web pages you can achieve this with HTML5 just as easily. In this article I cover the audio element, its attributes, and the different types of audio files that can be used with HTML5. Many of the concepts and techniques covered in the previous article for video apply to audio as well, so if you’ve read it then you’ll notice some similarities in this one.

P

d n u o laygr

(

APPLINESS FOCUS GROUP

Difficulty
- rookie - intermediate - expert

- HTML5 - Audio - DRM

Todo list
encode listen protect

by Ian Devlin

69/72

Serving aN AUDIO FILE: A quick comparison of two techniques
Before HTML5, if you wanted to embed an audio file into your web page, you had to use a third-party plug-in such as Flash Player. For example, to embed an MP3 audio file in your web page and make it available via Flash Player, you might use the following code: <object type=”application/x-shockwave-flash” data=”player.swf?audioURL=myAudio.mp3&autoPlay=true” height=”27” width=”320”> <param name=”movie” value=”player.swf?audioUrl=myAudio.mp3&autoPlay=true”> </object> Using HTML5, you can you can be more succinct: <audio src=”myAudio.mp3” controls autoplay></audio> This snippet of HTML5 code achieves the same result as the more verbose code for Flash Player: It embeds an audio file into a web page to play automatically. You can see just how much easier and neater HTML5 code can be.

AUDIO CODECS
I covered video codecs in Part 1 of this series, and it will come as no surprise to learn that many of the ideas carry over to audio codecs. The HTML5 specification initially had made support for the Ogg Vorbis codec mandatory, but Apple and Nokia’s challenge put an end to this. Browsers today support more audio codecs than video codecs, so you have more choices when deciding what to use: - Firefox supports Ogg Vorbis and WAV. - Safari supports MP3, AAC, WAV, and MP4. - Internet Explorer 9 supports MP3, AAC, and MP4. - Opera supports Ogg Vorbis and WAV. - Chrome supports all of the above. To cover all browsers that support HTML5 audio, you need to serve your audio in only two different formats: Ogg Vorbis and MP3. It’s not advised to use the WAV file format as it doesn’t compress very well if at all and therefore the file size can be quite large.

THE AUDIO ELEMENT
As you’ve seen, the audio element is used to embed audio files within a web page. Like the video element, it can have a number of attributes, some of which are listed in this table: Attribute src autoplay Description Provides the URL of the audio file. Indicates that the audio should be started automatically, where possible.

70/72

Attribute controls muted loop preload

Description Tells the browser to display its default audio control set. Sets the initial audio state to muted. (This attribute is currently not supported by any browser.) Indicates that the audio should be played continuously in a loop. (Firefox currently doesn’t support this attribute.) Suggests to the browser how it should attempt to preload the audio in question. It can have three possible values: - none: don’t perform any preloading - metadata: only load the audio’s metadata, for example, duration - auto: lets the browser decide for itself (this is the default)

For example, with the audio element and its attributes, you can use the following code to embed an MP3 audio file that starts playing on load, has a default set of controls, and loops repeatedly: <audio src=”myAudio.mp3” autoplay controls loop></audio> I must point out that this example would likely be quite annoying to your users. Automatically playing a looping audio file is generally considered to be bad Internet etiquette.

USING THE SOURCE ELEMENT
As I noted earlier, you’ll need to provide audio files for at least two different codecs to cover all browsers that support HTML5. As with the video element, you use the source element to accomplish this. An audio element can contain multiple source elements, so you can provide your audio in multiple formats. Extending the previous example, you can specify both an Ogg Vorbis and MP3 source for the same audio content as follows: <audio autoplay controls> <source src=”myAudio.ogg” type=”audio/ogg”> <source src=”myAudio.mp3” type=”audio/mp3”> </audio> When the browser parses the audio element, it will proceed through the list of source elements sequentially until it finds a file format that it can play. Once it does, it plays it and ignores any subsequent elements. In this case, Firefox and Opera would play the Ogg file. Chrome would also play the Ogg file, even though it is also capable of playing the MP3 file. Safari and Internet Explorer 9 would play the MP3 file. You can also specify the exact codec that was used to encode the audio file. This can help the browser decide whether it can play the content or not. It’s generally a better idea to simply provide the type and let the browser decide for itself, as often you’re not sure what codec was actually used. If you want to include the codec, you can do so as follows: <audio autoplay controls> <source src=”myAudio.ogg” type=’audio/ogg; codec=”vorbis”’> </audio>
71/72

Note how the codec is added to the type attribute, specifically the quotes used and the separation of the type and codec by a semicolon. As with specifying the video codec, it’s not difficult to make a formatting mistake here that will render the audio unplayable. So, if you’re specifying the codecs explicitly, be careful with the syntax.

LEGACY FALLBACK
Not everyone uses a browser that supports HTML5. Older versions of Internet Explorer (version 8 and below), for example, are still quite popular. To support users who are using these browsers, you can use a third-party plug-in such as Flash Player to embed audio files, just as you would have before the arrival of HTML5 and native multimedia. Browsers disregard what they don’t understand, so your HTML5 audio and source elements will be completely ignored by older browsers such as Internet Explorer 8. For example, you might use the following code to add a link to the audio file: <audio autoplay controls> <source src=”myAudio.ogg” type=”audio/ogg”> <source src=”myAudio.mp3” type=”audio/mp3”> <a href=”myAudio.mp3”>Download the audio file</a> </audio> Older browsers will simply display the “Download the audio file” link and ignore the rest. To add fallback support via Flash Player (as well as the download link) you can use the following code: <audio autoplay controls> <source src=”myAudio.ogg” type=”audio/ogg”> <source src=”myAudio.mp3” type=”audio/mp3”> <object type=”application/x-shockwave-flash” data=”player. swf?audioUrl=myAudio.mp3&autoPlay=true”> <param name=”movie” value=”player.swf?audioUrl=myAudio. mp3&autoPlay=true”> </object> <a href=”myAudio.mp3”>Download the audio file</a> </audio> Older browsers will display Flash Player and the download link, so users can choose how they want to access the audio. If a user doesn’t have Flash Player installed they can still access your audio file via the download link. Note that you can use the same MP3 audio file with Flash Player, since it is fully capable of playing MP3 files.

Digital rights management
HTML5 currently does not support digital rights management (DRM). As a result, if you don’t want users to be able to download your audio files, then HTML5 audio is probably not the right solution for you. HTML5 exposes the links to your audio files, so they are openly available for users to access the content. There is currently no way to prevent users from downloading HTML5 audio content, although it’s possible that in the future there will be.

appliness

HTML5 multimedia components Part IV: custom components

If you want to achieve a uniform look across browsers for your media controls, you can use the handy HTML5 media element API. You can create and style your own media control set using standard HTML and CSS and then use the media element API to hook it up to the audio and video elements you want to control.

THE MEDIA ELEMENT
This is Part 3 in a three-part series of articles on HTML5 multimedia. In Part 1 and Part 2, I covered the video and audio elements, respectively, and briefly showed how adding the controls attribute to these elements informs the browser to add a set of default controls to the media element in question. If you tried out the code for those tutorials, you may have noticed that the controls look different depending on the browser you are using. If you want to achieve a uniform look across browsers for your media controls, you can use the handy HTML5 media element API. You can create and style your own media control set using standard HTML and CSS and then use the media element API to hook it up to the audio and video elements you want to control. This tutorial describes the steps needed to gradually build up a custom media player, adding various features and functionality in the process, and using different API attributes, events, and methods. You can see the completed media player by downloading and exploring the sample files for this article.

P

d n u o laygr

(

APPLINESS FOCUS GROUP

Difficulty
- rookie - intermediate - expert

- HTML5 s t n e n o p m - co t p i r c S a v a J -

Todo list
- play - pause - rewind

by Ian Devlin

73/79

Getting started
To begin with, you’ll need to define a video element to use with the yet to be created media player: <video id=”video” controls> <source src=”grass-in-the-wind-sma.mp4” type=”video/mp4”> <source src=”grass-in-the-wind-sma.webm” type=”video/webm”> </video> You’ll notice that the controls attribute has been defined for the video, even though you’re going to create your own. Since your custom controls will be built in JavaScript, you’re going to turn the default controls off via JavaScript. That way, if a user has JavaScript turned off, they’ll still be served with the browser’s default control set. To turn the default controls off, you simply set the video element’s controls attribute to false: <script> // Grab a handle to the video var video = document.getElementById(“video”); // Turn off the default controls video.controls = false; </script> And with that, you’re ready to move on!

Adding play and pause functionality
The first and most basic requirement for any media player is the ability to play and pause the media in question. For this example, you’ll use a single button, which will serve as a play button when the video is paused (or stopped) and a pause button when it’s playing. <div id=”controls”> <button id=”playpause” title=”play”>Play</button> </div> Next, you need to create a JavaScript function that will do the work of changing the button title and starting or pausing the media. In this example, the function is named togglePlayPause(). Take a look at the full implementation below; a line-by-line explanation follows. function togglePlayPause() { var playpause = document.getElementById(“playpause”); if (video.paused || video.ended) { playpause.title = “pause”; playpause.innerHTML = “pause”; video.play(); } else { playpause.title = “play”; playpause.innerHTML = “play”; video.pause(); }}
74/79

To have this function invoked every time the play/pause button is clicked, you add it to the onclick event of the button: <button id=”playpause” title=”play” onclick=”togglePlayPause()”>Play</button> The first line of the togglePlayPause() function obtains a handle to the play/pause button itself, and assigns it to the variable playpause: var playpause = document.getElementById(“playpause”); Next, it checks the status of the video to see if it’s paused or ended, via the two attributes paused and ended. If the video is in either of these states, it then sets the button’s title and innerHTML attributes to “pause” and calls video.play() to start playing the video. If the video is not currently paused or ended, then you can assume it is already playing. In this case, the function sets the button’s title and innerHTML to “play” and calls video.pause() to pause the video. The button’s default text is “play.” When the button is clicked for the first time, the video will start playing and the button’s text will be changed to “pause.” Subsequently, when the pause button is clicked, the video will pause and the button’s text will be changed back to “play.” As you’ll see, the remaining functionality that you’ll add in this tutorial follows the same basic format: listen for an event from the video element, check the element’s status, and then act on it via API methods.

Adding volume and mute buttons
Another vital piece of functionality for a media player is the ability to control the volume, including the ability to mute it altogether. To add a volume control, you’ll use one of the new HTML5 input types: range. This input type is usually rendered by the browser as a slider, which the user can move from left to right and vice versa, so it’s ideal for a volume control. You specify the minimum and maximum values for the range input via the min and max attributes. You use the step attribute to set the amount you want the slider’s value to change when the slider’s position changes. To create a volume control slider with a range between 0 and 1, and a step size of 0.1, you can use the following code: <input id=”volume” min=”0” max=”1” step=”0.1” type=”range” /> When the slider is moved, you want to invoke a JavaScript function that will adjust the volume, so add an onchange event handler: <input id=”volume” min=”0” max=”1” step=”0.1” type=”range” onchange=”setVolume()” /> Next, create a JavaScript function named setVolume(): function setVolume() { var volume = document.getElementById(“volume”); video.volume = volume.value; } This simple function obtains a handle to the volume slider and assigns its value to the video element’s volume attribute.
75/79

Note: Firefox 7 doesn’t support the range input type and displays a text field instead. Typing a new value in this text field (between 0 and 1) and moving the focus away from the text field will alter the volume in this browser. Adding a mute button is just as easy. Again, you start by defining a new button, this time with an onclick handler: <button id=”mute” onclick=”toggleMute()”>Mute</button> Next, create a function named toggleMute(): function toggleMute() { video.muted = !video.muted; } This function simply sets the video element’s (Boolean) muted attribute to be the opposite of its current value. This toggles the mute status of the button. Easy!

Adding a progress bar
When a video is playing, users are accustomed to checking the progress bar to see how much has played and how much is left to play. To add a simple progress bar to your media player, you can use a div element and a span element. Specifically, you increase the width of the span element as the video progresses, using it to represent the amount played. <div id=”progressBar”><span id=”progress”></span></div> Of course, you’ll want to style these elements with simple CSS so that the progress can be seen easily: #progressBar { border:1px solid #aaa; color:#fff; width:295px; height:20px; } #progress { background-color:#ff0000; // red height:20px; display:inline-block; } Next, define a function that will update the progress bar by changing the width of the span element: function updateProgress() { var progress = document.getElementById(“progress”); var value = 0; if (video.currentTime > 0) { value = Math.floor((100 / video.duration) * video.currentTime); } progress.style.width = value + “%”; }

The first line of this function obtains a handle to the progress span element itself. It checks the value of the video element’s currentTime attribute, which defines the current playback position, in seconds. If currentTime is greater than 0, and therefore the video has advanced, it calculates the current progress as a percentage using the video element’s duration attribute, which contains the video’s total length in seconds. Finally, it sets the CSS width of the progress span to this calculated value. With the play, pause, mute, and volume controls you used events such as onclick and onchange to invoke the appropriate functions. You can’t use this approach with a progress bar, because it updates in response to video progress, not user interaction. The HTML5 media element API, however, raises a number of events that you can listen for and act upon instead. One of these is the timeupdate event, which fires every time the media’s currentTime attribute is changed. (This attribute changes as the media is played.) In the JavaScript initialization code of your web page, add an event listener that invokes the updateProgress function when the timeupdate event fires: video.addEventListener(“timeupdate”, updateProgress, false); Now your progress bar will be updated as the video plays.

Listening for Events
The media element API defines a number of events that you can use in implementing a media player. For a complete list, see the W3C’s summary of media element API events. The following table shows several of the more commonly used events. Event name playing ended timeupdate play pause volumechange Description Raised when playback of media is ready to start after having been previously paused Raised when the media has stopped playing as it has finished Raised when the media’s current playback position has changed Raised when the media that was previously paused is no longer paused and playback has resumed Raised when the pause() method has returned and the media has been paused Raised when the media’s volume or muted attribute has changed

When you’re adding custom controls, it’s good practice to listen for some of the available events to make sure your controls are always synchronized with the state of the video. How might the controls lose synchronization? Recall that you removed the default control set via JavaScript. It is possible, however, for a user to reenable these controls and use them to interact with the video. For example, in Firefox, a user can right-click the video, select Show Controls, and click Play or Pause. If a user did this and started a video playing, then the text on the play/pause button that you created would no longer accurately reflect the media’s current state. Regardless of what mechanism is used to control the video, the appropriate events will still be raised. So you can listen for the pause and play events and act on them accordingly to keep your buttons in synch; for example:

video.addEventListener(‘play’, function() { var playpause = document.getElementById(“playpause”); playpause.title = “pause”; playpause.innerHTML = “pause”; }, false); video.addEventListener(‘pause’, function() { var playpause = document.getElementById(“playpause”); playpause.title = “play”; playpause.innerHTML = “play”; }, false); You should also listen for the ended event, so that when the video ends, the play/pause button is also kept up to date. You can do this by calling the pause() method on the video when the ended event is raised: video.addEventListener(‘ended’, function() { this.pause(); }, false); Note: The reason you call the pause() method here is that it automatically causes the pause event to be raised which will in turn cause the code we’ve written above for the pause event handler to be called. You could indeed duplicate the code in the ended event handler, or, if you wanted to do something different or extra, you would define it here.

Adding a playlist
The final feature to add is a media playlist, which the user can use to change the video played in the media player. This is actually quite simple. First of all you define your playlist; for example: <ul id=”playlist”> <li><a href=”#” onclick=”playlistClick(‘grass-in-the-wind-sma’);”>Grass blowing in the wind</a></li> <li><a href=”#” onclick=”playlistClick(‘tree-in-the-wind-sma’);”>Trees blowing in the wind</a></li> </ul> There are two items in this playlist, and each calls a function named playlistClick() when clicked. This function takes a single argument: the stem of the video file it is to play (that is, the file name without the file extension). This function is defined as follows: function playlistClick(file) { var v = document.createElement(“video”); if (v.canPlayType(“video/mp4”) != “”) { changeSource(file + “.mp4”); } else if (v.canPlayType(“video/webm”) != “”) { changeSource(file + “.webm”); } return false; } This function first creates a temporary video element and then calls the canPlayType() method for each of the supported video types, which in this case are MP4 and WebM. After determining which file type the browser is capable of playing, it calls changeSource() with one argument, the file stem that

was passed into the function concatenated with the appropriate file extension. This function also returns false to prevent the element from following the link to the value of its href attribute. The changeSource() function is defined as follows: function changeSource(src) { resetPlayer(); video.src = src; video.load(); } This function calls resetPlayer(), which you’ll look at next, and then sets the video element’s src attribute to the new video file that has been passed as an attribute. Finally, it calls load() to load the new video source into the video element. Note: Not all browsers require the load() method to be called, but Safari does. Therefore it’s a good idea to call it. The resetPlayer() function resets a few of the player’s components in preparation for loading a new video: function resetPlayer() { var playpause = document.getElementById(“playpause”); playpause.title = “play”; playpause.innerHTML = “play”; if (video.currentTime > 0) video.currentTime = 0; updateProgress(); } First, it sets the play/pause button text to “play.” Next it resets the video element’s currentTime variable to 0 if it’s not already at 0. Finally it calls the updateProgress() function, which will reset the progress bar back to the start. (The progress bar uses the video element’s currentTime attribute, which was just set to 0.)

Where to go from here
That’s it! You’ve seen all the steps necessary to create a simple HTML5 media player. It is admittedly not the most attractive player available, but you can use CSS to style it and improve its appearance. To see more of the media element API, its events, and its properties in action, check out the W3C’s HTML5 Video Events and API demonstration page, which plays videos with basic controls and displays API properties and events.

Picture by Ade Oshineye

PAMELA FOX

“To me, programming wasn’t about math, it was about making apps that people could interact with, and that’s what was so cool about it.”

S

80/83

ee why this twenty-something-year old shy girl is asked to speak at conferences and user groups around the world...that is, when she’s not reading, writing, coding or just generally horsing around.

Hi Pamela, it’s a great honor that you have agreed to an interview for the second issue of Appliness magazine (BTW, our first, of hopefully many, women interviewees). Can you introduce yourself to our readers? I'm a twenty-something-year-old living in San Francisco. I suppose I would be best described as a web developer, though I've never identified as one. I just like making stuff, and coding is my means to that end.

What do you think are some roadblocks in the way of developers effectively deciding on a mobile strategy? In preparing a talk on mobile app strategies a few months ago, I researched the different mobile app platforms out there and discovered that there are a huge number of them, with a variety of input languages, optimal use cases, and pricing models. But, the fact that there are so many of them and that they’re so new makes it hard for developers to pick one. A platform might look promising from the landing page, but it may play out very differently. Does it breakdown when you try to customize it? Does it perform horribly? Does with their support suck?

I graduated from USC in 2007 with a bachelors and masters in Computer Science, with minors in Linguistics and 3-D animation. After that, I spent 5 years in Google Developer Relations working on the widely successful Maps API, and the went ill-fated Wave API. (Hey, you win some, “I you lose some). I recently left Google to PhoneGap and I When I’m thinking of using a new platpursue my own projects and see what form, I take to Twitter and ask my followthey might turn into. I've been working achieve my goal of ers what they think of it, and I’ll usually on a nutrition-tracking service (eatdifre-usability...” get a handful of responses reporting on ferent.com) for almost a year now, and the good and the bad of it. But I’m in since I offer both web (Python/AppEnthe fortunate situation of having a sizable number gine) and mobile (PhoneGap/HTML5) interfaces for of followers to ask, and most developers aren’t. it, it's been a great learning experience. On my blog a few months ago, I proposed what I called a “yelp for developers” - a review site for developer platforms, so you could see, at a glance, It sounds like you got an early start in the world of what other developers think about the platform beprogramming. How old were you when you really got fore you start developing with it. I’d argue it’s more interested in computers and programming? important to have a yelp for developers than a yelp for restaurants, because hey, a meal only lasts a few On one fateful Mother’s Day, I realised I did not hours, but an app can last months. Maybe Yelp will have a gift for my mum, and since we lived approxipivot. :) mately in the middle of nowhere, I didn’t have an easy way to obtain a physical gift. We did have a What are some of the hidden gotchas when develT1 line in our house though (my dad’s a computer oping in the wide world of HTML5 and how have you scientist), and I was very aware of the internet - so learned to work around some of those issues? I decided I’d make her a webpage. I Yahoo’d for webpage making instructions and promptly preOne of the tricky parts of HTML5 is how varied its sented my mum with her digital gift. As soon as my support is. It’s not like with a usual API, where you dad saw that I was interested in programming, he can say “all features from version X onwards are spurred me on to learn more (real) languages like supported” instead, you have this situation where Perl and Java. From then on, I was hooked, and the each browser supports a different subset of fearest is history. tures. Even the oft-maligned IE supports some features that other browsers don’t - it’s not behind on How did you come to select PhoneGap for your everything. Worse, even when a browser technically supports an HTML5 feature, it may still perform mobile app strategy? How many other mobile app quite badly with it, like in the case of the Android platforms did you review in the process? Webkit browser and CSS3 gradients. In deciding how to build the mobile apps for EatDifferent, my goal was re-usability. I wanted to reuse as much of my app logic and assets as possible, and I wanted to re-use as much of my existing web development knowledge as possible. I didn’t want to start from scratch on either front, and didn’t feel like I had the time or motivation to become an expert Android Java and Apple iOS developer. So, I went with PhoneGap and I achieved my goal of reusability - about 90% of my code is shared across the web and mobile apps, and that means it’s easier for me to add new features to all the platforms at once. So, if you’re a developer trying to use HTML5, you need to use something like Modernizr to check whether a feature exists, you need to use libraries that abstract on top of the feature across the different browsers, and you need to actually test your app in all the browsers and see both if it works and if it works fast enough. Two invaluable resources for HTML5 developers are the Modernizr wiki on HTML5 polyfills (https:// github.com/Modernizr/Modernizr/wiki/HTML5Cross-browser-Polyfills) and caniuse.com with upto-date browser support tables.

81/83

Do you think that cross-platform development makes sense? When should you go native instead of using web standards? It depends. Are you building an app that a user would only want to access on a mobile device? Or is it an app that users would want to access everywhere? Does the app need to be usable by everyone to be useful, or can you use it by yourself or with strangers? An app like “Draw Something” is very mobile-specific - someone is bored, they have their phone, they start a game with some random other person, and they draw with their touch screen. It makes sense for them to go the native route, as they don’t have to target every platform, and they can then take advantage of native touch capabilities. But an app like Twitter needs to be cross-platform - people want to tweet from everywhere, and they want to tweet with everyone. It makes sense for them to go the route of web standards, since they can then serve apps on any platform that has a web browser and a way of entering text, and they don’t need to worry about excluding users. I personally prefer apps that are accessible everywhere (I would totally “Draw Something” on my laptop), but each developer needs to decide for themselves how much to prioritize cross-platform development given their limited resources. You’ve had a number of different roles in the developer/IT world, what are some of the highlights that were most beneficial to giving you the perspective for where you are today?

Now that I’ve left that role and I’m a free-range developer, I can appreciate the perspective that developer relations has given me, and when I’m interacting with 3rd party APIs, I can put myself in their shoes. When I run into a bug, I try to actually post in their forum instead of simply ranting on Twitter, because I realize that they are busy too and they can get it fixed faster if it’s reported properly. Before I make a feature request, I try to think to myself whether that request is actually in line with their core mission and will be sustainable for them, and not just a niche request that would only satsify me. Basically, by being able to balance both perspectives in my head, I can be a more productive and useful developer of a 3rd party API. We’ve been hearing a lot lately about User Experience. Can you share your thoughts on Developer Experience? How important is it, really, for companies, such as Facebook and others enjoying their view from the top, to provide a good developer experience with their APIs? We’re now in a time when there are many companies out there that are purely dedicated to developer products - hosting platforms like Heroku and App-Forge, functional APIs like SendGrid and Twilio, services like Loggly and Pingdom. For those companies, their success depends solely on the success of their developer products, so they need to provide the best developer experience possible... and they generally do. But there are also many companies that provide both user-facing products and developer-facing products. Sometimes, the success of the user product is directly dependent on the success of the developer product. For example, Twitter might not be as popular as it is today if there weren’t so many alternative, 3rd-party clients built for it.

Actually, I’ve technically only had one job in my life: Google Developer Relations. But, that job was probably the best possible job that I could get in terms of how much I learnt across so many different aspects. There was the technical knowledge: JavaScript, Maps/GIS, Flex, Python, App Engine, NonBut othertimes, it’s not obvious how much the user Relational Datastores, and even a bit of Java. But product depends on the developer product. Would even more valuable was the not so tangible Facebook still be the world’s biggest soknowledge: how to deal with developers in cial network today if they didn’t provide a community (the good, the bad, the ugly), “My first applet an API? Quite possibly, yes. And unforhow to prioritize feature requests, how to tunately, when a company is in the posiwas a virtual handle a bug that breaks thousands of tion of owning the social graph on the sites, how to organize events, how to write dress-up doll...” web and they’re the only ones that can the most universally useful documentation, provide a reasonable API to that social how to give entertaining yet educational graph, then social app developers don’t really have talks, the list goes on. a choice but to use the Facebook API, regardless Developer Relations is a mix of many jobs in one - something like 10% software engineer, 30% support engineer, 30% community manager, 20% evangelist, 10% product manager. It’s a great role for someone starting out because it exposes you to everything at once, and it can help you figure out what aspects you like the most. And hey, if you like it all, you can work in developer relations for life. of the developer experience. Facebook has a monopoly, and they know it.

But, hey, if a company comes along that has a reasonable slice of the social pie and provides an amazing developer experience for their social graph API, they may be able to compete with Facebook. The web moves fast, we’ll see!
82/83

How do you perceive Adobe and the work it has done in creating tools for developers now and throughout the years?

Okay, so I’m going to steal the next 2 questions from your interview with your mum, What was the first line of code you ever wrote? That depends if we’re counting HTML as “code”... Asssuming not, my first script was a Mad Libs game written in Perl. My dad and I celebrated one New Years eve by writing the script, and running it just as the clock struck midnight. Yes, I come from a geeky family.

Now that I think about it, I’ve been using Adobe or Adobe-acquired products since I was a kid, though not always for programming. When I was in middle school, I used to draw advertisements for my parent’s college classes using Aldus Freehand, the vector drawing program. In high school, I used AdoSo, in that case, my first line was probably: be Pagemaker and InDesign to layout the school #!/usr/local/bin/perl newspaper. At computer camp one summer, I discovered Adobe Flash and started making animations and Flash websites (and yes, they had aweHow do you think the fundamental differences in men and women play out in the IT industry? some intros). In college, I minored in 3-D animation and continued using Flash for animations and fun Well, I think it’s good to clarify that there are aclittle web toys, plus spent a year using PhotoShop tually fundamental differences between men and as a graphic designer for our on-campus events. women. It seems like people try to pretend that At Google, I was working on the Maps API team we’re the same in all regards, but we’re not. We when they came out with the Maps API for Flash, evolved to be optimized for different tasks, both which was significantly more powerful than the Jaour minds and bodies. vaScript API in many ways at that time, and I spent a year Men are generally better at math, seeing what I could do in Flex/ women are generally better with Pam’s Pam’s Eat AS4. And now, I’m using the people - so in the IT industry, you’ll Blog Projects often find men playing the part of Different recently acquired PhoneGap for building mobile web apps. the engineer and women playing the part of the community managSo, wow, I think Adobe has er. If we want to see more women in the engineer been with me more than any other company, and role, then perhaps one way is to show women that curiously, the Adobe line of products has evolved engineering isn’t *just* math. at the same rate as my personal interests. But now the web is moving faster and faster while Adobe is For example, I first learnt programming via Java getting bigger, so... applets, and my first applet was a virtual dress-up doll that I uploaded and shared with my friends. To me, programming wasn’t about math, it was about In what ways is there still work to be done to make making apps that people could interact with, and HTML5 a valid solution for developing applications? that’s what was so cool about it. When it comes to using HTML5 for making mobile web applications, we’re in need of better, faster debugging tools. We now have really amazing developer tools for desktop debugging, particularly in Chrome and Firefox, but when it comes to mobile, it sometimes feel like debugging in IE6. There are a few tools for remote debugging, like weinre and iOS remote inspector, and there’s talk of better Webkit remote debugging in the future (http:// www.webkit.org/blog/1875/announcing-remotedebugging-protocol-v1-0/), but they’re still not on par with desktop tools - and there are times when all you can do is console.log or even alert. We also need a better testing solution for mobile web apps. We have great ways of running integration tests in the browser on our desktop, using tools like Selenium, but we’re not quite there when it comes to mobile (particularly mobile apps with embedded browser views, like PhoneGap). Once again, there are developers working on this, so there’s hope for the (near?) future. So, when I teach people how to program, I try to show them the many ways that it can be used, because you never know what their mind will be most excited by. And I think that’s how we can increase the diversity of the IT industry. Or one way, at least. What would you like to shout out to the developer world for a successful 2012? We all want to make the world a better place somehow, whether that means making an app that lets people play games with their friends or making an app that improves government efficiency. The faster we can make those apps, the faster we can reach our own idea of what a better world looks like. We can all make it easier for each other to build what we want if we share our knowledge and our code with eachother. So, please, when you learn something: share it, and when you write a bit of useful, reusable code: opensource it. Sharing is caring. :)

appliness

IS A WARM GUN

W

e want to showcase in this section the best mobile applications built with web standards. If you want to showcase your application, contact us by email - contact@appliness.net. This month, find clothes that match your tastes, discover cuuuuuute animals and build muscle thanks to PhoneGap.

Colour Match

by Anansi Web Development
The purpose of the app is to allow users to pick any colour using a colour picker tool and display clothing & accessories that match the colour from Online Shopping USA database. Features of the app include a colour picker, a selection of most popular colours for easy browsing, favourites where users can save their favourite products and email, facebook and twitter sharing. Anansi used jQuery Mobile 1.0.1, PhoneGap and PHP for the backend. They used three native APIs provided by PhoneGap: Twitter, ChildBrowser and the EmailComposer. It took about 4 weeks from the start of the project to the day the app became available on iTunes app store. Great performance and great design.

(

“The colour picker works very well. Good usage of jQuery Mobile.”
84/85

Michaël

Christophe

Piotr

Cutest Paw
by Ho Man Cheung
Cutest Paw iPhone App is designed for those who love to see new cute animal pictures everyday. You will love the seamless way we display the pictures on your iPhone. User can search the cute animal pictures by keywords or categories. User can register a new account, and login to upload their cute animal pictures. You can take a picture or choose any pictures from your photo library. You can also track your uploaded pictures. Oh my god! It’s so CUUUUUTE. The main screen is incredibly beautiful. A dynamic compisiting that really make a difference. The developer used jQuery Mobile and PhoneGap.

“I was surprised at how much of a distraction this turned out to be. Great job!”
Holly Greg Alan

Bit Timer
by Peiter Buick
This app is designed for the no-frills, hard-core workout. This is the first interval timer you’ll see with a set up that is this fast and easy. Your workout should be intense, not your workout set up. The clean design and simplicity of Bit Timer make it the perfect app for exercise enthusiasts. One of the best feature is that music automatically fades, allowing you to hear interval tones. The app uses smart drag and drop gestures to define the Work, Rest and Repeat parameters. The developers used PhoneGap to control the sound of the device.

Greg

Andy

Michaël

“As a techie who enjoys some cycling, this is app is a must-have!”

WHICH ELEMENT ?

One of the main challenges we see in building semantic content is picking what tag to use when. WhichElement.com seeks to help with that. Now, lest we seem all judgy and preachy let me get a few beliefs out there: - A perfectly semantic site does not exist. - Even if it did, someone would disagree with its semantics. - Therefore semantics for semantic’s sake is pointless.

However, semantics are about more than just semantics for semantic’s sake. Semantics can be about accessibility, SEO, or just good developer to developer communication of intent. They can be used to create better hooks for CSS and DOM manipulation. Therefore we approach this site with the following in mind:

- Semantics exist along a continuum, something can be more or less semantic. - We encourage semantics, but not at the cost of reasonableless.

Our goal is to suggest things to help you make a good decision about what you should do to be semantic. We certainly don’t think we have any authority to command you to do things to be absolutely semantic. by Terry Rian and Ray Camden Visit WhichElement.com

? . . . . . . .

<aside> or <blockquote> ?

Pull Quote

A pull quote is a fluffed up copy of a bit of the content on the current page. It’s usually bigger and more visually distinctive than the rest of the body copy. A pull quote in most cases is used to emphasize a theme or point of a piece. The idea is that by presenting this block quote, readers can determine more quickly if they want to read the piece. It’s a stylistic addition to a page that emphasizes content without actually adding concrete content.

Candidates
- <aside> - <blockquote> - Highlighted with CSS and HTML5, no semantic reference. The first issue to clear is, Is this a quote or a pull quote? An easy rule of thumb here is “If you are repeating something that is on this exact page, it’s pull quote”. Since it is not a quote, <blockquote> is inappropriate. The W3C specifically points out in their definition of <aside> that is intended for pull quotes: “The element can be used for typographical effects like pull quotes or sidebars, for advertising, for groups of nav elements, and for other content that is considered separate from the main content of the page.”

86/87

That should be an open and shut case. Shouldn’t it?

However Maykel Loomans makes a great case in his article Pull Quotes with HTML5 and CSS that pull quotes are a display issue and not a content issue. If you buy into it, it means adding extra markup, and repeating content just to show a pull quote is semantically wrong. He makes a compelling case for it, and has an awesome solution. Just using HTML5 and CSS to style a pull quote. The article is great reading.

Verdict

The semantic nitpicker in me loves to point to Highlighted with CSS and HTML5. It might be a little kludgy on the CSS side but from a semantic and content point of view, it’s very elegant. That being said, the W3C says you can use <aside> which might be a bit more flexible in terms of styling.

Further Reading
Wikipedia > Pull Quote

Smashing Magazine > Block Quotes and Pull Quotes W3C > The aside element

Maykel Loomans on design, the web and other stuff nerds like > Pull Quotes with HTML5 and CSS

? . . . . . . .
MORE INFORMATION

Comments

Comments are basically just big lists of individual comments.

Candidates
<div> <dl> <ol> <section> <ul>

At first glace, one of the lists makes a good candidate. This is a big honkin’ list of comments. Semantically, the <ol> makes a strong showing as comments are usually listed in chronological order. You can choose to have the numbers part of the display of the items or style them away. Note, however, that it is hard to style the <ol> numbers independent of the text. It can be done, but involves adding more elements to the content. The <ul> is also a reasonable choice here. The <dl> might be semantically correct, but seems like you’re just showing off your use of obscure elements. Not that there is anything wrong with that. You could go with a <div>. The w3c discourages using a <div> when there is a more specific element to use, and in this case you have several. A <section> refers to a group of related bits of content. A list of comments in a blog definately fit the bill.

Verdict
We recomend the <section>, containing either <ul> or <ol>.

Further Reading
Macrofolio > Style your lists

>

>

appliness

VIDEO TUTORIAL

phonegap and the file api

raymond camden demonstrates how to use the html5 file API with phonegap to start working with the file systems of mobile devices.

P

d n u o laygr

(

- PhoneGap m e t s y S e l i F - Storage

Difficulty
- rookie - intermediate - expert

Todo list
- store stuff - read & write - shave
by Raymond Camden

appliness

VISUAL AND JUICY

DECISION PATH TO PHONEGAP

in this article, i won’t explain what is phonegap. I’ll focus on where this technology fits in the mobile solutions landscape and when phonegap is relevant.

(

MOBILE

GROWING

WEB

IS

2013

2012

“First, you need to choose the userexperience for your app. A classic page by page navigation or an application UX with tabs, footers...”

?

x
Which mobile user-experience do you need?

8

“The mobile Web is growing eight times the speed of the Internet”

Classic Web UX
Links, Pages, navigation, text & images

ANSWERS

Application UX
Menu, Header, buttons, footer, tabs

- Responsive Design - Progressive enhancement - HTML5 & CSS3

ANSWERS

3

“There are three ways to code a mobile app user experience, inside or outside the browser.”

Web-app
DESCRIPTION

Hybrid
Hybrid apps are executed in the web view component of a native app (think of a headless browser). The app is coded with webStandard (HTML5, JS...). Hybrid apps are distributed as native apps on market places.

Native
A native application is coded with the native language of the mobile operating system (ObjectiveC for iOS, Java for Android...)

A Wep-app is executed in the browser of the mobile device. It’s coded with web standards (HTML5, JS...)

ACCESS

To access a web-app, the user launches the web browser and types a URL.

Native apps are distributed on market places (app store, google play, appWorld...).

LIMITATION

Very limited access to HW features and APIs. You can’t take a picture, store persistant data...

Full access to HW fea- Full access to HW and tures and APIs thanks native APIs. to native extensions (or plug-ins). The developer calls the native APIs with JavaScript commands. Developers need couple a mobile HTML framework (jQuery Mobile) and a mobile container framework such as PhoneGap to access native APIs with JS. Each platform provides specific SDK and IDE: ObjectiveC and Xcode for iOS, Java and Eclipse for Android...

SOLUTIONS

Developers need to use a mobile HTML framework such as jQuery Mobile.

?
GAME
inspired by Emmanuel le Valensi

Hybrid apps look cool. So what’s the most challenging step?

“In my opinion, the biggest challenge is to find a HTML framework that will simulate the user-experience of a native app. jQuery Mobile is a good candidate. Then, PhoneGap will expose native APIs in JavaScript (take a picture, accelerometer, File API...) and run your HTML code in a web-view (a kind of headless browser).”

WHICH ONE IS NATIVE, HYBRID OR A WEB APP ?

PATH

FACEBOOK

LINKEDIN

same?

?

These 3 mobile apps have very similar user-experiences. They are all using application UI patters: menu, header, icons, tabs... But just one of them is native and written with ObjectiveC. It’s “Path”, one of the most beautiful social application. Facebook is Hybrid, it has been written with HTML and JS. They used a distribution of PhoneGap to run it as a mobile application outside the browser and distribute it on app stores. LinkedIn is a pure web application. A wonderful HTML development that you can try on mobile. linkedin.com. That said, they just released an Hybrid app too. They just had to reuse their existing HTML code and package it as an mobile app with a technology such as PhoneGap.

What is PhoneGap?

a set of UI components to build mobile apps with HTML and JS

PhoneGap crosscompiles HTML and JS code to native code

a platform that allows you to author native applications with web standards

= Hybrid

a hack to the mobile web browsers to call native APIs

Workflow
Build your app once with web-standards
Based on HTML5, PhoneGap leverages web technologies developers already know best... HTML and JavaScript. Pick the HTML framework of your choice (jQuery Mobile, Sencha Touch...) and build your application. At the end, your HTML app must look like a native one.

to build hybrid apps
Wrap it with PhoneGap
Using the free open source framework or PhoneGap build you can get access to native APIs: access to the camera, to the accelerometer, to the list of contacts, to the File API... APIs that are not available in the mobile web browser

Deploy to multiple platforms!
PhoneGap uses standards-based web technologies to bridge web applications and mobile devices. You can deploy your application on iOS, Android, Windows Mobile, Bada, BlackBerry, WebOS and Symbian!!!

P

d n u o laygr

s p p a d i r b y - H p a G e n o h P - Browser

Difficulty
- rookie - intermediate - expert

Todo list
- user XP - Xcode - Xplatform
by Michaël Chaize

appliness

WTFJS?!*%

WTFJS!!! false advertising
HEY DUDE

JavaScript is a language we love despite it giving us so much to hate. wtfjs.com by brian leroux is a collection of those very special irregularities, inconsistencies and just plain painfully unintuitive moments for the language of the web.

Answer: do you think this constructor returns for new Dude(‘Bob’)? Doug or Bob? function Dude(name){ this.name = name; return {name: ‘Doug’}; } Answer: var bob = new Dude(‘Bob’); // { name: ‘Doug’ } bob instanceof Dude // false Huh!? So you can just slip in anything? What about arrays? function Dude(name){ this.name = name; return [1, 2, 3]; } new Dude(‘Bob’); // [1, 2, 3] That can’t be! What about... function Dude(name){ this.name = name; return 3; } new Dude(‘Bob’); // { name: ‘Bob’ } Wah? No way! So, if you try to return a primitive type from a constructor(number, string, date), it will ignore the return value and return the originally initialized object, but otherwise, the returned value overrides.

P

d n u o laygr

(

t - JavaScrip - Array - Objects

Difficulty
- rookie - intermediate - expert

Todo list
- laugh - have fun - sleep

by Toby Ho

appliness

BLEEDING EDGE

(

Generating Color Palettes from HTML5 Video
CRAZY RAY WILL SHOW YOU HOW TO USE YOUR WEBCAM and webrtc to define a color scheme. very creative.

One of the more interesting aspects of PhoneGap development is that the features it provides open up interesting possibilities when combined with other products. So for example, you can combine PhoneGap’s camera support with existing JavaScript libraries that manipulate images. HTML5 is much the same way. By broadening what the browser can do, all of a sudden you see multiple new opportunities for mashups and unique new creations. Today I’m going to demonstrate one simple example of this. I mentioned PhoneGap earlier because these particular demos are based on an earlier application I built that utilized an excellent JavaScript library called Color Thief. Color Thief gives you the ability to examine images and determine either the dominant color or get a palette of prominent colors. For my PhoneGap application, I made use of the Camera API to allow you to take pictures and generate a color palette from the result. I thought it might be interesting to apply similar logic to a desktop application making use of live video streams. In order to test this you will have to use Chrome 19 (still in beta) or higher and you must enabled WebRTC. WebRTC is a project aimed at giving browsers a way to perform real time communication with other clients. It involves quite a bit of moving parts and is very much a work in progress, but you can begin experimenting with it now. Note that before you do so, you must enable the feature. Details on how this is done may be found here: Testing WebRTC on Chrome. The first demo makes use of the web cam and combines it with the ColorThief library to provide a “live” view of the colors from the camera. You have a screenshot of my demo on the left.

91/95

This code is based on a simple demo by Greg Miernicki. Let’s look at the code, and then I’ll explain what’s happening.
<!DOCTYPE html> <html> <head> <script src=”js/jquery-1.6.2.min.js”></script> <script src=”js/quantize.js”></script> <script src=”js/color-thief.js”></script> <script> $(document).ready(function() { if(!navigator.webkitGetUserMedia) return; navigator.webkitGetUserMedia(‘video’, gotStream, noStream); var video = $(“#monitor”)[0]; var canvas = $(“#tempCanvas”)[0]; var img = $(“#tempImage”); img.load(function() { console.log(“load”); try { var p = createPalette(img,5); for(var i=0; i<p.length; i++) { $(“#p”+i).css(“background-color”,”rgb(“+p[i][0]+”,”+p[i][1]+”,”+p[i] [2]+”)”); } var dom = getDominantColor(img); $(“#domColor”).css(“background-color”,”rgb(“+dom[0]+”,”+dom[1]+”,”+d om[2]+”)”) } catch(e) {}; setTimeout(doSnapShot,1500); }); function gotStream(stream) { video.src = webkitURL.createObjectURL(stream); setTimeout(doSnapShot, 1500); video.onerror = function () { stream.stop(); streamError(); }; } function noStream() { document.getElementById(‘errorMessage’).textContent = ‘No camera available.’; } function streamError() { document.getElementById(‘errorMessage’).textContent = ‘Camera error.’; }
more on next page
92/95

function doSnapShot() { canvas.width = video.videoWidth; canvas.height = video.videoHeight; canvas.getContext(‘2d’).drawImage(video, 0, 0); img.attr(“src”,canvas.toDataURL()); } }) </script> <style> #monitor { width:640px; height:480px; } #tempCanvas, #tempImage { width: 640px; height: 480px; position:absolute; left:-1000px; top:-1000px; } div#domColor { width: 640px; height:50px; } div#palette { width: 640px; } div#palette div { width:20%; height:50px; float:left; } </style> </head> <body> <div id=”errorMessage”></div> <video id=”monitor” autoplay></video> <div id=”domColor”></div> <div id=”palette”> <div id=”p0”></div><div id=”p1”></div><div id=”p2”></div><div id=”p3”></div><div id=”p4”></div> </div> <canvas id=”tempCanvas”></canvas> <img id=”tempImage”></img> </body> </html>

93/95

There’s quite a bit here, so let’s tackle it in pieces. First - notice our jQuery $(document).ready block checks to see if the feature, webkitGetUserMedia, exists, and if not, immediately leaves. Normally I’d present some form of message to the user. Being a proof of concept though we can be mean like that. The magic begins with a request for the web cam. This is as simple as: navigator.webkitGetUserMedia(‘video’, gotStream, noStream); noStream is a simple error handler, so let’s focus on gotStream. gotStream handles two distinct things. First, it hands off the video data from the media stream to the actual video tag we have in the DOM. Secondly, it automatically runs a function, doSnapShot. That function then handles getting a “still” from the video source and drawing it to a canvas. (And again, I want to credit Greg Miernicki. All of this logic comes from his demo.) Here’s where things get interesting. Once we have an image, we can use ColorThief on it. But ColorThief only works on fully loaded images. You’ll notice we write to an image addressed by the JavaScript variable “img”. This was set earlier in a jQuery selector. Because I’ve got a handle to the image object in the DOM, I can attach an event handler specifically for the load event of the image. Once a load event occurs, I then turn to ColorThief. I mentioned earlier that it supports getting both a dominant color as well as a palette of used colors. I call both of those and draw them out to some divs below the video. Note the use of try/catch. I encountered errors with ColorThief when it first started hitting the video so I simply try/catch to avoid the initial problem. By the way - why the use of setTimeout - and why 1500 milliseconds? Because ColorThief has quite a bit of work to do, I thought it best to go for “slightly slower than real time” updating. Obviously this could be tweaked a bit. Another issue is the use of the image passed to ColorThief. I use CSS to hide this image offscreen. If you look at the source of ColorThief though you will see it actually creates a canvas out of the image. So I’ve actually got a canvas item sourcing an image sourcing a canvas. That could be optimized. So while running this demo and noticing the colors seemed pleasant (entirely due to my snazzy clothing selections), I wondered what could be done with this on a bigger scale. Remember how we hid the image used to source the color operations? What if we hid everything! Why? Imagine a web site that changes its main theme based on what you wore. That’s a bit over the top - but possible. Consider the following simple Bootstrap based site on the next page:

94/95

>
By grabbing the webcam again and selecting the dominant color, you can end up with something like the screenshot on the right. Of course, this assumes a user wearing a bright red shit - I used a handy Imperial Guard action figure I had nearby . The code for this version is much like the previous one - but simply uses jQuery to update Bootstrap CSS: img.load(function() { try { var dom = getDominantColor(img); $(“.navbar-inner”).css({“background-image”:”none”,”backgroundcolor”:”rgb(“+dom[0]+”,”+dom[1]+”,”+dom[2]+”)”}); om[2]+”)”}); $(“h1,h2,p”).css({“color”:”rgb(“+dom[0]+”,”+dom[1]+”,”+d

} catch(e) {}; setTimeout(doSnapShot,1500); });

Obviously this is a bit of a contrived example, but the idea is that once you have access to the web cam, there’s the possibility of doing much more than chat or taking silly pictures.

ABOUT THIS ARTICLE
Meet Raymond Camden. He is a 38 year old married father of three living in beautiful Lafayette, Louisiana. Ray is a developer evangelist for Adobe where his primary technical focus is ColdFusion, jQuery, Flex, AIR and the mobile space. http://raymondcamden.com/ @cfjedimaster

ONLINE RESOURCES Color Thief http://lokeshdhakar.com/projects/color-thief/ Ray’s blog http://raymondcamden.com/ WebRTC http://webrtc.org/

appliness

BLEEDING EDGE

(

Thanks to Molly Holzschlag’s tweet, I learned there was an Editor’s Draft of CSS Variables.

CSS VARIABLES DRAFT

Let me first say that I think it’s awesome that the W3C is taking this on. I think that variables in CSS will ultimately be a good thing. It will make it easy to reuse colors and other CSS properties. It will make large amounts of redundancy go away. It will make CSS files smaller, and therefore give less toehold to bugs. That being said, I have a major complaint with the implementation of--in a word “data.” See, here is how CSS variables are supposed to work according to the draft. I create a property in the root named “data-header-color.” :root { data-header-color: #06c; }
This Gist brought to you by Github variableset.css view raw

Then to refer to that color elsewhere, I use a construct that looks like a function named “data()” to retrieve it as so: h1 { background-color: data(header-color); }
This Gist brought to you by Github variableget.css view raw

96/98

As far as I can tell, the only explanation in the draft for why this is, is that it is trying to match the HTML specification for “data”: The naming here is loosely based on the form of custom data attributes in HTML5. However, as defined here, the syntax for variable usage is different from the syntax for variable definition (i.e. data-foo for definition, data(foo) for usage). Some have suggested that the syntaxes should should match, using functional syntax in both cases. Others have suggested using a prefixed symbol instead of functional syntax (e.g. $foo) for both the property and usage. Well at least they are aware that some might object to this format. So let me add my voice. I object. Variables are a pretty standard construct, people know how they work. Make them work like variables in other languages. I have a bunch of reasons here: • Two different syntaxes for creation and consumption seems confusing. • It looks like you’re calling a function, but you’re not. You’re referring to a variable. That’s confusing. • CSS and HTML don’t have a lot of overlap in syntax, why is adding some a good thing? My preference here is that I can just use plain old words as a variable, then consume them as plain old words. That being said, I would be okay with a prefixed symbol, like a $ if it comes down to some sort of parsing issue. That’s my major problem with the draft, but I have one other issue with the behavior on invalid variables. Like if you set the margin to #FFFFFF. Basically if you have this code:

p { background-color: red; } p { background-color: “Behold I am not a valid color at ALL!!!!” }
This Gist brought to you by Github errorwithoutvariables.css view raw

Then the p comes out as red, but if you have this code:

:root { data-not-a-color: “Behold I am not a valid color at ALL!!!!” } p { background-color: red; } p { background-color: data(not-a-color); }
This Gist brought to you by Github errorwithvariables.css view raw

The p comes out transparent. This sort of change in behavior might be pretty confusing. The explanation makes some sense: The invalid at computed-value time concept exists because variables can’t “fail early” like other syntax errors can, so by the time the user agent realizes a property value is invalid, it’s already thrown away the other cascaded values. I think “attr()” needs to rely on it as well, as its behavior is almost identical to variables.

97/98

But I imagine this is something that browser manufacturers can handle as they control the behavior of “throw[ing] away the other cascaded values.” They could hold on to cascaded values until they are done computing variables. But maybe I’m missing something here. But it’s also worth considering if this will make invalid CSS easier to track down. I doubt it, but until a browser implements these, it will be hard to determine if that is true. Anyway. The good news here is that this is the editor’s draft, not the recommendation. This means that now is the time to start analyzing this spec and commenting on it. So what do you think?

Aside on W3C Drafts It’s important to note that a “Working Draft” is a pretty early stage of the W3C recommendation process. W3C follows these steps when advancing a technical report to Recommendation. 1. Publication of the First Public Working Draft. 2. Last Call announcement. 3. Call for Implementations. 4. Call for Review of a Proposed Recommendation. 5. Publication as a Recommendation.

I believe we are between steps 1 and 2 at the moment. Also relevant: Purpose: The publication of the First Public Working Draft is a signal to the community to begin reviewing the document. So to be clear, we’re supposed to be commenting at this stage.

ABOUT THIS ARTICLE
Terrence Ryan is a Worldwide Developer Evangelist for Adobe. His job basically entails traveling the world and talking about the developer tools and technologies that Adobe has to offer or that evangelists support. To find out more, see about his Job. http://www.terrenceryan.com/ @tpryan

ONLINE RESOURCES
Editor’s Draft of CSS Variables http://dev.w3.org/csswg/css-variables/ HTML Specification for “data” http://www.whatwg.org/specs/web-apps/... CSS Variables Draft Comments https://gist.github.com/2136922 98/98

appliness

HELTER SKELTER NEWS

Fresh news about HTML and Javascript collected by Brian Rinaldi - remotesynthesis.com
WebStorage: Persistent client side data storage. via John Allsopp Experimenting with CSS Exclusions. via Ryan Stewart How to do content folding for your responsive web design using CSS Regions. via Chris Coyier

(

What is the meaning of this? via Douglas Crockford Device-agnostic and content-centric approach to responsive web design. via Thierry Koblentz How to create the popular “infinite scroll pagination” effect using jQuery via Mohd Hadihaizil Din

How to make Dreamweaver add code coloring and hinting with the Sass and Less CSS preprocessors via Greg Rewis

Tutorial on Underscore.js via Siddharth

How to create an Autocomplete in jQuery Mobile by Ray Camden

appliness

HELTER SKELTER NEWS

(

Toying With the HTML5 File System API via Ivaylo Gerchev Build animated CSS3 content tabs. via Ring Wing Understanding MVVM - A Guide For JavaScript Developers via Addy Osmani

Stop Nesting Functions! (But Not All of Them) via Jeremy McPeak Extending JavaScript – The Right Way. via websanova

DIRECTION-AWARE HOVER EFFECT WITH CSS3 AND JQUERY via MARY LOU

JavaScript motion detection via Romuald Quantin

Persisting Backbone Collections via Eric Feminella Object types in JavaScript by Keith Peters

MORE NEWS ON remotesynthesis.com

appliness

THE TEAM
Contribute and join Appliness

(

Appliness is a free digital magazine edited by passionate web developers. We are looking for contributors. Contact us and join the adventure. You’ll find on our website appliness.com a feedback form. You can also follow us on twitter, facebook and Google+.

MICHAEL
Michaël Chaize is a Developer Evangelist at Adobe where he focuses on Rich Internet Application and Mobile applications. Based in Paris, he works with large accounts that need to understand the benefits of rich user interfaces, leverage the existing back-ends to add a rich presentation layer and measure the impact on the existing IT teams. He believes that intuitive user experiences in the Enterprise are key to successful developments of effective, efficient, engaging, easy to learn and error free applications. Before joining Adobe, Michael founded a software company and taught RIA languages such as Flex and PHP in IT engineering schools. He’s the editor in chief of Appliness.

CHAIZE

R AY M O N D

Meet Raymond Camden. He is a 38 year old married father of three living in beautiful Lafayette, Louisiana. Ray is a developer evangelist for Adobe where his primary technical focus is ColdFusion, jQuery, Flex, AIR and the mobile space. He’s been invited to speak at many conferences over the years, including CFUNITED and Adobe MAX .

CAMDEN

IAN CHRISTOPHE
Christophe is a Developer Evangelist for Adobe where he focuses on Web Standards, Mobile, and Rich HTML Applications with a special focus on Enterprise Integration. In this role, Christophe has helped some of the largest financial services companies design, architect and implement some of their most mission critical applications. He was one of the initial members of the Flex Product Team in 2003. In his previous role at Macromedia, Christophe worked on JRun, the company’s J2EE application server. Before joining Macromedia, Christophe was managing Java and Internet Applications Evangelism at Sybase and Powersoft. Christophe has been a regular speaker at conferences worldwide for the last 15 years.

COENRAETS

Ian Devlin is an Irish web developer, blogger, and author who enjoys coding and writing about emerging web technologies such as HTML5 and CSS3. In addition to front-end development, Ian also builds solutions with back-end technologies such as .NET and PHP. He has recently written a book titled HTML5 Multimedia: Develop and Design.

DEVLIN

K

Keith has been programming professionally for over a decade and as a hobby for a while longer. He has written or contributed to a dozen books on programming and maintains his personal site at www. bit-101.com.

PETERS

E

I

T

H

B R I A N
Brian Rinaldi is as a Content and Community Manager for the Adobe Developer Center team, where he helps drive content strategy for HTML5 and JavaScript developer content. Brian blogs regularly at http://remotesynthesis.comand and is a unreformed twitter addict.

RINALDI

He lives near Boston, MA in the USA, and is the Engineering Guru at Infrared5.

T E R R E NC E
Terrence Ryan is a Worldwide Developer Evangelist for Adobe. His job basically entails traveling the world and talking about the developer tools and technologies that Adobe has to offer or that evangelists support.

R Y A N

R

Ryan Stewart is a Web Developer Evangelist for Adobe Systems. After graduating from the University of Pennsylvania with a degree in Economics he started on the Flash Platform by building eLearning rich Internet applications in Flex 1.5 and ColdFusion 7 for the Wharton School of Business. He is a long time blogger and had a prominent blog on ZDNet where he covered all sides of rich Internet applications. He has spoken at a number of industry conferences including Web 2.0 Expo, Adobe MAX, 360|Flex, SXSW, PHP Tek, and Web Design World. When not working with the latest Adobe technology you can find him in Seattle where he enjoys making beer, mountaineering, and spending as much time as possible in the outdoors.

STEWART

Y

A

N

A N D R E W
Andrew Trice is a Technical Evangelist with Adobe Systems. Andrew brings to the table more than a decade of experience designing, implementing, and delivering rich applications for the web, desktop, and mobile devices. He is an experienced architect, team leader, accomplished speaker, and published author, specializing in object oriented principles, mobile development, realtime data systems, GIS, and data visualization.

T R I C E

M A I L E
Maile is the assistant editor for Appliness magazine and has worked with Adobe both as an employee and consultant for 8 years now. Mailestarted with Adobe on the Technical Marketing team as a technical trainer for the Adobe LiveCycle Enterprise Suite (most recently Adobe Digital Enterprise Platform). She then went on to work with the Adobe Enterprise Evangelist team to support great Flex developer resources such as Tour de Flex and Flex.org. Maile is excited to jump into the world of digital publishing and dig deeper into leading edge HTML and related technologies.

VALENTINE

G

Greg is a Developer Evangelist at Adobe Systems focusing on the use of Adobe technologies in enterprise applications. Technologies include HTML, JavaScript and related technologies, Flex, AIR, data services, digital publishing, and anything mobile, tablet and desktop app development related. Prior to joining Adobe, Greg architected and developed many largescale applications at Verizon, Motorola, NASA/Boeing and others.

W I LS O N

R

E

G

Appliness is a digital magazine written by passionate web developers. You can follow our activity on Facebook, Twitter or Google+.

O W FO LL
o t t n a w ? u e Yo ribut t n co

U S

If you want to contribute writing articles or showcasing your app, feel free to contact us. We are permanently looking for new contributions and content to cover all the aspect of application development with web standards. We are also opened to suggestions. The “Give us feedback” form on our website is the best way to contact the team.

GIVE US FEEDBACK

CLICK HERE TO CONTACT US

CO

N

TR I

BU

TE