37
option or showing the user the error. Understand that this quota is a per-domain quota (a domain
being a combination of schema, host, and port). So you will have separate quotas for http:// and
https://. But this also means that if another application on the host http://www.YourAppSite.com uses
up the quota, then you are out of luck. This issue is described in the HTML5 Web Storage specifica-
tion section 7.2. I particularly like the reference to geocities.com:
Different authors sharing one host name, for example users hosting content on geocities.com, all share
one local storage object. There is no feature to restrict the access by pathname. Authors on shared
hosts are therefore recommended to avoid using these features, as it would be trivial for other authors
to read the data and overwrite it
.
So be certain that you know who is writing applications for the domain that you are using, or you
expose your saved data to others. In addition, do not save sensitive data in web storage. Anyone
sharing your domain would find it all too easy to loop through and read your data.
Before we dive too deeply into the saving of data, you need to know that there are actually two types
of defined storage: session storage and local storage.
Session Storage
Session storage is designed for scenarios in which the user is carrying out a single transaction. The
HTML5 sessionStorage attribute is available only to the window or tab in which it was initiated and
only while that window stays active. When the window or tab is closed (i.e., the session has ended),
the data ceases to exist. This approach has an advantage over cookies, not only because you have
more room to store data (5MB versus 4KB for a cookie), but because this attribute is scoped only for
the window that is open. Cookies can leak to another window if you open another browser instance
while your session is still active.
Local Storage
Local storage is designed for scenarios in which you want the data to persist beyond a single session.
This storage spans all windows that you might have open on that domain. If you set or modify data in
one window, that data will be available to all other windows that are opened to that domain. In addi-
tion, the data stays available after you close your browser, unless explicitly deleted by the developer
or user. This approach allows you to store data over instances, across windows, and on the client side,
without using cookies.
Using HTML5 Storage
Now that we have examined the different kinds of storage, let’s take a look at how to use them. The
HTML5 Web Storage specification defines the following:
• Length <attribute>
• Key() <function>
126
Chapter 14: Storing Your Data in HTML5
27
• getItem<function>
• setItem()<function>
• removeItem()<function>
• clear()
These attributes and functions are available for both sessionStorage and localStorage. In essence, we
are saving key/value pairs of data. Because both types of storage use the same methods, we will show
examples using only session storage.
Setting and Retrieving Data
Using the Web Storage API, you can set and retrieve data in several ways. We can use the setItem and
getItem methods to place and retrieve data:
sessionStorage.setItem(‘firstName’, “Daniel”);
sessionStorege.setItem(‘lastName’, “Egan”);
var fName = sessionStorage.getItem(‘firstName’);
var lName = sessionStorage.getItem(‘lastName);
If you want to save your fingers from doing some typing, then you can also use Expandos to add and
retrieve data:
sessionStorage.firstName = “Daniel”;
sessionStorage.LastName – “Egan”;
var fName = sessionStorage.firstName;
var lName = sessionStorage.lastName;
Understanding that all data is saved as a DOMString is vital for several reasons. First, because the
API stores numbers as strings, a developer needs to be sure to convert numbers when retrieving data,
as the example in Figure 2 shows. Remember that the “+” symbol serves a dual purpose: It performs
both arithmetic and concatenation. Second, as a developer you won’t be limiting yourself to simple
key/value pairs, so you will need a way to store more complex structures as strings.
Chapter 14: Storing Your Data in HTML5
127
30
Figure 2: Converting strings to numbers
sessionStorage.setItem(‘price’, 32);
sessionStorage setItem(‘tax’, 11);
// will return 3211
var totalPrice = sessionStorage.getItem(‘price ‘) + sessionStorage.getItem(‘tax
‘);
//instead you will need to parse the data
var intPrice = parseInt(sessionStorage.getItem(‘price’);
var intTax = parseInt(sessionStorage.getItem(‘tax’);
var totalPrice = intPrice + intTax;
Saving More Complex Structures
Although saving key/value pairs locally in a 5MB storage area is convenient, most developers will
want to save more complex objects. As noted previously, all data is stored as a string, so the process
of saving an object into storage saves the object name “[Person person]”, not the actual data. To get
around this limitation, we can use JavaScript Object Notation (JSON), an open-source and text-based
way of storing data. Take a look at this simple example of JSON as a person object:
var person = { “firstName” : “John”,
“lastName” : “Doe”,
“age” : 23 };
If we want to store this object in session storage, we can encode and decode it, using the JSON.strin-
gify and JSON.parse methods. First, we save the object to storage:
sessionStorage.setItem(‘person’, JSON.Stringify(person));
Later, when we want to retrieve the data, we use JSON.Parse:
var person = JSON.Parse(sessionStorage.getItem(‘person’);
Clearing Data
Now that we have filled our storage with data, we need a way to remove it. There are two ways to
remove data that you have placed in storage: removeItem and clear. The removeItem method is very
similar to getItem, in that if you pass it a key, it will remove the value associated with that key:
128
Chapter 14: Storing Your Data in HTML5
12
sessionStorage.removeItem(‘firstName’);
If you want to remove everything that you have stored in storage, you can use the clear method:
sessionStorage.clear();
Keep in mind that the examples we have been using are for session storage and will go away when
the browsing session is completed. The same is not true for local storage. Because we have a limit of
5MB per domain, make sure that you keep your storage area clear.
In this article, we have focused specifically on web storage as a way to store data locally. As we men-
tioned previously, web storage has been widely implemented across all major browsers. This type of
storage is a step up from cookies and is a much simpler and cleaner way to save your data, whether
you need to save information for one session or across sessions.
Chapter 14: Storing Your Data in HTML5
129
26
Chapter 15:
Using the HTML5 Canvas Tag
The HTML5 canvas tag expands your options
for rendering text, images, shapes, and more
By Dan Wahlin
Rendering complex graphs or designs to the web has always been a challenge that has typically
been solved by using images, server-side processes, or plug-ins such as Silverlight or Flash. Although
drawing charts with straight lines has never been a problem (with the use of some creative CSS), ren-
dering different types of shapes and colors natively in the browser—such as ellipses, Bézier curves,
and other custom shapes—has always been a problem. With the addition of the HTML5 canvas tag,
available in the latest version of all major browsers, you can now do a lot using only JavaScript and
HTML tags. In this article I’ll provide an introduction to the canvas tag and demonstrate some of the
fundamental tasks you can perform using it.
The Canvas: What Is It, and Why Use It?
So what is the canvas tag? Put simply, it’s a way to render pixels on the client side using JavaScript.
This includes rendering text, images, shapes, linear and radial gradients, and more. Unlike Scalable
Vector Graphics (SVG), which is vector based (and also available in many modern browsers now),
the canvas is pixel-based. This makes it more challenging in scenarios where a user can zoom in or
out since code has to be written to re-render pixels based upon a specific zoom level. However, the
canvas performs very well, making it a good candidate for many types of complex rendering sce-
narios, such as graphs, charts, and games. The performance is especially good in Internet Explorer 9
(IE9) because of the hardware acceleration it provides. On the web you can find several great exam-
ples of using the canvas, such as Microsoft’s www.beautyoftheweb.com site. Check out Mike Tomp-
kins’ excellent Firework musical demo (see Figure 1).
130
Chapter 15: Using the HTML5 Canvas Tag
29
Figure 1: Putting the canvas into action with other HTML5 features such as audio and video
Before jumping into a discussion of using the canvas, let’s take a moment to consider why you’d want
to use it instead of using Silverlight, Flash, or server-side image generation processes. Determining
when to use the canvas (or, in my mind. any HTML5 feature) comes down to the target audience.
For example, I’m a big fan of Silverlight in addition to web technologies. If I’m building a line of
business (LOB) application that will be deployed on only Windows or Macintosh machines using
in-browser or out-of-browser techniques, then I’ll generally look to Silverlight first since it works very
well in that scenario and brings a lot of power and productivity to the table. However, if I’m writing
an application that will be released on the Internet or an intranet and may be used by different
devices such as iPads or iPhones, Android phones and tablets, or others, then I’ll pick standard web
technologies. Every application is different and I don’t believe that one size or technology fits all. Of
course, you’ll have to evaluate whether your target users have browsers that support the canvas tag
and plan an alternative strategy if they don’t. The canvas is definitely a new feature and not supported
by many older browsers including pre-IE9 Internet Explorer versions.
Now let’s get started with an overview of how to define and interact with the canvas.
Getting Started with the Canvas
Canvas functionality is available in the latest versions of the major browsers (IE9, Chrome, Safari,
Firefox and Opera) and can be defined using the <canvas> tag, as shown in the following example:
<canvas id=”canvas” width=”800” height=”600”></canvas>
Once a canvas is defined (or dynamically added) in HTML, you can interact with it using standard
JavaScript. I generally prefer to use jQuery in any JavaScript-oriented page, but you can also use the
standard document.getElementById() function to locate a canvas tag and then interact with it. The fol-
lowing code demonstrates how to locate a canvas tag defined in a page and get access to its 2D con-
text for drawing:
<script type=”text/javascript”>
window.onload = function () {
var canvas = document.getElementById(‘canvas’);
Chapter 15: Using the HTML5 Canvas Tag
131
28
var ctx = canvas.getContext(“2d”);
};
</script>
If you’re using jQuery it would look something like the following:
<script type=”text/javascript”>
$(document).ready(function () {
var canvas = $(‘#canvas’);
var ctx = canvas[0].getContext(“2d”);
});
</script>
Notice that once the canvas object is located, you must access its 2D drawing context. The W3C
defines the 2D context: “The 2D context 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.”
You can think of the 2D context as the drawing surface that you’ll programmatically interact with
using JavaScript. Once you have a reference to the 2D context object, you can use methods such as
lineTo(), fillText(), and fillRect() to perform drawing operations. Let’s take a look at a few of the drawing
features available.
Drawing Shapes, Lines, and Text
If you’ve ever used GDI+ (Graphics Device Interface) in the .NET framework (System.Drawing
namespace), you’ll feel right at home using the canvas since it’s similar to GDI+ drawing in many
ways. If you’ve never touched GDI+, then don’t worry about it; it’s simple to get started using the
canvas once you know a few fundamentals. Drawing is accomplished by calling standard JavaScript
functions that handle rendering lines, shapes, colors, styles, and more. Figure 2 shows several of the
key functions you can use.
Figure 2: Key canvas functions
132
Chapter 15: Using the HTML5 Canvas Tag
34
Let’s look at a few things you can do with the canvas starting with rendering rectangles or squares. To
draw rectangles or squares you can use the fillRect(topLeftCornerX,topLeftCornerY,width,height) func-
tion. It accepts the x/y coordinates of where to start the shape as well as its height and width. Figure 3
shows an example of defining a rectangle.
Figure 3: Rendering a rectangle using the fillRect() function
<script type=”text/javascript”>
window.onload = function () {
var canvas = document.getElementById(‘canvas’);
var ctx = canvas.getContext(“2d”);
//Render a rectangle
ctx.fillStyle = ‘Green’;
ctx.fillRect(0, 0, 200, 100)
};
</script>
In this example, the 2D context has its fillStyle set to a color of Green. The square that’s rendered by
calling fillRect() will be displayed in the upper left of the screen (0,0 point) and have a width of 200
and a height of 100.
If you’d like to render an arc or circle, the arc() function can be used. It has the following signature:
arc(centerX,centerY,radius,startAngle,endAngle,antiClockwise);
The centerX and center Y parameters define where the middle of the ellipse will be, the radius defines
the size of the ellipse, and the startAngle and endAngle parameters control the start and end points
of the ellipse (note that the startAngle and endAngle parameters are defined using radians rather than
degrees). The antiClockwise parameter will draw an arc (part of a circle) in an anticlockwise direction
when set to true. Here’s an example of using the arc() function:
//Render a circle
ctx.arc(100, 200, 50, 0, 2 * Math.PI, false);
ctx.fillStyle = ‘Navy’;
ctx.fill();
Passing a value of 0 and 2 * Math.PI for the start and end angle parameters will result in a complete
circle being rendered. To render part of a circle, simply supply a different value for the startAngle or
endAngle parameter, as shown next. This example will result in 1/2 of a circle being rendered. Figure
4 shows the rectangle, circle and arc that are rendered to the canvas.
Chapter 15: Using the HTML5 Canvas Tag
133
11
Figure 4: The results of rendering a rectangle, circle, and arc
ctx.beginPath();
ctx.arc(100, 300, 50, 0, Math.PI, false);
ctx.fillStyle = ‘Navy’;
ctx.fill();
It’s important to note that a call to beginPath() was performed before the arc() function call so that
each circle/arc shape stayed distinct and didn’t merge into the following one as shown in Figure 5.
Figure 5: The result of two shapes combining as a result
of not making a call to beingPath()
134
Chapter 15: Using the HTML5 Canvas Tag
40
The beginPath() function tells the canvas to start rendering a new path, while fill() ends the path (you
can also add a call to closePath() after each call to fill() if desired although it’s not required in this
case).
The final topic that I’ll cover in this section is rendering lines. This is accomplished by using moveTo()
and lineTo() along with the stroke() or fill() functions. The moveTo() function positions the virtual pen
at a specific location which can then draw a line to a specific x/y coordinate by using lineTo(). Figure
6 shows an example of drawing lines. The complete code for the shapes and lines rendered to this
point is shown in Figure 7.
Figure 6: Drawing lines and filling an area
ctx.beginPath();
ctx.moveTo(100, 400);
ctx.lineTo(50, 500);
ctx.lineTo(150, 500);
ctx.lineTo(100, 400);
ctx.strokeStyle = ‘Red’;
ctx.lineWidth = 4;
ctx.stroke();
ctx.fillStyle = ‘Yellow’;
ctx.fill();
Figure 7: Rendering shapes and lines using the canvas
<!DOCTYPE>
<html>
<head>
<title>Canvas Fundamentals</title>
<script type=”text/javascript”>
window.onload = function () {
var canvas = document.getElementById(‘canvas’);
var ctx = canvas.getContext(“2d”);
//Draw a rectangle
ctx.fillStyle = ‘Green’;
ctx.fillRect(0, 0, 200, 100);
//Draw a circle
ctx.arc(100, 200, 50, 0, 2 * Math.PI, false);
ctx.fillStyle = ‘Navy’;
ctx.fill();
//Draw an arc
ctx.beginPath();
ctx.arc(100, 300, 50, 0, Math.PI, false);
Chapter 15: Using the HTML5 Canvas Tag
135
Documents you may be interested
Documents you may be interested