The words you are searching are inside this book. To get more targeted content, please make full-text search by clicking here.

Tips & Tools for Creating Interactive Web Application

Discover the best professional documents and content resources in AnyFlip Document Base.
Search
Published by igodigital, 2017-04-19 14:00:21

HTML5 Hacks

Tips & Tools for Creating Interactive Web Application

Keywords: html5,hack,tools,tips,interactive,web,applications

Figure 4-8.
The 200 × 200 <canvas> tag with a drawing of a smiley face
We set the background color by adding a color fill to the circle that makes up the head.
Once the stroke is started, it’s a simple line of code:

smileCtx.fillStyle = '#F1F42E';
Our end result will have a simple image used as a repeating background (see
Figure 4-9).

Figure 4-9.
The 200 × 200 <canvas> tag with a drawing of a smiley face and a repeating heart background
image
172 HTML5 HACKS

To change that solid color to an image, we will use a very similar API:

smileCtx.fillStyle = myPattern;

You can see in the preceding code that we are using the same API for an image back-
ground as we are for a fill color (similar to the background attribute in a CSS decla-
ration). However, a bit of additional overhead is required when using an image.

Using an Image as a Fill

In JavaScript, to use an image you first must have a reference to it. In our case, we will

start by creating the image dynamically, and then setting its src attribute:

var img = new Image();
img.src = '/assets/img/heart.png';

The image we are using is the small icon-size image shown in Figure 4-10.

Figure 4-10.
The small image used as a repeating background

That was easy enough; we now have a variable called img that references our image
file. The second step is to set that image as a pattern to be utilized by the <canvas>

tag:

var myPattern = smileCtx.createPattern(img,'repeat');
smileCtx.fillStyle = myPattern;

To accomplish this, we used a canvas method called createPattern. This requires

two parameters: the first is the reference to the image file, and the second is our

DOMstring repetition. Similar to a CSS implementation, we can set the DOMstring
repetition to repeat, repeat-x, repeat-y, or no-repeat. If no value is specified, it
defaults to repeat.

Now let’s put all of this together and see what it looks like. Here is a view of the code
used to generate our smiley face with the image as a background:

var mySmile = document.getElementById('mySmile4')
var smileCtx = mySmile.getContext('2d');

// create new image object to use as pattern
var img = new Image();
img.src = '/assets/img/heart.png';
// create pattern

CHAPTER 4: HACKING YOUR GRAPHICS WITH CANVAS AND SVG 173

var myPattern = smileCtx.createPattern(img,'repeat');
smileCtx.fillStyle = myPattern;
smileCtx.arc(100,100,99,0,Math.PI*2); // head
smileCtx.stroke();
smileCtx.fill();

smileCtx.beginPath(); // Mouth
smileCtx.moveTo(170,100); // Left eye
smileCtx.arc(100,100,70,0,Math.PI);
smileCtx.stroke();
smileCtx.beginPath();
smileCtx.fillStyle = 'black';
smileCtx.moveTo(60, 65);
smileCtx.arc(60,65,12,0,Math.PI*2);
smileCtx.fill();

smileCtx.beginPath(); // Right eye
smileCtx.moveTo(140,65);
smileCtx.arc(140,65,12,0,Math.PI*2);
smileCtx.fill();

If we were to run this code, we would probably be disappointed with the results. In
most cases, our smiley face would look like Figure 4-11.

Figure 4-11.
The smiley face canvas rendering with the background image set as in the previous code sample

174 HTML5 HACKS

Can you identify the problem? Think about the load time. The canvas is taking ad-
vantage of real-time data. In the preceding sample, we created the image and then
set it as a background immediately. Since the pattern failed, the canvas fill reverted
back to its default state of black for the fill color. The problem has to do with the
availability of the image data, which in our case hasn’t been loaded yet.

To solve this problem we will add a few lines of JavaScript that wait for the image to
load before we execute the necessary canvas code. Browsers have supported the

image onload event for years. In this example we’ll use the image onload event to

know when we have the necessary data loaded:

var mySmile = document.getElementById('mySmile4')

var smileCtx = mySmile.getContext('2d');

// create new image object to use as pattern
var img = new Image();
img.src = '/assets/img/heart.png';
img.onload = function(){

// create pattern
var myPattern = smileCtx.createPattern(img,'repeat');
smileCtx.fillStyle = myPattern;
smileCtx.arc(100,100,99,0,Math.PI*2); // head
smileCtx.stroke();
smileCtx.fill();

smileCtx.beginPath(); // Mouth
smileCtx.moveTo(170,100);
smileCtx.arc(100,100,70,0,Math.PI);
smileCtx.stroke();

smileCtx.beginPath(); // Left eye
smileCtx.fillStyle = 'black';
smileCtx.moveTo(60, 65);
smileCtx.arc(60,65,12,0,Math.PI*2);
smileCtx.fill();

smileCtx.beginPath(); // Right eye
smileCtx.moveTo(140,65);
smileCtx.arc(140,65,12,0,Math.PI*2);
smileCtx.fill();
}

