nooshu - Matt Hobbs' Web Development Blog

Kneeling on the shoulders of giants

A visualisation experiment using SoundCloud, Backbone.js, three.js and node.js

Client work, as always, has been busy over the past month or so; so it’s always refreshing to have a play with something a little different. It’s even better when you can actually combine the two! Visual Jazz Isobar decided to have a little code competition open to all the developers in the company. The brief was very simple: build something cool using an external API (bonus points for multiple API’s). Very open brief don’t you think? You only have to have a look at the list of API’s available on programmable web to see that.

As I’ve recently been looking at Backbone.js I decided to put what I’ve learned good use. The experiment evolved over a couple of weeks. I originally planned to use d3.js and last.fm but eventually settled on three.js and SoundCloud. My final submission looked like this:

Visualisation using Backbone.js, Node.js and Three.js

My little experiment using the SoundCloud API and three.js (with a sprinkling of node.js)

To be honest I could have built the experiment easily without using Backbone, but where is the challenge in that! I love the whole Model, View, Router set up. You do seem to be writing a lot of code a first for very little functionality, but once you are over the initial set up you can add features very quickly. I’ll definitely be using it again for future projects.

The visualisation itself makes use of the Web Audio API. The API is still being developed and standardized, because of that it only runs in Chrome at the moment. Three.js itself runs fine in Firefox, but no audio visualisation.

During development I stumbled across an issue with Chrome and the way the audio buffer works; for the data to load, the music files need to be on the same server as the application. This was a bit of a problem as I was using the SoundCloud API for music streaming. That’s where node.js and Nodester came to the rescue. With a little bit of node.js magic it’s fairly simple to create a proxy server and ‘bounce’ the stream from SoundCloud via the server to the visualisation. A big downside to this method is the music stream (mp3) has to be fully downloaded before the visualisation starts. For this reason only tracks under 6 minutes are returned as search results from SoundCloud. It’s not ideal but it work!

When the competition results came in I was placed second; not first but hey I learnt a lot in the process! You can take a look at my little experiment here.

Auto-spacing input field text

On a recent project, a set of wireframes landed on my desk which contained some “interesting” ideas, particularly when it came to form fields. One that really stood out was having a credit card number auto-space as the user types it into a single input box. This of course would depend completely on what type of card they are entering, as different cards have different layouts. American Express for example have a [4, 6, 5] layout, where as Visa use a [4, 4, 4, 4] number layout.

Thankfully this functionality was eventually removed from the UI specifications after concerns from myself and others were raised. Just to make this perfectly clear; I think this is a bad idea, and here is why:

  • Users are very wary when it comes entering their credit card details. Spaces magically appearing in their credit card number could freak a few of them out.
  • Most e-commerce website I’ve ever used ask for the credit card number as one long string of numbers with no spaces. Auto-spacing goes against this convention, so a user may actually go back and try to remove the spaces (I know I would).
  • Validation scripts for credit card numbers usually ask for the input to have no spaces, or will remove any spaces on submit.
  • If you do want to space out the credit card number, why not use different input boxes for each set of numbers? It looks cleaner and is simpler to implement. Just have your JavaScript automatically jump between boxes as the user types.

Even though this functionality was removed, I decided to build a prototype of it in action because… well because I can and I was bored. :) Please, (please!), whatever you do don’t use this code in production. I created it as an experiment and should be treated that way. It’s very simple to get around the auto-spacing and then all hell breaks loose! (not really, but it is easy to break).

The spacing is implemented by counting the length of the string inside the input field, but you could also monitor the current position of the cursor. Anyone wishing to do this see this excellent set of answers on Stackoverflow.

You can see the prototype here. Remember, don’t use it. It’s not big and it’s not clever :)

Using the Fullscreen and Pointer Lock API’s

This post is a couple of months late due to real life getting in the way, but I finally got around to experimenting with the Fullscreen and Pointer Lock API (formally known as the Mouse Lock API). Both are still in the experimental stage, Pointer Lock especially. To get it to work you will have to be running the latest Canary build of Chrome (currently 19.0.1067.0) and enable it via about:flags. I’ve had no luck getting Pointer Lock working in the latest version of Firefox and Aurora, even though most documentation on the API is written by Mozilla. Maybe there’s a setting I’m missing?

