Recreating the Apple Watch UI using a hexagonal grid

Building on the hexagonal grid from earlier, I have added a little JavaScript and have created an effect similar to the Apple Watch home screen UI.

Below is a video of it in action, I am using IE11 (metro version) on a Surface Pro 2 which I found to be the most performant for this effect. Chrome was janky as hell, and Safari on the iPad doesn’t like to do things while scrolling.
READ MORE

Triggering a ‘finish’ event on an external video with Storyline HTML5

If you have at some point needed to use Articulate Storyline – you have probably come to a point where you want to murder everyone around you (not literally of course!) due to its ridiculous, quirky limitations. More often than not I find myself hacking the published code to make things works how I want.

One of the big limitations in Storyline is video – if you want to trigger something when the video starts or finished you must use the built in player. But the built in player cannot load videos from an external site (such as a streaming server – a common requirement) so you are left with using the ‘video embed code’ option, which doesn’t seem to allow custom embed codes – all I could get to work was YouTube and Vimeo. And even if you can get this to work you can’t add triggers to it for when the video ends.

I found a little hack which uses the Web Object and a custom video player in a HTML page. You can listen for the video complete event in the custom player then change a variable in the Storyline player. Then in Storyline add a trigger for when that particular variable changes, which will be when the video finishes.

Here’s how to do it.
READ MORE

Accessing command line arguments with Grunt

I needed to be able to set up a watch task with Grunt to only watch a specific client sub directory. This directory would change depending on the client I was working on and new clients were constantly added so I need a way to watch the specific client that I was working on only, without hard coding all the clients into separate tasks. The only thing I could think of doing this was to pass some sort of parameters when starting the watch task.

This is how I set it up. It might not be the best method but it works for me.

First I had to set a value in the grunt configuration, which would be taken from the command line args. With Grunt you can get them them using:

1
grunt.option('someCommandLineArg');

You can also set a configuration value using:

1
grunt.config.set('myValue', 'someValue');

So combining those two methods, the following will get a command line arg called “watchDir” (and assign a default value of src if it was not specified) and set it in the grunt config. I added this line after initConfig in my Gruntfile:

1
grunt.config.set('watchDir', grunt.option('watchDir') || 'src');

You can then access this property using a template string in your task:

1
2
3
4
5
6
watch: {
      less: {
        files: ['clients/<%= watchDir %>/**/*.less'],
        tasks: ['less']
      }
}

When running the Grunt task, we can specify the option “watchDir” by adding two dashes in front and setting it equal to the desired value:

1
grunt watch --watchDir="clientX"

The watch task above would in this case watch the following directory:

1
'clients/clientX/**/*.less'

This allows you to set up a generic task that can be pointed to different directories when it is started.

Local AJAX calls with IE11

Here is a little snippet to get local AJAX (with jQuery) working when running content locally in IE 11. Local content is not allowed to use the XMLHttpRequest but it can use the proprietary ActiveXObject, so this tells jQuery to always use the ActiveXObject if it’s available.

I needed to use this to run local content on a Surface RT which doesn’t have IIS or any other browsers. This allowed me to run content that relied on AJAX from the desktop in IE modern.

1
2
3
4
5
6
7
8
9
10
11
$.ajaxSetup({
    xhr: function()  {
        if ('ActiveXObject' in window) {
            return new ActiveXObject("Microsoft.XMLHTTP");
        }
        else
        {
            return new XMLHttpRequest();
        }
    }
});

Javascript voice control

Since Chrome 25 we have had access to the new Web Speech API which allows us to create web apps that can utilse voice to text or voice control with a microphone. I have been wanting to experiment with this for quite a while so I built simple example to using voice commands to control an e-learning module made with my e-learning framework. I recorded a video below demonstrating navigation through voice commands. After the video I will show show you how easy it is to set up this basic control.

The following link provides a tutorial on implementing a speech to text example: http://updates.html5rocks.com/2013/01/Voice-Driven-Web-Apps-Introduction-to-the-Web-Speech-API

To use speech recognition for voice commands, this is how I implemented it:

1. Create a new speech recognition object

1
var recognition = new webkitSpeechRecognition();

2. Make the object continuously check the microphone

1
recognition.continuous = true;

3. Set the language to use. By default it will use the document’s language

1
recognition.lang = "en-AU";

4. Start the speech recognition

1
recognition.start();

5. Get results on the ‘onresult’ event

1
2
3
4
5
6
7
8
9
10
11
recognition.onresult = function (e) {
    // loop through the results
    for (var i = e.resultIndex; i < e.results.length; ++i) {
        // only get the final results
        if (e.results[i].isFinal) {
            // trim any whitespace from result and pass to our command handler
            // note: I am using jQuery here to trim the string because my e-learning demo already had jQuery included
            runCommand($.trim((e.results[i][0].transcript).toLowerCase()));
        }
    }
};

