Chrome touchcancel event & scrolling instead of touchmoving

When you’re devel­op­ing for Chrome for Android, one of the little quirks is that some­times your touch­move events appear to stut­ter and get can­celled almost imme­di­ately. This is evid­ent when you’re try­ing to pan or slide a can­vas, except the Chrome for Android stops after 300 ms and starts scrolling the page instead.

This is actu­ally by design due to the way Chrome pre­vents pages from break­ing scrolling, and it’s fairly easy to fix by call­ing event.preventDefault() in your touch­move handler.

myElement.ontouchmove = function(e){
    // Do things
    e.preventDefault();
}

Using Pixi.js

Pixi.js is a pretty cool low-level game engine that uses Canvas or WebGL to render 2D graphics.

Pixi.js doesn’t give you dir­ect access to the ori­ginal event, so if you’re try­ing to drag ele­ments on a Pixi can­vas, call­ing preventDefault() on your event gives you a func­tion not defined error.

Pixi actu­ally passes the ori­ginal event as e.originalEvent, so for Pixi touch­move events you should use the fol­low­ing code;

myPixiElement.touchmove = function(e){
    // Do things
    e.originalEvent.preventDefault();
}

Further read­ing

For more inform­a­tion on why Chrome is break­ing the touch­move hand­ler, check out Wilson Page’s dis­cov­ery of the 300 ms touch­move can­cel­la­tion or more gen­er­ally the HTML5Rocks touch and mouse primer.

Installing NPM packages globally on Windows

For some reason (per­haps in multi-user envir­on­ments) a default install of Node on Windows may not put the cor­rect NPM global pack­age loc­a­tion in the path.

If you’re hav­ing issues like the following:

'grunt' is not recognized as an internal or external command,
operable program or batch file.

Where Grunt might be any global pack­age, such as Browserify, add the fol­low­ing loc­a­tion to your path:

Windows 7: C:\Users\{username}\AppData\Roaming\npm

Replace {username} with your cur­rently logged in user.

This should make global Node mod­ules dis­cov­er­able and usable on your system.

Interactive SVG and the ABC NRL Infographic

I recently worked on an infographic for ABC Grandstand Sport, show­ing an accu­mu­lated field of all the scores for each of the NRL grand finalists.

The Tech

The infographic uses a plain SVG file and a small amount of Javascript to per­form the task. The imple­ment­a­tion is actu­ally quite simple, with most of the heavy lift­ing to gen­er­ate the graphic being done on my PC before being uploaded to the server as a static SVG.

The ini­tial stages of the pro­ject involved access­ing the data and turn­ing it into some­thing we could visu­al­ise. I wrote a Node script to access the SportsFlash API and pull down every game of the sea­son. From there I cre­ated a Fiddle to do up some quick visu­al­isa­tions show­ing how the points relate to each other.

From there my col­leagues Ben and Lincoln dis­cussed how best to present the inform­a­tion, and worked on some actual designs.

Designing with SVG

Ben used Fireworks to cre­ate a few dif­fer­ent SVG vari­ations includ­ing all the line mark­ings to scale and a back­ground pat­tern we could repeat to save on bandwidth.

Fireworks out­put to SVG where I used Inkscape to make a few changes includ­ing cre­at­ing some empty group ele­ments for the auto-generated con­tent I was going to add later.

Adding the Data

I wrote another Node script to san­it­ise all the data from the SportsFlash API and sep­ar­ate out the two teams’ plays onto either side of the field.

Once the data was sor­ted it was a fairly simple mat­ter of cre­at­ing a circle ele­ment for each point, as well as a path link­ing each con­nec­ted dot together.

These were placed in two sep­ar­ate groups for convenience.


<circle r="7" cx="836" cy="406" id="t-1-e-3-0" class="first t-1-e-3" fill="maroon"><title>Round 14 - Try scored by Jorge Taufua  (vs Canterbury-Bankstown Bulldogs)</title></circle>

Styling and Interaction

SVG is styleable with CSS so we could tweak the design on the fly, and even­tu­ally settled on what you see here.

