23
Sep
This entry is part 1 of 5 in the series HTML5 Series

Welcome to the series on HTML5 development brought to you by the team at Xoriant.

HTML5 has been in the news of late and it promises to help deliver the next set of web applications with features that closely resemble some top of the line desktop applications.

This series will focus on demonstrating a feature of HTML5 with emphasis on a short working example. The idea is to introduce to you what your applications could gain by using HTML5 today. We will focus less on controversial stuff like Flash v/s HTML5 and instead focus on the features. As a developer, you are the best judge of using the technology in your applications today by looking at all factors. We will focus particular on bringing these experiences to mobile web applications, where the Webkit based browsers on most Smart phones today are more than capable of supporting several HTML5 features.

All you need is a text editor (or your favorite IDE), a Web Server (maybe) and a HTML5 compliant browser (more on that later).

Ready, Set … Lets Go!

Which Browser?

First, a word about the browser support for HTML5. To summarize in brief, HTML5 support has been announced in most browsers and all of them support core features, though several features present in the specification are still not implemented. With the announcement of IE9 Beta, HTML5 support has got a fillip in the IE world too, though Google Chrome presents your best bet at this point in time to try out some of the features.

Enter “The HTML5 Test”

A quick tip to figure out how well your browser supports HTML5 specification is to navigate to http://www.html5test.com. This will display a score about how well your browser supports HTML5. You should not worry too much about the score, rather there are 2 things that are particular important here and can actually act as a guide to your learning HTML5 and they are:

  • Check out all the features that are there in HTML5. Just a look at the number of features should get you excited about HTML5. Pick each of them up, refer to the web and learn about them. We will also be covering most of them in our series.
  • Once you have learnt about a particular feature and wish to see it work, check if your browser is supporting that feature of HTML5. If Yes – you are good to go. If not – you will need to wait.

A quick look at http://www.html5test.com in my browser (I am running Google Chrome 6.0.472.63 beta) shows that it does quite well.

html5test.com in Google Chrome browser

html5test.com in Google Chrome browser

Some assumptions

We will assume that our readers are familiar with developing basic web applications with HTML, JavaScript and a little bit of CSS. That will help you best to appreciate the new capabilities that HTML5 is bringing forth to the table.

What about Mobile Browsers?

The thing that excites us the most today is the fact that most Smart phones shipping today are equipped with the fantastic WebKit browser, which has great support for several HTML5 features. So if you have a Smart Phone, be it Android or the iPhone, you are all set. The other Smart Phone manufacturers including RIM and Nokia have also announced support for WebKit, so moving forward your application will be well placed to be functional on newer devices coming from them.

Where do we go from here?

Well, the question to ask should be “Where am I?” before we can go anywhere. And with that, we can look at the Geolocation APIs that are provided in HTML5. Geolocation is all about telling us where we are. In short, we will know the Latitude and Longitude, though it gives much more information than that like Altitude, Accuracy, etc.

To make sure that your browser supports Geolocation, point it to http://html5test.com and navigate below the Geolocation section, where you should see a score of 10 as shown below.

Browser supports Geolocation

In case there is no Geolocation support, which means the screen below:

Browser does not support Geolocation

Then I strongly suggest that you get either the latest version of Google Chrome or Firefox to see the example work. If not, you can still follow the article.

The code (geotest.html)

We will write a minimal piece of HTML code that is functional in nature and will access the Geolocation support in the browser and show the current Latitude and Longitude. First, take a look at the geotest.html file below:


<!DOCTYPE html>
<html>
<head>
<meta charset=”utf-8">
<title>HTML Geolocation Test</title>
<script type="text/javascript">

function findCurrentLocation(){
	var geoService = navigator.geolocation;
	if (geoService){
		geoService.getCurrentPosition(showCurrentLocation,errorHandler);
	} else {
		alert("Your Browser does not support Geolocation.");
	}
}

function showCurrentLocation(position){
	document.getElementById("mylocation").innerHTML = "Current Latitude : " + position.coords.latitude + " , Longitude : " + position.coords.longitude;
}

function errorHandler(error){
	  alert("Error while retrieving current position. Error code: " + error.code + ",Message: " + error.message);
}
</script>
</head>

<body>
<div id="main">
	<div id="mylocation"></div>
	<input type="button" value="Get Location" onclick="findCurrentLocation()"/>
</div>
</body>
</html>

Let us analyze the code which is rather straightforward:

1) Our body has a div element named mylocation, that we shall populate once we have the Latitude and Longitude.

2) We have a button, which when clicked calls the findCurrentLocation() method

3) The findCurrentLocation() method is where all the magic happens. The standard navigator object now has an object named geolocation. So, if your browser supports the geolocation object the navigator object will contain it. That is the first test we do. If there is no object then we display a standard alert informing the user that his/her browser does not support Geolocation.

4) If you do have support for the geolocation object, then all you need to do is invoke the getCurrentPosition method on it. The getCurrentPosition method takes 3 parameters:

  1. A success callback function
  2. An error callback function
  3. An optional parameters where you can provide some additional options to get the Current Position