6. Set up a function to handle the commands

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function runCommand(command){

    switch (command) {
        case "alert" :
            alert("Hello");
            break;
        case "prompt" :
            prompt("Enter some text");
            break;
        case "confirm" :
            confirm("Confirm?");
            break;
    }
}

Creating a mathematical colour picker

The most common technique for creating a colour picker (at least in the ActionScript world) seems to use a colour wheel bitmap and then getting the colour of the pixel that was clicked on. I found that this was not a very accurate way to go about it and decided to build a colour picker that gave colours based on calculations in a HSV cube – Hue on the Z axis, Saturation on X axis, and Value on the Y axis.

Of course a 3D cube colour picker would be pretty hard to use, so what we end up with is a vertical hue slider, then an area that determines the saturation and value like so:

picker

READ MORE

Reverse engineering Captivate for HTML5 widgets

Adobe Captivate is pretty horrible, especially the HTML5 output. I feel like I’m banging my head against a wall every time I use it. The HTML5 output is riddled with bugs and most of the features simply don’t work. If there is one upside to the HTML5 publishing though (and there aren’t many), it’s the ability to access almost anything in the Captivate movie due to the openness of JavaScript and work around its frustrations. I thought I would document a couple issues I faced which could potentially help someone else out. If you’re trying to figure out how to create a HTML5 widget then see my post on Creating HTML5 widgets for Adobe Captivate 6/7.

Problem 1: Create a custom slide index widget

This is pretty much impossible in the Flash publish. I needed a widget that would automatically get all the slide labels and generate an index. After a bit of digging thanks to Chrome’s dev tools, I discovered that most slide information can be found in the ‘toc’ global object on main Captivate window.

Below is a snippet of code that can be used in the HTML5 widget to get all slide names:

1
2
3
4
5
6
7
8
9
10
11
var mainWindow = window.parent; // get captivate main window, widgets are loaded into an iframe

// get list of slides
var slides = mainWindow.toc.mainMovie.stage.slides;

// get slide labels
var i = 0, lgt = slides.length;
for (i; i < lgt; ++i){
  // log all slide labels to the console, you could add them to your custom menu
  console.log( mainWindow.toc.movieProperties[slides[i]].lb );
}

Problem 2: Setting variables doesn’t work properly

Another bug I found in Captivate HTML5 widgets was sometimes setting a variable on the varHandle object doesn’t trigger a change in the movie, such as the cpCmndGotoSlide variable, which tells the movie to go to a particular slide. I found the following snippet to work more reliably:

1
2
// use the main movie's executeAction to set the variable
mainWindow.toc.mainMovie.executeAction("cpCmndGotoSlide = 2"]); // go to slide 3

I hope someone else will find this useful.

Webcam to canvas or data URI with HTML5 and Javascript

This post has been sitting around unfinished since April so I thought I should finish it and get it out there.

In this post I am going to show how you can capture an image from a webcam via JavaScript and convert it to a Data URI which can then be saved in a database or displayed in an IMG tag.

Note: This is more of a proof of concept rather than a best practices example so the code is a bit messy and hacked together from various sources.

I have only tested this on Safari for iOS 6 and latest Chrome with a webcam. It may or may no work in other browsers.

View demo

All explanations for the the code and markup are in the code comments, so please read them for more detail.

READ MORE

Creating HTML5 widgets for Adobe Captivate 6/7

I decided to write this post due to the frustration and lack of information out there on how to make HTML5 widgets for Adobe Captivate. There is almost no documentation on this and the only useful article I could find was riddled with mistakes. My approach may not be the best but this should get you started.

First things first, you will need to make two versions of your widget – a SWF version and a HTML5 version. Even if you don’t plan on using the SWF version, it is required during authortime in Captivate and is where you can provide the edit mode GUI.

These two versions are packaged up into a .wdgt file which is just a zip file with the extension changed to wdgt.

READ MORE

Windows 8 start screen in HTML, CSS and Javascript

About 7 or 8 months ago I built a tile based launch page at work to launch learning modules which looked similar to the Windows 8 start screen. When I had spare time I kept building on and adding 3D animations to match it even closer to Windows 8. Then I kind of forgot about it until this week when I stumbled upon this article Creating Windows-8-like 3D animations with CSS3 and jQuery which provides a tutorial on creating a similar effect.

I had been meaning to do a post on my laucher when I first started making it but it never happened. So now that that article reminded me I thought I should post it. I am not going to provide any explanations of the code or tutorials but rather just show a demo (It’s HTML and javascript so you can just view the source anyway). I have ripped a bunch of LMS related code out of it and turned it into a web page launcher.

Click a tile to launch an ‘app’ (in this case a website). Hover you mouse over the top or bottom right corner for the ‘charms’ bar to close the site and return to the start screen. I have currently only tested it in Chrome and on an iPad and there isn’t a way to get to the charms bar on iPad yet.

Click to launch demo