Traditionally we’ve used client-side code such as D3 to imple­ment inter­act­ives and infograph­ics. This time the SVG was already gen­er­ated so all it needed was a couple of onclick events to change change the CSS when someone clicked/hovered a point.

This meant there was actu­ally very little code required to imple­ment the inter­ac­tion, and pos­sibly points to the abil­ity to add anim­a­tion and inter­activ­ity to design-heavy infograph­ics in the future.

Browser Support & jQuery

Because we’re using SVG for this infographic, it only sup­ports IE9 and above. We added altern­at­ive con­tent for older browsers in the form of a static image, which is rel­at­ively easy to add using the <object> tag.

<object width="100" height="100" data="myfile.svg">
    <img src="myfile.png" alt="The roosters prove the long range threat."/>
</object>

One of the gotchas that I hit at the last minute was my use of jQuery didn’t work prop­erly with the external SVG file. We’re using an old ver­sion which doesn’t sup­port SVG well at all, so I had to rewrite bits of code to use the document.querySelectorAll call.

In future I won’t be using jQuery for SVG inter­act­ives because newer ver­sions of Javascript sup­port cool stuff like forEach, indexOf and querySe­lector, and there’s no need to sup­port older browsers in this case. Furthermore, pure Javascript can be included inside the SVG file which means more port­ab­il­ity and less dependencies.

Conclusion

While there’s a few things I’d do dif­fer­ently next time, I’m pretty happy with the res­ult here. The end product is a stan­dalone, inter­act­ive graphic that we can reuse elsewhere.

The browser sup­port is fairly good for this kind of thing these days, and the abil­ity to spe­cify fall­back con­tent is great for those that don’t sup­port it. There’s really no reason not to be using SVG for these kinds of things.

Bugs and errata

The Race

One inter­est­ing bug I noticed was that Chrome calls the window.onload method before the SVG doc­u­ment has fully loaded. This only seems to hap­pen once the HTML doc­u­ment has cached and can be repro­duced by click­ing back and for­ward to reload the page from cache.

The fix isn’t straight­for­ward and I ended up adding a quick timeout on load, but optim­ally you’d be able to bind to a load event on the object. I’ll look into this and report back.

Adobe SVG

The Adobe SVG plu­gin presents prob­lems for devel­op­ing inter­act­ive SVG graphics.

With this plu­gin installed, a SVG doc­u­ment embed­ded using an <object> ele­ment doesn’t load in Chrome and falls back to whatever altern­at­ive con­tent you’ve specified.

Furthermore, even though the SVG doc­u­ment loads in IE it doesn’t present the same API as a reg­u­lar SVG doc­u­ment so it requires extra code to get working.

I haven’t found any real work­arounds for this other than unin­stalling the Adobe SVG viewer. This plu­gin was dis­con­tin­ued with XP in 2009 so it shouldn’t be used these days, how­ever I don’t have any mar­ket share stats for this one.

Apache & SVGZ

If you’re using Apache and want to use svgz files in your site, add this to your con­fig­ur­a­tion .htac­cess file:

AddType "image/svg+xml" .svgz
AddEncoding gzip .svgz

This firstly sets the content-type and secondly instructs the browser to unzip it once it’s downloaded.

Offline Apps

One of the things a lot of people don’t real­ise about web apps is that they don’t actu­ally have to run off a server. These days with little effort at all you can write a web app that runs dir­ectly on the tar­get com­puter which reduces infra­struc­ture costs and makes the app more respons­ive for the end user.

There are a num­ber of reas­ons you might make an off­line app, but it’s espe­cially use­ful in cases where web access may be lim­ited (kiosks, trade shows, etc), some­where imme­di­ate action might be required (such as point of sales sys­tems, doctor’s sur­ger­ies), or where the func­tion­al­ity just makes sense to per­form on the cli­ent side (such as cal­cu­lator apps, to do lists, image edit­ors etc).

How do I make an off­line app?

There’s a few tech­no­lo­gies that let you do this, for instance:

  • Web Stores such as the Chrome Web Store
  • Packaged desktop solu­tions like node-webkit and the now-defunct Adobe Air
  • Hosted, but off­line applic­a­tions delivered from your web­server using con­ven­tional meth­ods but cached for off­line use using AppCache.