CHAPTER 4: HACKING YOUR GRAPHICS WITH CANVAS AND SVG 175

Now we’re sure that our image data has loaded, and the <canvas> tag can take full

advantage of the image for use in its pattern background.

Easy Image Data

Adding image onloads around whole segments of code can sometimes be cumber-

some. A nice shortcut available in HTML5 browsers is the use of inline image data. We

can easily remove the onload event from the preceding example and simply reference

the image data. Since the image data was loaded when the page was loaded, there is

no need to wait for the onload event to fire before we attempt to use the image. Our

new code would look like this:

var mySmile = document.getElementById('mySmile5')
var smileCtx = mySmile.getContext('2d');

// create new image object to use as pattern
var img2 = new Image();
img2.src = 'data:image/png;base64,iVBORw0K... image data here
...f5v038BfQ3g/3mcvqgAAAAASUVORK5CYII=';

// create pattern
var myPattern = smileCtx.createPattern(img2,'repeat');
smileCtx.fillStyle = myPattern;
smileCtx.arc(100,100,99,0,Math.PI*2); // head
smileCtx.stroke();
smileCtx.fill();

smileCtx.beginPath(); // Mouth
smileCtx.moveTo(170,100);
smileCtx.arc(100,100,70,0,Math.PI);
smileCtx.stroke();

smileCtx.beginPath(); // Left eye
smileCtx.fillStyle = 'black';
smileCtx.moveTo(60, 65);
smileCtx.arc(60,65,12,0,Math.PI*2);
smileCtx.fill();

smileCtx.beginPath(); // Right eye
smileCtx.moveTo(140,65);
smileCtx.arc(140,65,12,0,Math.PI*2);
smileCtx.fill();

176 HTML5 HACKS

It may not make sense to utilize the Base64 version of your image in all cases, since
it results in added weight in the initial page load, but sometimes it may be appropriate
in order to utilize and simplify your code. It’s a good practice to have multiple imple-
mentation methods to choose from.

HACK 40 Use the HTML5 <canvas> Tag to Create
High-Res, Retina-Display-Ready Media

When Apple first introduced the Retina display on the iPhone 4, parts of the Web
started to look pretty shabby. The display’s higher resolution made your quick-loading
“web-ready” images look pixelated. In general, higher-resolution images mean longer

load times. This hack uses the HTML5 <canvas> tag to provide Retina-ready imagery

without the added weight.

There is a problem with our Retina screens. They look great (few people will debate
that), but the way in which they accomplish this has caused a lot of problems for web
developers. Apple first introduced the Retina display with the iPhone 4, in an attempt
to solve two problems: create a display in which the pixels were indistinguishable to
the naked eye, and not make iOS and Apple apps look like crap. To do this, Apple
marked the pixel density much higher than was necessary, and in fact gave the display
a density that was evenly divisible by the previous iPhone screen density. This enabled
Apple to update all the visual assets of the iOS SDK and the iOS operating system to
a higher resolution, and simply downsize it for older, less dense screens. For all the
other assets in the Apple apps, the company used a method called pixel doubling to
help the assets remain at the proper size.

Assets such as images and media on the Web fall prey to pixel doubling. This makes
our web pages look pixelated and jagged. The common solution to this problem is to
utilize images with twice the pixel resolution, which leaves us with images that are
larger and web pages that take significantly longer to load.

In Comes the <canvas> Tag

The <canvas> tag is a drawing space for vector illustrations. Since the <canvas> tag

is created using a set of definitions, the size of the illustration is inconsequential to
the amount of data that is necessary to create it (unlike images that required the
transfer of additional data to accommodate more pixels). This being the case, we can

make our <canvas> tag Retina-ready without any additional page weight.

Let’s start by loading a simple example of a smiley face drawn out on a 200 × 200-

point <canvas> tag. Here is the code for creating our example:

var mySmile = document.getElementById('mySmile2')
var smileCtx = mySmile.getContext('2d');

CHAPTER 4: HACKING YOUR GRAPHICS WITH CANVAS AND SVG 177

smileCtx.beginPath();

smileCtx.fillStyle = '#F1F42E';
smileCtx.arc(100,100,99,0,Math.PI*2); // head

smileCtx.stroke();
smileCtx.fill();

smileCtx.beginPath(); // Mouth
smileCtx.moveTo(170,100);
smileCtx.arc(100,100,70,0,Math.PI);
smileCtx.stroke();

smileCtx.beginPath(); // Left eye
smileCtx.fillStyle = 'black';
smileCtx.moveTo(60, 65);
smileCtx.arc(60,65,12,0,Math.PI*2);
smileCtx.fill();