So what exactly do the Fullscreen and Pointer Lock API’s do you may ask. Well Fullscreen is obvious; it allows you to view any web content in fullscreen mode, removing the browser UI for distraction free reading. Pointer Lock gives a developer access to raw mouse movement data, not just the absolute position of the cursor. You are no longer limited to the size of the browser window, so you can scroll continuously in one direction without having to stop. Where both of these API’s come in very handy is the development of HTML5 games. It’s now possible to create a games like Quake 3 directly in the browser with usable controls… impressive!

To have a play with both API’s I put together a little experiment using three.js and a panoramic image.

Fullscreen, Pointer Lock and three.js

What a beautiful day in Sydney, just round the corner from where I live.

I started by building on an excellent blog post by Paul Lewis called “Create your own environment maps”. Using Microsoft’s Photosynth App and Blender it’s dead simple to create a panoramic image. After adapting Paul’s code to my needs, I added the Fullscreen and Pointer lock API’s. To enable Fullscreen mode press enter. If you have a compatible browser, the browser UI will disappear and you will enter fullscreen mode. If Pointer Lock is available, a prompt will appear asking for permission to hide your cursor. You will now be able to scroll left and right continuously without having to stop, if Pointer Lock isn’t available the demo will drop back to standard mouse co-ordinates.

A quick tip for working with both of these API’s: use a shim like that made by Brandon Jones, it will save you a lot of cross browser pain! Browser vendors are still changing the way both of these API’s are implemented, so until this stabilises, using a shim is the way to go. Big thank you to Paul and Brandon for their excellent contributions.

HTML5 date input type on mobile

Whilst developing a new mobile only website, the UX team specified in the wireframes that a datepicker was needed for an input field; but nowhere else on the site was a datepicker used, so I really wanted to avoid using a JavaScript heavy solution. I couldn’t justify including so much extra JavaScript, CSS and images for so little usage. So what other options do we have?

Well there is a jQuery plug-in called Mobiscroll which is around 16KB is size and works on iOS and Android devices. Unfortunately there’s no mention of Windows-based mobiles which is a real shame, as it’s almost a perfect solution. The other option we have is to take advantage of some cutting edge HTML5 form input types; the date input type. Support is nowhere near 100% yet, but if you approach its usage from a progressive enhancement standpoint, it works well. On mobile browsers that support it, the user gets a fancy datepicker that’s very intuitive; browsers that don’t simply drop back to a standard text input. It’s worth noting that Modernizr can’t detect that date inputs create a datepicker, since Modernizr can’t do it I assume it isn’t possible. Damn!

An example of the date input type on iPhone, iPad and iPods.

The date input type as displayed on iOS mobile Webkit devices.

Once I’d decided on how the date picker was going to work (HTML5) it was time to implement it and test it across my available mobile browsers. Implementation was dead simple:

1
2
<!-- Fancy datepicker on supported devices, standard text input on unsupported -->
<input type="date" name="fancyDate" id="fancyDate">

Where things got a little tricky (and annoying) was the client-side validation of the input. Since the wireframes contained lots of forms with a varying range of input types and requirements, I decided to go with quite a heavyweight validation script (around 21KB minified). This turned out to be a very good decision in the end, as there are a few quirks to the date input element.

First thing I had to consider was how were users going to input the date when they don’t have the fancy datepicker? The most intuitive way (at least for me) is they simply enter in the format dd/mm/yyyy. Great, that’s sorted! And guess what, when a user uses the fancy datepicker it also returns a value of dd/mm/yyyy…. no, no it doesn’t! It looks like that’s the value that will be returned as that’s how it is displayed, but no, it’s never that easy. Webkit actually returns the date in the format yyyy-mm-dd, not quite what I was expecting! Unfortunately this breaks our validation as it is looking for a format of dd/mm/yyyy!

So what’s the fix? Well you could take the easy route and make your non-fancy datepicker users enter the date in the yyyy-mm-dd format; but that just feels wrong. No user is going to expect to enter a date like that, it’s completely unintuitive! No I’m afraid it’s going to take a little hack to fix this issue. The hack involves using a second input field of type “text”; when a user interacts with the fancy datepicker or enters in the date manually, the date is “cleaned up” and passed along to the second input field. You then do your form validation against this second field. You can see an example of this working here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
 * iOS input type="date" returns a value of yyyy-mm-dd even when
 * it displays dd/mm/yyyy. This breaks validation. Fix for this using a second input.
 * Keyup event for testing in a browser, not needed for mobile.
 */

