Tony’s Technical Blog

Collection of useful resources and technical documents

NOTE: To preview some of the links included in this article you will need to be on an HTML5/SVG compliant browser. i.e. Webkit based (Chrome,  Safari) or Gecko (Firefox 3.5+), you’re on IE (Trident) ? Don’t even bother clicking on the links !


With a lot of  recent articles proclaiming that, with the imminent release of HTML5 will also come the death of Flash, I figured I’d start doing some reading around.  I know the W3C are still drafting HTML5 standards (Version as of Mar 4th, 2010), but it’s close. Very close. Browsers are hedging their bets on what will be included and slowly we’re seeing adoption of some core HTML5 spec’s, most notably in Webkit based browsers (Chrome and Safari).

For me; the introduction of HTML5 will introduce many new HTML tags, some exciting new Javascript events (like native drag and drop!), but I think, of ALL of these features none will be as widely adopted, or as expansive, as the humble <canvas> tag.

A container, a Flash ’stage’ if you will for the sake of analogies. To quote:

…is only a container for graphics, you must use a script to actually paint graphics
http://www.w3schools.com/html5/tag_canvas.asp

With recent Javascript library developments from Mootools, jQuery, YUI, even the BBC’s own “Glow!” (to name just a few) we are seeing next generation Javascript (or if we’re being trendy “Web2.0″) that rivals some of Flash’s mainstream tweening capabilities. DOM and JavaScript Library mash-ups have exposed a new era of creativity. SEO compliant interfaces that lift content into a new dimension.

That humble canvas tag is going to extend that concept way beyond what I’d previously imagined possible. SVG (Scalable Vector Graphic) mash-ups created with Inkscape for example. Literally being able to compose SVG output that can be sucked straight into a canvas with CAKE (not to be confused with a well known MVC framework for PHP), but rather the Canvas Animation Kit Experiment, already developing next-NEXT generation Javascript frameworks to compliment HTML5 canvas painting.

For example it’s SVGParser() class…


SVGParser.load('cakenu3.svg', {
width: 1024,
height: 768,
onSuccess: this.initDesign.bind(this),
onFailure: function(xhr, e){ console.log(arguments) }
})

Inkscape SVG output:  http://glimr.rubyforge.org/cake/cakenu3.svg (View Source for example SVG output).

Just think of SVG definitions as a cross between HTML imagemap’s and XML, but on steroids! The ability to define glyphs for typographic freedom. No more font constraints. Typographic freedom ? (We’ll see how the font houses (Adobe)) feel about that!

Vector graphics and the canvas tag. Enough to ‘kill’ Flash? We’ll see, but enough with the waffle. Show me some examples! Here you go, but remember; for optimum output view these on the latest Webkit based (support for HTML and SVG) browsers (Chrome/Safari).

HTML5/JavaScript and Canvas Animation Examples:

Further Reading:

Beyond The Canvas Tag

Google have taken SVG graphics and the capabilities of the canvas tag to new heights. With the installation of their O3D plugin it is possible to animate 3D objects directly within the browser. This is an absolutely amazing demo’ and with just a little bit of imagination the possibilities that this can lead to are endless!

http://o3d.googlecode.com/svn/trunk/samples/beachdemo/beachdemo.html

I was just sitting here watching the presentation Steve Jobs gave earlier today announcing the release of Apple’s latest device in it’s “i-series”; the iPad. As I sat watching a relaxed Jobs recline in a chair on stage, whizzing through one of the devices very first ‘apps’; the “New York Times”, whilst his every move was relayed onto a larger screen for the audience, I couldn’t help but think to myself that the skeptics out there who are already doubting the need for a third category of device between laptops and PDA’s could actually have it wrong.

It’s not a third category, I think it will replace a category, completely redefine it. Think about it. What do most people use their laptop’s for. Email and Surfing the Web. Writing content on blogs, using Facebook.

I can do all that on the iPad, why would I want to use a mouse. Even hardcore business applications such as MSOffice and specialist technology apps like lightwave and Adobe’s CS suite. To be able use my finger as the mouse, to touch, to draw, to point rather than click. I think I’d rather do that. The User Interface for the iPhone/iPad is simple, intuitive. Clean; none of the extravagance typical OS’s burden you with. A brilliant concept seen in Google Chrome, no bells and whistles… just web-browsing!