5)  The success callback function in our case is the showCurrentPosition method. This method will get passed one parameter, an object of type Position. This object has two parameters, a property called timestamp and a property called coords that is an instance of type Coordinates. The coords object has several properties related to the current location like latitude, longtitude, altitude and several more. For our example, we are interested only in latitude and longitude.

6) The error callback function in our case is the errorHandler method. This method will get passed one parameter, an object of type PositionError. This object has two properties: code and message. The code is either 1 (PERMISSION_DENIED), 2(POSITION_UNAVAILABLE) or 3(TIMEOUT). The message is dependent on the device / machine browser.

7) We can leave out the 3rd optional parameter for now, since it is not fully supported on all browsers.

8)  So once the success callback function i.e. showCurrentPosition is invoked, we simply retrieve the latitude and longitude and populate the div with the results.

Our Geolocation Example in Action

We serve the geotest.html file via a local web server as shown below. Please note that I am using a latest version of Google Chrome browser.

Geolocation Example

Geolocation Example

When we click the Get Location button, we see that the browser prompts a warning message as shown below. This is important since it is recommended that all applications that deal with the location of the user should always allow the user to opt-in for sharing the location. It is good practice and strongly recommended, since it is a privacy issue and more users in the future will demand it.

Geolocation Example

Geolocation Example

If we click on Allow, you will find that it takes a little while (at times) to get the location and the current latitude and longitude are printed below.

Geolocation Example

Geolocation Example

Do note that since you allowed the browser to share the location, it has remembered that you have opted-in. On subsequent calls or even across browser restarts, this is remembered by the browser and you are no longer prompted by the browser for permission to determine your location. You can clear this preference, by clicking on the Icon shown below and then clicking on Clear these settings for future visits.
Geolocation Example

What happens, if we refuse permission to the browser to determine our location? Let us see what happens by running our example again. We navigate to the home page i.e. geotest.html and once again the browser prompts us, asking for our permission, as shown below:

Geolocation Example

This time we refuse it by clicking on Deny. This will results in the error callback function getting invoked i.e. errorHandler and we extract out the PositionError.code i.e. value of 1 (PERMISSION_DENIED) and PositionError.message that is device specific. In the case of Google Chrome, it rightly populates it to “User denied Geolocation” as shown below.

Do not assume that this message will be populated correctly. The same error message on Firefox browser gave the following alert message, as shown below:

So remember to provide a user friendly message that is populated by your application rather than depending on the device to do that.

What if the Browser does not support Geolocation?

If the browser does not support Geolocation, we have handled the scenario such that it displays an alert to the user in our test code. For e.g. I accessed our sample page via Internet Explorer 9 Beta and found that it displayed the appropriate message as shown below:

Remember HTML5Test that we covered earlier in the article. If we access http://www.html5test.com in Internet Explorer 9 Beta, we get the correct results for Geolocation feature as shown below.

So remember to save yourself enough heartburn and use html5test.com as a quick way to ascertain if a particular feature is supported or not.

What can we do with our location?

Location is the starting point of an entirely new class of applications/services that called themselves “Location Based Services”. Once you know the Location of the user, several value added features can be built on top of it. Location of a user is such a hot topic nowadays that everyone from Google, Yahoo, Twitter and Facebook added location of the user activity to their applications. Examples of how you can use a location are:

· Weather Reports for a particular location as the user is passing through it

· Traffic incidents as they happen

· Retail offers from merchants in the vicinity of the location that the user is currently in

· A Friend Locator application that informs the user of his/her friends if they are within close proximity of each other.

Most of these LBS application also make use of Google Maps to provide an intuitive user interface.

Conclusion

We saw how easy it was to get access to Location using the Geolocation APIs in HTML5. Geolocation data when combined with Maps and Other services can help create powerful applications.

Please participate

How important is Location to your application? How did you incorporate it into your application? What do you think of HTML5 Geolocation APIs? Would it make things simpler/better? Please discuss in the comments below. We look forward to your active participation.

Romin Irani
Romin Irani– Principal Architect

26
Sep
This entry is part 2 of 5 in the series HTML5 Series

In the first part of our series, we saw how to use the Geolocation feature of HTML5. While this part will not focus on any specific feature of HTML5, it will bring to the table an interesting way in which you can determine if your browser supports a particular HTML5 feature or not.

To understand that a little bit, let us go back to the code in the first part in which we determine if the browser has Geolocation support or not. Take a look at the code snippet below that is reproduced from the first part:


function findCurrentLocation(){
	var geoService = navigator.geolocation;
	if (geoService){
		geoService.getCurrentPosition(showCurrentLocation,errorHandler);
	} else {
		alert("Your Browser does not support Geolocation.");
	}
}

The above Javascript function findCurrentLocation() is interested in determining first if there is Geolocation support or not. If you notice, it queries the standard navigator object first. If your browser support Geolocation, then it will have an object geolocation. We then put in an if statement that does something if support is there and if there is no support then it falls back to another path of execution.