I’m not going to focus on any par­tic­u­lar tech­nique, rather than go through some gen­eral tac­tics you can use to cre­ate a fully off­line app.

What’s an off­line app anyway?

An off­line app is exactly what it sounds like, it runs on your com­puter like a reg­u­lar app, regard­less of your Internet connection.

These apps use tech­no­lo­gies such as Javascript, local stor­age and cache mani­fests to keep the app on the cli­ent side. These apps can also be used to update data on the server but might util­ise cach­ing to save web requests until the user is online. The primary pur­pose of an off­line app doesn’t require an Internet con­nec­tion to run.

Offilne apps are denoted in the Chrome web store by a lightning bolt.

The Chrome Web Store denotes off­line apps with a light­ning bolt icon. You can tick a box when you pub­lish your app, put­ting “Offline” in the name is optional.

How to make my web app offline

There’s a bunch of tech­niques you can use, but the most basic one is ensur­ing all your applic­a­tion logic is executed in the browser, and that there are no server-side com­pon­ents (such as log-in, stor­age, processing).

A good start might be to make sure your app runs straight off your hard disk. If you can double-click your HTML file and your web app launches and oper­ates cor­rectly then there’s a good chance it’s going to work great as an off­line app. This isn’t a hard and fast rule though, as depend­ing on your plat­form you may have more or less func­tion­al­ity at your disposal.

Once your applic­a­tion is built, one of the more standards-based approaches is to use App Cache to instruct the browser to cache your app for off­line use.

Specific Technologies for Offline Apps

Some spe­cific tech­no­lo­gies exist that work really well for off­line web apps.

TechnologySupportDescription
AppCacheIE10+AppCache lets you spe­cify the files that need to run off­line. The browser caches these files for sub­sequent app loads.
Web StorageIE8+Web Storage lets you store per­sist­ant data with an inter­face akin to an asso­ci­at­ive array.
File APIsIE10+/Android 3+Read, manip­u­late and write files to disk. Especially use­ful in con­junc­tion witht he drag & drop API.

Of course there’s a bunch of other tech­no­lo­gies, both stand­ard and pro­pri­et­ary which you can use to make your web app rock on vari­ous plat­forms. If you don’t need gen­eral web sup­port, check out the doc­u­ment­a­tion for the web app stores or ren­der­ing engines you’re plan­ning to support.

Ultimately, the best way to make an off­line web app is to break the ties with that server-side code. It’s a shift in think­ing from tra­di­tional web devel­op­ment, but the pay­offs can be huge.

Practical SVG Manipulation for use in Games

I tried to do a demo of some of the SVG stuff I’ve been play­ing with recently at BrisJS, but due to a com­edy of errors I was unable to do much more than talk about it. So I figured I’d write up some of my find­ings here.

SVG in Canvas

Basically what I’ve been doing recently is exper­i­ment­ing with SVG sprites for use in HTML5 Canvas games.

SVG is an XML-based vec­tor image format that’s often used in graphs and inter­act­ive fea­tures, but it’s actu­ally really good as a graph­ics inter­change format for use in games because it can be manip­u­lated really eas­ily with Javascript.

Here’s a SVG image so you can check it out. You can inspect it in the DOM inspector which will show you the ele­ments and attrib­utes we can manip­u­late with JS.

I drew it in Inkscape, but because it’s all XML-based we can adjust the col­ours and styles of the image dynam­ic­ally in the browser.

A Quick Demo

I’ve put together a quick demo of the tech­nique which shows a basic col­our­ising of col­our mapped images such as the one above.

Changing the col­our of SVG images is a pretty simple fea­ture which people use all the time in reg­u­lar SVG oper­a­tions. Generally this might be used to cre­ate a rollover effect or adjust the col­our of a bar in a dough­nut graph, but with this demo you can choose two col­ours and use them to col­our­ise the entire SVG image.

Check it out at assets.kyd.com.au/svg-recolour/demo/demo.html

How it works

I’ve used the col­or­box lib­rary to per­form col­our modi­fic­a­tion oper­a­tions on the input col­ours to gen­er­ate high­lights and shades, which cor­res­pond with the vari­ous key col­ours in the source image.