smileCtx.beginPath(); // Right eye
smileCtx.moveTo(140,65);
smileCtx.arc(140,65,12,0,Math.PI*2);
smileCtx.fill();

Our smiley face looks great on a standard display, but it’s pretty jagged on the Retina
display. Figure 4-12 shows how our canvas image looks on the iPhone 3Gs and the
iPhone 4.

178 HTML5 HACKS

Figure 4-12.
The canvas image displayed on the iPhone 3GS (left), and on the iPhone 4 with a Retina display
(right)

In order to have the illustration be smooth for the Retina display, we need to counteract
the pixel doubling that is taking place. To accomplish this, we will add a few simple
lines of code to our JavaScript:

if(window.devicePixelRatio == 2) {
mySmile.setAttribute('width', 400);
mySmile.setAttribute('height', 400);
smileCtx6.scale(2, 2);
}

We will insert this into our code right after we declare our context, but before we start

to apply our elements to the <canvas> tag. In essence, we have detected when pixel

doubling is being applied (by checking the device pixel ratio) and then doubled the

size of our <canvas> tag. These lines of code will result in the big, fat smiley face shown

in Figure 4-13.

CHAPTER 4: HACKING YOUR GRAPHICS WITH CANVAS AND SVG 179

Figure 4-13.
The smiley face twice the size it was before, thanks to the new JavaScript code

Now we need to rescale our <canvas> tag to fit our original page space. In order to

have the page render all the pixels in half the size, we will set our canvas to 400 and
then use CSS to shrink it back down to 200 px. Let’s add this CSS to the top of our
page:

#mySmile{
height: 200px;
width: 200px;

}

With just a few lines of code we have essentially Retina-enabled our <canvas> tag

without having to increase the page weight significantly. Let’s go back to our iPhone
3GS–iPhone 4 comparison to see our results (see Figure 4-14).

180 HTML5 HACKS

Figure 4-14.
The canvas image displayed on the iPhone 3GS (left), and on the iPhone 4 with a Retina display after
the addition of the new JavaScript code

We’ve improved the experience for our Retina-display users without affecting the rest

of our user base. You can apply this technique to any <canvas> tag, whether it is a

page illustration or a canvas element used as a CSS background image. The only time
you will not benefit from using this technique is when you import an image into your

<canvas> tag that doesn’t support the Retina display’s higher resolution.

HACK 41 Accelerate Animation with
Canvas Drawings

Use of the <canvas> tag is often one of the most efficient ways to create animations

in your web applications. This hack digs into the nitty-gritty of creating animations

while using the <canvas> tag.

Clean animation can make or break your web applications. Native applications on
desktop and mobile devices have raised users’ expectations: if your web application
fails to include clean, concise animations, users will often write it off as being a poorly
performing app.

Canvas animation can be a powerful tool for web animations. As more and more
browser makers enable the GPU for canvas animations, it becomes even more ben-
eficial to perform your animations with a canvas element.

CHAPTER 4: HACKING YOUR GRAPHICS WITH CANVAS AND SVG 181

Write and Clean
Animation on a <canvas> tag is reminiscent of early cartoon animations where each

frame is drawn out and then displayed in the correct order and at the determined
frame rate. Canvas animation basically consists of these three steps:

1. Draw on the canvas.
2. Erase what you just drew.
3. Repeat steps 1 and 2 until the animation is complete.

In JavaScript, when things need to be called over and over again we often use methods

such as setTimeout and setInterval to call our drawing methods. The problem

with each of these methods is they need to be set to a specific amount of time. If we
set that time to, say, 100 milliseconds, we would never be able to achieve a frame rate
higher than 10 frames per second.

A powerful new standard has been introduced to address this issue with the <can
vas> tag: the requestAnimationFrame method. With this method, you are asking

the browser to render the next frame as soon as it is available for rendering, as op-

posed to attempting to render at a fixed interval. The goal of requestAnimation
Frame is 60 frames per second, but it doesn’t fail if it can’t render that quickly; it simply

renders as soon as it can. Note that this method isn’t limited to use in canvas anima-
tions; it’s available for any web drawing technology, including WebGL.

Smile, You’re Being Animated!

Let’s take a good look at an example of a canvas animation. If you’ve worked your way
through the previous hacks in this chapter you have seen the smiley face examples.
Each example drew the smiley face on a 200 × 200 canvas element. For this illustration
we will draw it on a much larger canvas to give us room to move. Let’s start by dropping

our <canvas> tag onto the page:

<canvas id="moveSmile" width="800" height="200"></canvas>
Now that we have a big, fat, blank canvas, we will draw the smiley face on top of it. To
do this, we’ll pull in a few lines of JavaScript to build our page elements:

182 HTML5 HACKS


Click to View FlipBook Version