While this approach is fair enough, you will soon end up with similar pieces of code to determine if a certain HTML5 feature exists or not. In certain situations you may also do browser sniffing (User Agent detection) to include a certain piece of code if support exists or not. This soon becomes unwieldy and clutters up your code too. You need a cleaner mechanism of detecting support for HTML5 features (since we still in the transition phase where all browsers support most features).

Enter Modernizr. To quote from their web site, Modernizr is a small and simple JavaScript library that helps you take advantage of emerging web technologies (CSS3, HTML 5) while still maintaining a fine level of control over older browsers that may not yet support these new technologies.

And how does it do that? Modernizr creates a global JavaScript object (called Modernizr) which contains properties for each feature. If your browser supports it, it will evaluate to true, else it will be false.

Modernizr is useful for all aspects of HTML5. It not only helps you detect if your browser supports new HTML5 markup elements, CSS3 features but also the Javascript APIs (Geolocation, Storage, Web Workers, etc). Keep in mind that it does not enable any of the features, it is simply there to help you detect it.

You can refer to its complete documentation for all the features that it can help detect for HTML5. I provide a brief summary below for certain HTML5 features and we will see how to modify our function above to incorporate Modernizr.

HTML5 Feature Modernizr Object
Geolocation
Modernizr.geolocation
Local Storage Modernizr.localstorage
Session Storage
Modernizr.sessionstorage
if (Modernizr.<feature>) {
//Yes! Your browser supports the feature, so take advantage of it
}
else {
//No! Your browser does not support the feature, so fall back on some other mechanism. Degrade gracefully.
}

Using Modernizr in your code
We shall modify our existing Geolocation code shown at the start of the article and which we covered previously in the series and employ Modernizr.

Follow these steps to include Modernizr:

  1. Download modernizr-1.5.min.js from the main web site
  2. Include the script in your code. This will initialize Modernizr when the page loads. In fact, it creates the global Modernizr JavaScript object with all the feature objects created, so that you can start using it in your code.
  3. Finally, use the template pattern in your code as shown above.

I will recreate the geotest.html example that we covered in Part 1: Geolocation article.

<!DOCTYPE html>
<html>
<head>
<meta charset=”utf-8">
<title>HTML Geolocation Test</title>
<script src="js/modernizr-1.5.min.js"></script>
<script type="text/javascript">

if (Modernizr.geolocation) {
  navigator.geolocation.getCurrentPosition(showCurrentLocation,errorHandler);
}
else {
  alert("Your Browser does not support GeoLocation.");
}
… REST OF THE CODE
</script>
</head>

<body>
<div id="main">
	<div id="mylocation"></div>
	<input type="button" value="Get Location" onclick="findCurrentLocation()"/>
</div>

If you look at the above code, we have simply included the script file i.e. js/modernizr-1.5.min.js and then checked if the Geolocation feature is supported. The rest of the code remains straightforward.

While this is a simple example, the utility of Modernizr becomes visible when you deal with many other features of HTML5. Let it do all the hard work of determining a particular feature of HTML5 in your browser.

Please participate

We look forward to your feedback on this article and the others in the series. Let us know which feature you would like to see covered. Additionally, do share your experiences with HTML5.

Romin Irani
Romin Irani– Principal Architect

28
Sep
This entry is part 3 of 5 in the series HTML5 Series

Hope you have been enjoying the series on HTML5 so far, where we covered HTML5 GeoLocation and the Javascript library Modernizr. In this part of the series, we shall cover the new HTML Form elements that have been introduced in HTML5.

A Form is one of the most basic and essential features of any web site. The form elements available in HTML so far include the textbox, checkbox, radio, button, drop-down list, password and file picker. While these have sufficed so far, there is a clear need for newer form elements. The question is not just of newer form elements, but the ability to inject behavior into existing form elements so that usability and validity, which is a cornerstone of any good UI, is given highest consideration.

We shall break up HTML5 Form features into 2 parts in this series. This part will be more focused on the different types of input elements that are introduced in HTML5. In the next part, we shall look at how additional attributes introduced in HTML5 bring in significant improvements to both usability and also to the development code.

New Input Types

HTML5 brings to the table several new input types, a total of 13. The philosophy behind these new input types is to address the common types of data fields that users typically have to fill up in a web form. Apart from plain text, there is data to be filled up like email address, web site URLs, Phone Numbers, Date/Time, Numeric data, Colors, etc.

HTML5 introduces these data types via the <input type=”_NEW_TYPE_HERE_”/> format.

What if my browser does not support these new HTML5 form elements?

No problem. One of the key design decisions in HTML5 is backward compatibility. What this means is that if the new input types are not supported, then by default it falls back to <input type=”text”…./>, so it will be rendered as a plain text box, which the user can then fill data in.

One may ask, what is the advantage of these new input types and how are the browsers supposed to implement them? By supporting the new input types, two things happen:

a) You get automatic validity of the fields as per the format. This means that the form is not going to get submitted if the value entered is not as per the default validation of that type

b) The browser inspects the input type and if it finds that it is of a specific type, then it does something quite clear to aid the input of that data. For e.g. On the Smart Phones, which do not have a physical keyboard but instead a virtual keyboard, the keyboard that will be shown up will only contain keys that will aid the user in filling out the data.