I’ve then per­formed a basic string search and replace on the tar­geted col­ours to make the changes to the image so it uses the col­ours you’ve chosen rather than the ori­ginal col­ourmap. This some­thing that could very nicely be done with jQuery select­ors for instance, but isn’t some­thing I’ve had time to do yet.

  • 1-or8
  • 3-or8
  • 5-or8
  • 7-or8
  • 10-or8
  • 11-or8
  • 10-or8
  • 7-or8
  • 5-or8
  • 3-or8

The demo also has a game time fea­ture, which per­forms fur­ther col­our modi­fic­a­tions based on the in-game “hour” of the day. So for instance at mid­night the col­ours you ori­gin­ally chose would be heav­ily desat­ur­ated and tin­ted with a blue col­our to sim­u­late night time. In the even­ing, sun­set adjusts the col­ours to add oranges and reds before fad­ing into night.

The final fea­ture of the demo is a little logic which flicks lights on and off once it gets dark, and altern­ates neon signs on and off at intervals.

And then?

SVG tends to be a little slow in select browsers, and espe­cially so with com­plex images which you can prob­ably see in the demo. While this might be okay when you’re just dis­play­ing a static image, it becomes totally unac­cept­able in high-performance situ­ations where you need to draw it sixty times per second.

We can get around this issue by pre-drawing the SVG images to another Canvas object (not pic­tured). This off-screen Canvas holds a bit­map rep­res­ent­a­tion of the image and con­sequently renders to our game can­vas much faster because the heavy lift­ing has already been done.

We can take this a step fur­ther and render all the vari­ations of a par­tic­u­lar image if we have enough memory, res­ult­ing in a long ini­tial load but a fast game once it’s done.

As a side note, using this method trig­gers addi­tional secur­ity pre­cau­tions in the browser which may pre­vent you from per­form­ing some game-related tasks.

Where from here?

Ultimately I’d like to imple­ment this in my game engine and pro­ced­ur­ally gen­er­ate com­plex game worlds, but for now this is just a concept.

I’ve also been play­ing with trans­form­ing tex­tures and apply­ing them to objects within the SVG envir­on­ment as a sort of 2D tex­ture map­ping, but I’m not espe­cially happy with the res­ults so I think I’m going to stick with vec­tor graph­ics for now.

warehouse-toy

Anyway, if you like the idea you should totally have a play and see what you can come up with. You can also check out my code on GitHub if you’d like to see exactly what I’ve done.

A private key for specified extension already exists

So your Chrome app is ready to go? Awesome! You’re pack­ing it up to test on all your devices when sud­denly… A private key for specified extension already exists. Reuse that key or delete it first.

Pack Extension Error

The Pack Extension Error is actu­ally a pretty simple one to get around. It’s caused because the exten­sion has already been packed in the past, and Chrome auto­mat­ic­ally cre­ated a private key for the package.

The auto­mat­ic­ally cre­ated key has the same file­name as the folder you selec­ted, and is in the same par­ent folder as your exten­sion, You can choose to either delete it (and another will be cre­ated next build) or select the key from the dialog.

Chrome CRX Keys

Each Chrome app is signed with a key, and if you don’t spe­cify one it’s auto­mat­ic­ally cre­ated for you.

You can see from the com­mand line below that the pack-extension com­mand cre­ates both a crx (exten­sion) and a pem (key) file.

$ ls
build-chrome  build-chrome.sh  chrome.zip  libs
$ google-chrome --pack-extension=build-chrome/
Created the following files:
Extension: build-chrome.crx
Key File: build-chrome.pem
Keep your key file in a safe place. You will need it
to create new versions of your extension.
$ ls
build-chrome      build-chrome.pem  chrome.zip
build-chrome.crx  build-chrome.sh   libs

The next time we run the pack-extension com­mand above it will fail because we also need to spe­cify the --pack-extension-key para­meter like so:

$ google-chrome --pack-extension=build-chrome/ --pack-extension-key=build-chrome.pem

None of this is par­tic­u­larly obvi­ous from within Chrome itself, which just gives you the unhelp­ful Pack Extension Error dia­log box. It’s a fairly easy fix though, just hit “Browse…” and the pem file should be right there.