$("input[type='date']").on("blur keyup", function(e){
    var $this = $(this),
        value = $this.val();

    //Does the input have "-", if so it is from the webkit datepicker, fix it
    if(value.indexOf("-") !== -1){
        var cleanDateArray = value.split('-');
        value = cleanDateArray[2] + "/" + cleanDateArray[1] + "/" + cleanDateArray[0];
    }

    //Set the hidden value to validate on, trigger the blur and keyup event for validation as you type
    $("#hiddenDateField").val(value).trigger("blur").trigger("keyup");
});

A couple of points to note about using this method. Even though we aren’t validating the datepicker input, we still have to set “date: false” in the validation rules. This is because the validation plug-in automatically tries to validate date inputs. Validation fails because it doesn’t like the dd/mm/yyyy format. I’ve also used the dateITA method to validate the date on the “hidden” input (you can find this in the additional-methods.min.js file). This additional method is more robust than the plug-ins standard date validation. A minor pitfall with this hack is that setting the second input to type “hidden” will stop its validation; this is due to the validation plug-in ignoring hidden inputs. So to hide the input you can set “display: none” in the CSS (urghh I know, I feel dirty too!).

So there you have it, that’s how I solved validating a date input on mobile with fancy datepicker and standard text fallback. It’s not ideal by any means, but it works. Another solution would be writing a validator Regex that accepts both dd/mm/yyyy and yyyy-mm-dd date formats, but this means returning both types of dates to the server on submit. Due to server-side constraints with the project, this isn’t an option (boo!). Is there a much simpler method that I’m completely missing? If so please leave a comment! :)

Sublime Text 2, a truly sublime text editor

I’m always on a quest to find that one perfect editor, I’ve been hunting for it for many years. Having been an UltraEdit, Notepad++, Eclipse, Aptana and Komoddo user in the past, they all had their pro’s and cons. Eclipse and Aptana (built on Eclipse) were very feature rich (and very slow!). UltraEdit and Notepad++ were quick but didn’t quite fulfil what I was looking for in an editor (maybe that has changed in newer versions). Komoddo I was very impressed with, but it had a few bugs that just became annoying after a while (like tabbing code blocks). None of them were quite right.

Upon starting my new job a couple of months ago, a colleague, Anton Mills, introduced me to Sublime Text 2 and I haven’t opened another editor since!

Sublime Text 2 editor in action with 2 columns.

Sublime Text 2 editor with its very handy 2 column layout.

There are a few key features I look for in an editor. They are:

  • Speed: It needs to be responsive and quick to load. There is nothing more frustrating than an editor that freezes all the time and takes 5 minutes to load.
  • Regular updates: If there is a bug it’s nice to know it will be fixed soon(ish).
  • Plugins: It may not be possible for an editor to have everything you need in the core, so a good plug-in interface is essential.
  • Community: The author may not be on hand to answer all questions so having a helpful community is a plus.

Thankfully, Sublime meets all of these criteria. Development builds are released every week or so and there is a vibrant community on hand to answer any questions. As I’m in a list making mood, here’s a few plug-ins I’d encourage any Front-end Developer install:

  • Package Control: Before you do anything, install this plug-in! It makes installing all other plug-ins a breeze.
  • SublimeCodeIntel: An excellent code auto-complete plug-in that’s been ported from Komoddo.
  • Zen Coding: If you haven’t heard of Zen Coding take a look at my previous blog post. You will wonder how you ever survived without it.
  • SFTP: Making changes and uploading them directly from the editor can be a godsend at times, but use with caution! Paid plug-in but you get a free trial.
  • DocBlockr: Makes documenting your code quick and easy (supports JavaScript and PHP).

A few of the key features to look out for when you try it are the full screen and distraction free mode, multi columned editor (see image above), multiple cursors (this one I love!), code mini-map and the command palette. Those are just a few I’ve noted but I’m discovering more every day. Checkout this informative post by Nettuts+ for more awesome features.

Now it’s not perfect, there are a cons. Automatic tag closing isn’t working for me at the moment and the project panel needs a little work (being able to drag and drop files would be nice), but the pros far outweigh the cons, so I’m willing to overlook them. If you have a suggestion or find a bug the place to report them is here. As you can see there are lots of feature requests already and the author actually implements (some) of them!

Big thank you to the author Jon Skinner, a fellow Sydney resident for developing such an excellent editor! Download it here.

Currently on page 1 of 2412345Last »