Let us look at the new HTML5 input types that are present.

Email Address

This input type allows for entry of email addresses. The format is shown below:

<input type="email"/>

This input type is useful for entering email ids like test@test.com

Web URLs

<input type="url"/>

This input type is useful for entering web urls like http://www.xoriant.com

Tel

This input type is useful for entering telephone numbers

<input type="tel"/>

The email, url and tel input types are meant to instruct to the browser that the input would be valid only if it contains characters that validate the input type. Additionally, Smart Phone browsers like Apple iPhone do a very neat trick when they encounter input types like URL, Email and Telephone. Since they have a virtual keyboard, they will only show those keys that aid in entering the value quickly. So if you are trying to type the Telephone, it will only show the numbers and some characters, the other keys are hidden from you.

Shown below is a screenshot of the Android Web browser accessing a form which contains an input element of type tel. Notice that in the virtual keyboard, it only shows keys that aid in faster and less error prone data entry.

Android Web browser accessing a form Date Time

HTML5 provides for 6 types of DateTime inputs, which cater to a variety of date time entries, as your application may require. They are date, time, datetime, local-datetime, month, year. The syntax is shown below:

<input type="datetime"/>
  <input type="date"/>
  <input type="time"/>
  <input type="month"/>
  <input type="week"/>
  <input type="local-datetime"/>

Shown below is the datetime input type rendered in the Opera Browser:

Datetime input type rendered in the Opera Browser

Datetime input type rendered in Opera Browser

Spin Box

A frequent requirement in forms is to fill out numeric values. An input type number has been added. This will render the input as a spinbox if the browser supports it. It will even honor the min, max values that you specify. The step attribute is used to indicate the increment/decrement if the user clicks the up/ down spin button. The value attribute specifies an initial value for the control.


<input type="number"
       min="1"
       max="5"
       step="1"
       value="3">

Slider

Spin boxes are not the only way to enter numeric input. You can also allow a user to use a slider to specify a value. The syntax is shown below:

<input type="range"
       min="1"
       max="5"
       step="1"
       value="3">

If the browser supports the number and range types, it will render as shown below:

Browser supports the number & range types

Browser supports the number & range types

Search

This input is specified by giving the type=”search” as shown below.

<form>
  <input name="search_terms" type="search">
  <input type="submit" value="Go">
</form>

It will be rendered as shown below:

As you type, a cross icon will appear at the end of the input box and you can clear the search term by clicking on it.

autofocus, placeholder and novalidation

There are 3 attributes that we can apply to HTML5 forms that aid in data entry.

  • autofocus: This attribute when applied to any form element, will result in the field receiving focus. For e.g. consider the form shown below:

<form>
	<label for=”firstname”>First Name</label>
	<input type=”text” id=”firstname” name=”firstname” autofocus>
              <label for=”lastname”>Last Name</label>
	<input type=”text” id=”lastname” name=”lastname”>
	<input type=”submit” label=”Go”>
</form>

We have added the attribute autofocus to the firstname input field. When the form loads, you will find that the focus is already set on that field, thereby making it easier for the user to start filling the form.

  • placeholder: This attribute when applied to any form element, will display helper text to aid the user to fill up the value. When you give focus to the element, the placeholder value will go away and let the user enter the value. If no value is entered and you move away to another field, then the placeholder value will be shown again. Consider the same example as above but with placeholder values for both firstname and lastname fields.

<form>
	<label for=”firstname”>First Name</label>
	<input type=”text” id=”firstname” name=”firstname” placeholder=”Enter First Name here” autofocus>
              <label for=”lastname”>Last Name</label>
	<input type=”text” id=”lastname” name=”lastname” placeholder=”Enter Last Name here” >
	<input type=”submit” label=”Go”>
</form>

When we visit this page, we see the following form:

Placeholder rendered

You will notice that we had put placeholders for both the fields, but since the firstname field also had the autofocus, the placeholder text is not shown. Instead it has the focus so that the user can start entering the text. The lastname field has the placeholder text as shown. As you tab in and out the First Name field without entering any data, you will find the placeholder text returning back there.

Do note that not all browsers support placeholder text. The above support was from Google Chrome browser.
  • novalidation: By default, when you submit a form, all the fields in the form will be validated. This means that the browser that fully supports the HTML5 input types, will validate all the fields as per the input types and if they are not valid, the form is not submitted. Browser support varies over here so be careful. By default, all the forms are validated before submission. However, you can opt for the form to not be validated, by adding the novalidation tag to the <form> tag as shown below:
<form …. novalidation>

Conclusion

The new HTML5 input types and several attributes introduced in the specification are a clear step to address data input via forms, which forms a cornerstone of any public web application. Do note that there are many more features like pattern, etc which we have not discussed in this blog post, but the reader is encouraged to go and refer to documentation on the standard. While testing out any of these features, it is important to first determine if your browser supports them. In our tests, we have found the Opera browser to be one of the first to implement the different input types, however latest versions of Chrome and Firefox Beta are not far behind. We believe that the browsers will catch up soon and implement most of them.