Chrome SecurityError: DOM Exception 18

Of the more cryptic and frus­trat­ing Chrome errors are the SecurityErrors. These bad boys show up at inop­por­tune times and ruin your day with an “Uncaught Error” and a big red excep­tion killing your code in its tracks.

So you’re play­ing around with HTML5 Canvas when all of a sud­den you’re get­ting a Uncaught Error: SecurityError: DOM Exception 18 in the con­sole. What’s it mean?

DOM Exception 18

This excep­tion is thrown when your code is try­ing to access some­thing it shouldn’t, includ­ing cross-domain resources or stuff on your local filesystem.

Once you hit this one you will either need to loosen your browser secur­ity set­tings which is never optimal, or find out how to work around it.

HTML5 Canvas & Exception 18

Which brings us to the case of the com­plain­ing can­vas. Loading images into your can­vas from another domain will “taint” your can­vas, mean­ing any attempts to read the can­vas back again will fail with this error.

This is because your Javascript adheres to a same-origin policy to increase secur­ity. It’s essen­tially done as a con­tain­ment meas­ure so that a rogue script can’t use your browser to access resources you’re authen­tic­ated against.

Hypothetical Canvas Attack

For instance, if I hypo­thet­ic­ally wanted to access your email and your browser didn’t pre­vent cross-site-scripting, I could per­form a $.ajax('http://gmail.com'). This would pull down your logged-in gmail page, and then I could send all your email mes­sages back to my server.

The same applies for images.

This fea­ture pre­vents a rogue site pulling down your Facebook pho­tos, for instance (which again could hypo­thet­ic­ally be done), ren­der­ing them to a can­vas in order to get a hold of the bin­ary image data then send­ing it back to the attack server.

So the second you draw a third party image to your can­vas, you can no longer read back the res­ult­ing image.

The easy solu­tion is to host all your images loc­ally or if that’s not pos­sible you could use a script to pull down and serve the images on your behalf.

SVG Image & Canvas SecurityError

If you’re play­ing around with draw­ing SVG to Canvas in Chrome, you may also run into this secur­ity error, but for a dif­fer­ent reason.

Chrome bombs out printing a SVG

This appears to be a Chrome-specific fea­ture (per­haps a bug?) whereby the SVG doc­u­ment is con­sidered to be of dif­fer­ent ori­gin to the can­vas. This goes a step fur­ther than simply check­ing the ori­gin of the url, it out­right black­lists all SVG images regard­less of ori­gin, includ­ing images encoded in data: uris.

This means that whenever you paint a SVG to your can­vas you’re taint­ing your can­vas and won’t be able to pull inform­a­tion back out of it. This severely hinders efforts to use SVG images as dynamic game sprites, and can be frus­trat­ing to debug because it isn’t imme­di­ately obvi­ous what’s happening.

Working around the same-origin policy

It’s actu­ally pos­sible to spe­cify a cus­tom policy to over­ride the default same-origin beha­viour. This is done via cus­tom HTTP head­ers, which means you’ll need access to your web server to make these changes.

I haven’t yet exper­i­mented with this tech­nique myself, but you can read about it on HTML5 Rocks. I’ll be play­ing with this in the fol­low­ing days, but if you’ve had luck with this tech­nique, do let me know in the comments.

SVG images on a HTML5 Canvas

I wrote a while back about using SVG sprites in a HTML5 Canvas game, but there’s actu­ally a bet­ter way of doing it that doesn’t involve an external JavaScript lib­rary like canvg.

Rendering SVG to a HTML5 Canvas

It’s trivi­ally easy to load up a SVG image as a JavaScript Image ele­ment and draw that to the can­vas. There’s a few ways you can do this, with the easi­est being:

var source = new Image();
source.src = 'http://example.org/myfile.svg';
source.width = '100';
source.height = '100';

This example loads the source file into a new Image ele­ment, ready to be applied to a Canvas the same as any other image.

This takes the hassle and unpre­dict­ab­il­ity out of using a third party lib­rary because it uses the nat­ive browser’s SVG cap­ab­il­it­ies, and will prob­ably be faster to boot.