Our CEO mentioned two keywords in an earlier meeting this year: ‘Simple’ and ‘Response’, give the user what they want. Those words have stuck. Apple have done just that. A simple device that delivers response. No fluff! I honestly think that good, well designed tablet devices will replace the laptop. That’s my theory anyway!

So plugins. I came across an interesting problem today. How DO you detect browser plugins? In particular Adobe’s Acrobat Reader. I needed to disable a feature of my application if the plugin wasn’t installed.

Well it turns out that Javascript has quite a nifty little function for that as part of the navigator() object. window.navigator.plugins. An array of plugin objects. Each with a name, description and filename (navigator.plugins[i].filename), simply look for it in the plugins collection, right?

Well; not quite. Introduce our arch-nemesis, Internet Explorer. In typical fashion they have not fully implemented this model. They support the plugins collection, but it’s populated with empty data. Well that’s just great now isn’t it. As an alternative the answer is to use some VBScript to try and create an Acrobat Reader ActiveX object, if that fails, assume it isn’t installed, but this causes a whole set of problems for other browsers that would potentially ‘wig’ out on some of our VBScript. OK, so the answer to that… A simple userAgent check….


# if( navigator.userAgent.indexOf('MSIE') != -1 ) {
//write the VBscript
} else {
//use navigator.plugins
}

… man the things we do for IE! So to put it all together if IE use VB to detect else simply refer to the plugins array. Ta Da!… So to put it all together. I have to admit this is a modified version of the example found buried on the Adobe web server. Which in itself is based on a document written by Apple on the subject.

<?php if(!$bCheckedForAcrobat): // If not already detected, detect PDF Plugin... ?>
/*    DETECT IF PDF READER PLUGIN IS INSTALLED. NEEDED FROM PREVIEW */
// initialize global variables
var bVBDetected = false;
var bPluginFound = false;

function canDetectPlugins() {
if( bVBDetected || (navigator.plugins && navigator.plugins.length > 0) ) {
return true;
} else {
return false;
}
}

function detectPDF() {
bPluginFound = detectPlugin('Adobe','Acrobat');
if(!bPluginFound && bVBDetected) {
bPluginFound = detectActiveXControl('PDF.PdfCtrl.5');
}
return bPluginFound;
}

function detectPlugin() {
var aPluginArguments = detectPlugin.arguments; // Allows multiple checks in a single 'pass'.
var bPluginFound = false; // Considered false until proven true...
if (navigator.plugins && navigator.plugins.length > 0) {
var iTotalPlugins = navigator.plugins.length;
for (i=0; i < iTotalPlugins; i++ ) { // Foreach plugin found loop through and check name.
var iFoundPlugins = 0;
for(j=0; j < aPluginArguments.length; j++) {
if( (navigator.plugins[i].name.indexOf(aPluginArguments[j]) >= 0) || (navigator.plugins[i].description.indexOf(aPluginArguments[j]) >= 0)) {
iFoundPlugins++; // if desired plugin name is found in either plugin name or description
}
}

if(iFoundPlugins == aPluginArguments.length) {
bPluginFound = true;
break;
}
}
}
return bPluginFound;
}

// VBScript for MSIE only.
if ((navigator.userAgent.indexOf('MSIE') != -1) && (navigator.userAgent.indexOf('Win') != -1)) {
document.writeln('<script language="VBscript">');
document.writeln('\'do a one-time test for a version of VBScript that can handle this code');
document.writeln('bVBDetected = False');
document.writeln('If ScriptEngineMajorVersion >= 2 then');
document.writeln('  bVBDetected = True');
document.writeln('End If');
document.writeln('\'this next function will detect most plugins');
document.writeln('Function detectActiveXControl(activeXControlName)');
document.writeln('  on error resume next');
document.writeln('  bVBDetected = False');
document.writeln('  If bVBDetected Then');
document.writeln('     detectActiveXControl = IsObject(CreateObject(activeXControlName))');
document.writeln('  End If');
document.writeln('End Function');
document.writeln('</scr' + 'ipt>');
}

if(canDetectPlugins() && !detectPDF()){
window.location='index.php?a=0';
}
<?php endif; ?>

Further Reading