Please participate

We look forward to your feedback on this article and the others in the series. Let us know which feature you would like to see covered. Additionally, do share your experiences with HTML5.

Romin Irani
Romin Irani– Principal Architect

04
Oct
This entry is part 4 of 5 in the series HTML5 Series

Welcome to Part IV of this series. We covered the basics of HTML5 Geolocation support in Part I of this series. In that article, we looked at how an HTML5 based web application can make use of Geolocation support built in the browser.

To recap, I will recreate the Javascript code for you below:


<script type="text/javascript">

function findCurrentLocation(){
	var geoService = navigator.geolocation;
	if (geoService){
		geoService.getCurrentPosition(showCurrentLocation,errorHandler);
	} else {
		alert("Your Browser does not support Geolocation.");
	}
}

function showCurrentLocation(position){
	document.getElementById("mylocation").innerHTML = "Current Latitude : " + position.coords.latitude + " , Longitude : " + position.coords.longitude;
}

function errorHandler(error){
	  alert("Error while retrieving current position. Error code: " + error.code + ",Message: " + error.message);
}
</script>

In the above code, we used the getCurrentPosition method on the navigator.geolocation object to get the current location co-ordinates. The main point to note about this method is that it is just a onetime call to get the location co-ordinates. The application is then in control to provide location relevant data. So while this might suffice for certain kinds of applications, it may not be enough for an application that needs the location regularly at a certain interval. For e.g. if you wish to write an application that would provide different location based data, if the user co-ordinates are changing i.e. if the user is moving.

To do that, you need to substitute the getCurrentPosition call with watchPosition. This method functions in a similar manner to getCurrentPosition, just that your application will get notified when the users position changes. In addition to getting notified i.e. the success function getting called when the location has changed, the watchPosition method also returns a unique ID. This ID is used together with a paired method called clearWatch. So whenever you wish to stop tracking the users location (which you should by the way, since these operations are draining), you can use the ID and pass it as a parameter to the navigator.geolocation.clearWatch method. This will stop the tracking of the user’s location.

Let us take a look at our modified code then continuously gets notified when the location of the user changes. We are simply changing the code that we covered here in Part I of the series.

Do note that I have decided to use the Modernizr Javascript library for detecting HTML5 support that we covered in Part II of the series.

The geotest.html file is shown below:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HTML GeoLocation Test</title>
<script src="js/modernizr-1.5.min.js"></script>
<script type="text/javascript">
var watchPositionID=0;

function startLocationTracking(){
	alert("startLocationTracking");
	if (Modernizr.geolocation) {
		alert("Your Browser supports GeoLocation");
		watchPositionID = navigator.geolocation.watchPosition(showCurrentLocation,errorHandler,{enableHighAccuracy: true});
	} else {
		alert("Your Browser does not support GeoLocation.");
	}
}

function showCurrentLocation(position){
	document.getElementById("mylocation").innerHTML = "Current Latitude : " + position.coords.latitude + " , Longitude : " + position.coords.longitude;
}

function errorHandler(error){
	  alert("Error while retrieving current position. Error code: " + error.code + ",Message: " + error.message);
}

function stopLocationTracking(){
	if (watchPositionID > 0) {
		navigator.geolocation.clearWatch(watchPositionID);
		alert("Stopped Tracking Location");
	}
}

</script>
</head>
<body>
<div id="main">
	<div id="mylocation"></div>
	<input type="button" value="Start" onclick="startLocationTracking()"/>
	<input type="button" value="Stop" onclick="stopLocationTracking()"/>
</div>
</body>
</html>

Let us go through the code in brief:

  • Our HTML page is simple. It has two buttons, one to start location tracking and the other to stop location tracking.
  • The Start button, invokes the startLocationTracking method. This method determines first if Geolocation support is present. If yes, it will invoke the watchPosition() method on the navigator.geolocation object. The first parameter to the watchPosition() method is the success function that gets invoked if the location is determined. That success function i.e. showCurrentLocation simply displays the location in terms of latitude and longitude.
  • The watchPosition method returns an ID that we are saving in the global variable named watchPositionID.
  • The Stop button, invokes the stopLocationTracking method. This method simply uses the watchPositionID and passes that as a parameter to the navigator.geolocation.clearWatch(…) method. This will stop the invocation of the success function i.e. showCurrentLocation if the users location changes.

Conclusion

We have seen in this article how we can use the navigator.geolocation object to keep tracking a user’s location as it changes. In an earlier part of the series on HTML5 Geolocation, we had covered getting the location on demand or only once. As per the requirements of your application, you can use any of these two mechanisms. Do keep in mind, that determining the location of the device is quite a drain on the battery, especially on mobile devices. So if you are using the watchPosition method to keep a track as the location changes, be sensitive to the battery consumption too.

Please participate

We look forward to your feedback on this article and the others in the series. Let us know which feature you would like to see covered. Additionally, do share your experiences with HTML5.

Romin Irani
Romin Irani– Principal Architect

13
Oct
This entry is part 5 of 5 in the series HTML5 Series