There are still a few quirks when it comes to load­ing SVG images this way, in par­tic­u­lar the browser may not get the width and height right. In the example above we’ve hard-coded the dimensions.

Actually Rendering to a Canvas

To actu­ally draw a SVG image to a can­vas, it’s the same as any other Image object.

// Set up our canvas on the page before doing anything.
var myCanvas = document.createElement('canvas');
myCanvas.width = 640;
myCanvas.height = 480;
document.getElementsByTagName('body') [0].appendChild(myCanvas);
// Get drawing context for the Canvas
var myCanvasContext = myCanvas.getContext('2d');
// Load up our image.
var source = new Image();
source.src = 'http://example.org/myfile.svg';
source.width = '100';
source.height = '100';
// Render our SVG image to the canvas once it loads.
source.onload = function(){
	myCanvasContext.drawImage(source,0,0);
}

This code loads the SVG image, cre­ates an image in the <body> and renders the SVG to the Canvas ele­ment. The onload is import­ant because it makes sure the image has com­pletely loaded before try­ing to draw it.

Rendering Dynamically Created SVG

If you’re going to be dynam­ic­ally cre­at­ing or modi­fy­ing your SVGs, this tech­nique won’t work.

Any SVG ele­ments loaded as Images no longer have a DOM access­ible for you to manip­u­late, so you will need to pre-load the SVG file and manip­u­late it prior to load­ing it in an Image. You can use any num­ber of tech­niques here such as XHR which I won’t go into.

The dif­fi­cult bit is load­ing the mod­i­fied SVG string back into an Image in order to plop it down onto a can­vas. The solu­tion to this is base64 encod­ing the image and cre­at­ing a Data URI.

The fol­low­ing code will cre­ate a data URI by base64 encod­ing the SVG string:

// My SVG file as s string.
var mySVG = '<svg […]';
// Create a Data URI.
var mySrc = 'data:image/svg+xml;base64,'+window.btoa(mySVG);
// Load up our image.
var source = new Image();
source.src = mySrc;

The btoa func­tion is a nat­ive func­tion to encode a string to base64, but is not offi­cially stand­ard­ised yet. It is a part of the WHATWG liv­ing stand­ard and is sup­por­ted in all SVG/Canvas-capable browsers with the excep­tion of IE9. If you require back­wards com­pat­ib­il­ity or IE9 sup­port there are count­less base64 lib­rar­ies out there you can use instead.

Some Caveats to using SVG on a Canvas

This tech­nique is great provid­ing you don’t require sup­port for IE8, in which case you’re out of luck and should look into using a third party ren­der­ing lib­rary in con­junc­tion with a Canvas shim.

If you’re only look­ing at tar­get­ing mod­ern browsers like Android 3+ and IE9+ this tech­nique will work per­fectly and give you the power and speed of the browser’s nat­ive SVG implementation.

Learn Chrome Dev Tools

Have you always wanted to learn how to use the developer tools in your web browser? Or do you want to learn the ins and outs of debug­ging your sites?

CodeSchool have released a fant­astic range of tutorial videos and inter­act­ive quizzes designed to teach you how to use and make the most of the Chrome dev tools inter­act­ively by modi­fy­ing the tutorial code your­self. It’s really quite clever.

Discover Devtools

The Devtools course fea­tures sev­eral chapters, each tak­ing you through a series of videos and quizzes which teach you to use a skill then assess your know­ledge from within the browser.

  • Check out these Chrome Devtools tutorials.
  • Each tutorial comes with a video and a quiz.
  • The tutorials are HTML based and work with the live developer tools.

The early quizzes work straight up, but more advanced ones such as the source edit­ing, pro­fil­ing and debug­ging require a Chrome plu­gin to track your progress.

If you’re work­ing on Javascript game devel­op­ment, you should def­in­itely check this out for the chapters on per­form­ance and pro­fil­ing. Even if you’re a vet­eran developer, you may still learn a thing or two, so check it out.

CodeSchool

CodeSchool is an ini­ti­at­ive to teach you web devel­op­ment lan­guages and tech­niques from the com­fort of your own browser. It fea­tures a num­ber of classes from web design to pro­gram­ming and is a great way to learn new skills by exper­i­ence.