HTML in itself is primarily about designing and presenting content on the Web. Attempts to add new features to HTML and other related APIs have taken the Web environment to a different level altogether.

In this blog, we are going to look into designing features made available in HTML5. Talking about designing in HTML pages, the element canvas takes prime importance.

What is Canvas?

The new canvas element provides scripts with a resolution-dependent bitmap canvas, which can be used for rendering graphs, game graphics, or other visual images on the fly. The canvas API supports the same two-dimensional drawing operations that most modern operating systems and frameworks support. Furthermore, once canvas is added in an HTML page using the standard <canvas></canvas> notation, we can manipulate it with JavaScript. But to actually do something interesting, we can use JavaScript and get the context of canvas.

Before canvas, to have any drawing on the page, the only option we had were images (jpeg or gif), Flash, applets or some JavaScript hacks.

Canvas Co-ordinates

Like any other graphics system, canvas has a coordinates system with X=0 and Y=0 at the upper-left corner, as shown below.

Canvas Co-ordinatesSupport

Currently, canvas is supported by all major browsers such as Firefox, Chrome, Safari, Opera etc. The recently launched IE9 beta has also incorporated support for canvas.

Note: Before we start, we assume here that the reader has a basic understanding of HTML and JavaScript.

Getting Started

Let’s get your favorite editor and start typing!

In its simplest form, a canvas element can be added in an HTML page using “<canvas></canvas>”. But to do something interesting, we will add some more attributes as well.

<canvas id="myCanvas" width="150" height="150"></canvas>

First things first: For any element, it is a good practice to have some “fallback content” just in case the element is not supported in the browser.

<canvas>Use updated browser to see new features of HTML5</ canvas >

Here is a simple piece of code on which we can build our page:

<html>
<head>
<script>
	function draw() {
		var canvas = document.getElementById("myCanvas ");
		var ctx = canvas.getContext("2d");
	}
</script>
</head>
<body onload="draw();">
<canvas id=" myCanvas " width="150" height="150">
This example requires a browser that supports HTML5.
</canvas>
</body>
</html>

The above code will create a blank rectangular area. We can use JavaScript to add whatever shapes or patterns we need to add within this area.

Going Line by Line

var canvas = document.getElementById("myCanvas");

This line obtains a reference to the canvas element so that we can use it further in our code.

var ctx = canvas.getContext("2d");

Canvas has the getContext() method which provides a reference through which we can actually draw shapes.

The “2D” parameter provides a 2D context that represents a flat Cartesian surface whose origin (0,0) is at the top left corner, with the coordinate space having x values increasing when going right, and y values increasing when going down. 2D context provides a variety of different methods for drawing shapes, text APIs etc.

Trying out a Shape

Here’s a sample piece of code to draw two overlapping rectangles of different colors.

function draw() {
	var canvas = document.getElementById("myCanvas ");
	var ctx = canvas.getContext("2d");

	ctx.fillStyle = "rgb(200,0,0)";
	ctx.fillRect (10, 10, 55, 50);		// Draws a filled rectangle
	ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
	ctx.fillRect (30, 30, 55, 50);
}

The result of the above code should look similar to the image below.

Overlapping rectangles

Drawing Paths

There are some additional steps that need to be taken while drawing paths: beginPath(), closePath(), stroke(), fill().

  • Create a path by calling the beginPath() method. Internally, paths are stored as a list of sub-paths (lines, arcs, etc.) which together form a shape. Every time this method is called, the list is reset and we can start drawing new shapes.
  • Next, call the methods that actually specify the paths to be drawn. This could be line or arc or curves.
  • It is optional to call the closePath() method. This method tries to close the shape by drawing a straight line from the current point to the start.

Finally, we can call the stroke() and/or fill() methods. Calling one of these will actually draw the shape to the canvas. stroke() is used to draw an outlined shape, while fill() is used to paint a solid shape.

function draw() {
		  var canvas = document.getElementById("canvas");
		  var ctx = canvas.getContext("2d");

		 ctx.beginPath();
		 ctx.moveTo(125,125);
		 ctx.lineTo(125,45);
		 ctx.lineTo(45,125);
		 ctx.stroke();

		 ctx.beginPath();
		 ctx.arc(75,75,50,0,Math.PI*2,true); // Outer circle
		 ctx.moveTo(110,75);
		 ctx.arc(75,75,35,0,Math.PI,false);   // Mouth (clockwise)
		 ctx.moveTo(65,65);
		 ctx.arc(60,65,5,0,Math.PI*2,true);  // Left eye
		 ctx.moveTo(95,65);
		 ctx.arc(90,65,5,0,Math.PI*2,true);  // Right eye
		 ctx.stroke();
    }

The above code should produce results similar to the image below.

Draw Image

The functions used in the sample code above are described in brief below:

moveTo(x, y) – The moveTo() function takes two arguments – x and y, – which are the coordinates of the new starting point.

  • lineTo(x, y) – This method takes two arguments – x and y, – which are the coordinates of the line’s end point. The starting point is dependent on previous drawn paths, whereas the end point of the previous path is the starting point for the following path etc. The starting point can also be changed by using the moveTo() method.
  • arc(x, y, radius, startAngle, endAngle, anticlockwise) – This method takes five parameters: x and y are the coordinates of the circle’s center. Radius is self-explanatory. The startAngle and endAngle parameters define the start and end points of the arc in radians. The starting and closing angle are measured from the x axis. The anticlockwise parameter is a Boolean value which when true draws the arc anticlockwise, otherwise in a clockwise direction.

Using Images

We can have images in canvas for dynamic photo compositing or for use as backdrops of graphs etc. But it is a little tricky to add images in canvas. There three ways we can use images:

  • Using images which are on the same page – We can access all images on a page by using either the document.images collection, the document.getElementsByTagName() method, or if we know the ID attribute of the image, the document.getElementById() method.
  • Using other canvas elements – Just as with normal images we access other canvas elements using either the document.getElementsByTagName() method or the document.getElementById() method. Make sure you’ve drawn something to the source canvas before using it in your target canvas.
  • Creating an image from scratch – Another option is to create a new image objects in our script:
var img = new Image();   // Create new Image object
img.src = 'myImage.png'; // Set source path
var img = new Image();   // Create new Image object
img.onload = function(){
// execute drawImage statements here
}
img.src = 'myImage.png'; // Set source path
function draw() {
	var ctx = document.getElementById('canvas').getContext('2d');
	var img = new Image();
	img.onload = function(){
		ctx.drawImage(img,0,0);
		ctx.beginPath();
		ctx.moveTo(30,96);
		ctx.lineTo(70,66);
		ctx.lineTo(103,76);
		ctx.lineTo(170,15);
		ctx.stroke();
	}
	img.src = 'images/backdrop.png';
}

drawImage(image, x, y) – image is a reference to an image or canvas object and x, y form the coordinates where the image should be placed.

Pixel Data and Canvas

Remember that the canvas API is based on pixels. This gives us the ability to easily access pixel information from canvas and manipulate it.

ctx.getImageData(startX, startY, width, height)

This function returns a representation of the current state of the canvas display as a collection of integers. Specifically, it returns an object containing three properties:

  • width: The number of pixels in each row of the pixel data
  • height: The number of pixels in each column of the pixel data
  • data: A one-dimensional array containing the actual RGBA values for each pixel retrieved from the canvas

RGBA – is Red, Blue, Green and A is an alpha component with values ranging from 0-255.

ctx.putImageData(imagedata, dx, dy)

This function can be used to update the canvas display. As you have access to the object with image data (using getImageData()), now you can easily modify the pixel values in the data array mathematically, because they are each simply integers from 0 to 255.

ctx.createImageData(sw, sh)

This method can be used if you want to create a new image from scratch using canvas. This set of data can be programmatically changed as before, even though it does not represent the current state of the canvas when retrieved.

Canvas Security

There could be security issues with respect to using pixel manipulation in canvas. For this reason, the concept of an origin-clean canvas was specified, so that canvases that are tainted with images from origins other than the source of the containing page cannot have their data retrieved.

Any canvas that contains images rendered from remote origins will throw a security exception if the getImageData() function is called. It is acceptable to render remote images into a canvas from another origin as long as you (or any other scriptwriter) do not attempt to fetch the data from that canvas after it has been tainted.

So as we have seen in this blog, the canvas API provides a powerful way to draw on HTML pages with images, gradients and paths. When properly planned, canvas applications can range from simple charts to complex visual data representing tool to cool animations and more!


Saurabh Akshekar– Sr. Software Engineer

29
Oct
This entry is part 6 of 5 in the series HTML5 Series

What are we going to talk about in this blog?

In this blog, I shall introduce you to the power of WebSockets – a new technology providing bidirectional, full-duplex communication channels over a single TCP socket, solving most of the issues faced in real time communication.

What’s in it for me?

I have heard a lot of people assuming that HTML5 just deals with UI components and has nothing for programmers. This article puts this apprehension to rest.

Is it really worth it?

Real-time applications such as stock trading, banking, financial applications, online gaming, gambling, etc. need very reliable and high performance systems. Imagine you playing an online poker game on Facebook and waiting for the other player to finish their turn. It is, at times, frustrating just to wait for your turn as the communication is not fast enough and even though it is nearly happening in real time, you can still feel the delay. The above example is not that critical, but imagine the delay in stock trading, banking, financial applications, currency exchanges, etc. To cite another example, the Indian currency exchange rate changes 10 to 15 times in a minute. Even a small delay could be crucial.

Anatomy of HTTP

HTTP, which is widely used, is only half duplex, i.e., the data can flow only in one direction at a given time, thereby making real time communication difficult. Also, each request and response has header information which adds to the network traffic. To find out the HTTP request and response headers, you can use an application like the Live HTTP Headers add-on in the Firefox browser and then see the results. There is a lot of unnecessary HTTP request and response header information overhead, at times, as much as 2000 bytes.

But I already have applications running on the Web! Why use WebSockets?

Some techniques used such as polling, long-polling and streaming have their own limitations:

Polling: This technique is used in Ajax applications to simulate real-time communication. I was really impressed when I had first used the Ajax concept and was happy that only the part of the Web page which needs to be refreshed is refreshed, and not the whole page. The XmlHTTPRequest was God’s own gift! But even Ajax needs us to keep polling to check whether the server has sent any response. This is achieved by the value of the readyState property of the XMLHttpRequest object:

If(http.readystate == 4) // meaning request is complete
{
	Call the function to process the data
}

Long polling: This is also known as asynchronous polling. The browser sends a request to the server and the servers keeps the request open for a long set period hoping that the process is completed within the period.  Thus the name long polling (but polling nevertheless).

Streaming: This is better than the above two techniques but faces possible complications when firewalls and proxies come into picture. The responses keep on getting built up and must be flushed periodically.

A step forward – beyond hacks

Enter HTML5 WebSocket to solve the above issues. It is a W3C API and IETF protocol, details of which can be found at http://dev.w3.org/html5/websockets/ or http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-03.

WebSocket is a fully duplex single socket. It creates a channel between the browser and the server where two-way communication can be performed. The client (on the browser) does not poll whether the response has come or not. The client and server can send data to each other through WebSocket freely. It shares the port with the existing HTTP content. It easily traverses through firewalls, routers, proxies, etc. This is also known as Push technology. The server just pushes the data to the client and does not mandate the client to keep polling for data.

There are 2 schemes provided by WebSocket:

  • WebSocket scheme  - ws://www.websocket.org/text
  • WebSocket secure scheme – wss://www.websocket.org/encrypted-text

WebSocket Architecture

WebSocket Architecture

The browser clients communicate with the WebSocket server using the WS scheme and the WebSocket server communicates with the backend servers using TCP. There are various WebSocket servers available and the best of the lot is undoubtedly the Kaazing WebSocket Gateway. An evaluation copy of the same can be downloaded from www.kaazing.com.

There are some backend servers which understand the WebSocket scheme and can accept the requests directly from the browser clients. ActiveMQ 5.4.0 is one such server which I have come across. The WebSocket architecture diagram would then be as follows:

WebSocket connection uses the same TCP connection as it upgrades from the HTTP protocol to the WebSocket protocol. Once it is upgraded to the WebSocket protocol, then the data can be sent back and forth between the client and the server in full-duplex mode.

WebSocket data is sent in frames, where each frame of data starts with a 0×00 byte and ends with a 0xFF byte. In between the start and end bytes, it contains the UTF-8 data, for example:

\x00Hello, WebSocket World\0xff

There is no limit defined for the size of the data which can be sent as long as the user agent can manage it. Since JavaScript does not allow more than 4GB of data, so that is limit.

With WebSocket, each data packet (frame) has only 2 bytes of packaging and so the overhead is a minimum, when compared to the header information in HTTP request and response headers. There is no latency in establishing the new TCP connections for each HTTP message. Hence there is significant reduction in network traffic and latency.

There was a talk recently when W3C came out with a warning to go slow while embracing HTML5, but the good news is that all the important players such as Microsoft, Google, Mozilla and Apple are going ahead full steam supporting WebSocket in their browsers. The browsers which support the WebSocket as of now are:

  • Chrome 4.0 +
  • Firefox 4.0 Beta 1+
  • Safari 5.0 +
  • IE 9.0

There are two ways to check whether your browser supports WebSocket or not. The first way is to just go to www.websocket.org and on the top right side, you will get a message saying whether your browser supports WebSocket or not. The second way is to write a simple JavaScript code and check it yourself.

if (window.WebSocket)
{
alert("Yahoo !! Your browser does support WebSocket!");
}
else
{
alert("Sorry!! Your browser does not support WebSocket");
}

Now let us see how easy it is to use the WebSocket object.

var objWebSocket = new WebSocket(url);

The URL above is the address of the server to which you want to create the WebSocket connection to. For e.g., talk.google.com:5223 (the Google Talk server).

WebSocket programming is event based. Once the WebSocket is opened, we just wait for events and do not poll the server for data. There are 3 events associated with WebSockets and we need to code listeners for each one of them and associate the listeners with the events. The 3 events are open, message and close. The open event is fired when the WebSocket connection is opened successfully. The message event is fired when the server sends data. The close event is fired when the WebSocket connection is closed.

For e.g.:

objWebSocket.onopen = function(evt)
{
alert("WebSocket connection opened successfully");
};
objWebSocket.onmessage = function(evt)
{
alert("Message : " + evt.data);
};
objWebSocket .onclose = function(evt)
{
alert("WebSocket connection closed”);
};

Once the WebSocket connection is opened, the onMessage event is fired when the server sends the data to the client. If the client wants to send data to the server, it can do that easily as follows:

objWebSocket.send("Hello World");

With WebSocket, you can communicate with WebSocket servers and via that to any back-end servers or any message brokers. You can extend any TCP-based protocol to the Web like XMPP, Jabber, Publish/Subscribe protocols like Stomp & AMQP, gaming protocols like Darkstar, etc.

References:

Chirag Trivedi
Chirag Trivedi– Lead – HTML5 Group