nooshu - Matt Hobbs' Web Development Blog

Kneeling on the shoulders of giants

Category: JavaScript

All things JavaScript in its many forms, be it plain old JavaScript to a cutting edge Library abstraction.

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 :)

Plotting the Lorenz Attractor using three.js

It’s been a while since I dabbled with three.js. There have been a few API changes, so it’s slightly different from what I remember. That being said it’s still as fun to use, and there are even a few API docs available (not sure if they are fully up to date though)! I happened to be reading an article on Chaos Theory and the “butterfly effect” which mentioned a lovely set of equations; the Lorenz Equations, also known as the Lorenz oscillator. So I decided to investigate further. Here they are in all their glory:

\begin{aligned}\dot{x} & = \sigma(y-x) \\ \dot{y} & = \rho x - y - xz \\ \dot{z} & = -\beta z + xy \end{aligned}

So what exactly is the Lorenz oscillator? Well to quote from Wikipedia “The Lorenz oscillator is a 3-dimensional dynamical system that exhibits chaotic flow, noted for its figure eight shape.”. What this really boils down to is how even very small change in the equations initial conditions (x, y and z) causes large changes over time, in a complex and non-repeating pattern. There’s a famous title of a talk given in 1972 by Philip Merilees:

Does the flap of a butterfly’s wings in Brazil set off a tornado in Texas?

The butterfly flapping its wings introduces slight changes to the initial conditions, creating a chain of events that lead to a tornado in Texas. The Lorenz butterfly is a graphical way of showing these changes over time on a much smaller scale.

I’ve created a demo that allows you to change variables related to the Lorenz butterfly and observe the effect it has on the system.

Example of my Lorenz attractor demo in action

Adjust the demo variables to see how the Lorenz butterfly changes.

There are a few variables you can play to change how the Lorenz attractor is rendered:

  • rhoValue: Called the Rayleigh number. Rho of value 28 shows chaotic behavior. Other values show periodic orbits.
  • showAxis: Allows you to turn the x, y, z (red, green, blue) axis on for reference.
  • randomStart: Picks a random initial conditions, rather than 0, 0, 0.
  • totalTime: The total time (or number of iterations performed) when generating the graph. Higher numbers equals more lines and increases the render time.
  • timeIncriment: The accuracy of the graph depends on the number of points plotted. A lower number creates a smoother graph but increases render time.
  • colorModifier: Simply changes the colo(u)r. Pointless but pretty!

While rendering a larger number of points, I noticed the browser lock-up for a second or so. This was because the points were being calculated on the browsers UI thread. Luckily modern browsers support thread like message passing in the form of the Web Workers API. By offloading the point calculation to its own thread (lorenzPoints.js), I was able to stop the nasty UI freeze. Unfortunately you are fairly limited with what you can pass back and forth between workers. It was possible to generate the three.js geometry in the worker thread thanks to the importScripts() method. I tried passing the three.js geometry back to the browser but all the methods were stripped out, leading to lots of errors (JSON issues). In the end I dropped back to calculating the points in the worker, pushing them into an array and generating the geometry on the main browser thread.

It was good fun dabbling with three.js, Web Workers and dat.gui again. Now on to my next project… View the demo here.

Remote Loading HTML5 Elements with jQuery

I ran into a rather annoying problem a few months ago while developing my travel blog; the problem of course was involving Internet Explorer. I’m used to working with WordPress as I use it all the time, but I wanted to get away from the standard pagination you find on a blog. So I decided to use jQuery 1.6.4 to pull in articles from other pages (blogname.com/page/2, blogname.com/page/3 etc). Now this is all fairly simple using the handy jQuery .load() method; point it to a URL, pull in the page, pick the bits you need and reinsert into the page. Simple! Unfortunately once I got a prototype working in ‘good’ browsers, IE8 and below was having non of it!

After a little head scratching to work out what was failing, I worked out it was because I was using HTML5 elements such as ‘article’, ‘header’ and ‘footer’. There was no problem displaying them on the page, as I’d used Remy Sharps excellent HTML5 Shiv script. It only failed when trying to pull in these ‘new’ elements via Ajax.

Note: Before you read on you’ll be happy to hear that this issue no longer occurs in jQuery 1.7.0. Horray!

If you can’t upgrade, for whatever reason, I hashed together a little work-around for browsers IE8 and below, so read on. I admit the work around isn’t pretty, but it works. I tried for a few hours to get IE8- to recognise the ‘new’ elements after an Ajax request, but to no avail. Eventually I had to wrap the HTML5 tags in a div using conditionals:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!--[if lt IE 9]><div id="ieHackContainer"><![endif]-->

<article id="html5Content">
    <header>
        <h2>H2 wrapped in a header element</h2>
    </header>
    <!-- Other HTML here... -->
    <footer>
        <p>This is the footer element</p>
    </footer>
</article>

<!--[if lt IE 9]></div><![endif]-->

The div is added for browsers IE8 and below, you can then use it as a hook to pull in the elements inside the div. I was hoping that wrapping the HTML5 elements in a standard div would be the end of it, I’m afraid not. The .load() method still didn’t work, IE just ignored the elements it didn’t recognise. I used jQuerys much more customisable .ajax() method to fix the issue in IE6, 7 and 8:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//IE8- work around to load HTML5 elements into a page
$("#loadHTML5LinkOld").click(function(){
        $.ajax({
                url: "page_to_load.html",
                cache: false,
                success: function(html){
                        var HTML;
                        //Clear before load
                        $("#html5LoadHolder").empty();
                       
                        //IE: Look for the hacky wrapper before insertion
                        HTML = $(html).filter("div#ieHackContainer").html();
                       
                        //If HTML var is empty assume using newer browsers
                        if(!HTML){
                                HTML = $(html).filter("#html5Content").html();
                        }
                       
                        //Append to page
                        $("#html5LoadHolder").append(HTML);
                }
        });
       
        return false;
});

This method works in all browsers I’ve tested in as I’ve added a fall back (or should that be forward?) for newer browsers. The solution isn’t ideal (I really hate the conditional comments), but older versions of IE aren’t going away any time soon, and it works. Maybe there’s a more obvious solution that I missed? Leave a comment if there is, I’d love to know!

You can see a working example here. The page I’m loading from is here and the JavaScript in full here.

dat.gui – controller library for JavaScript

Very recently I’ve been looking at some awesome JavaScript experiments and have noticed they are all using the same GUI. Now I fully admit I had a little ‘blonde’ moment as I assumed it was just a style everyone had adopted; developers being ‘one of the cool kids’, that type of thing. It turns out I was wrong, and it finally clicked. All the experiments have started using a little controller library called dat.gui.

After it appeared on Google’s workshop (along with three.js), I thought it was about time I had a play with this neat little library. Luckily there’s an excellent set of documentation and working examples available so you can dive right in. Here’s a code example of how to get started:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//Define the controller function
var FresnelControls = function() {
    this.movingParticles = 5000;
    this.seedColor = "#ff0098";
};

//Create the Dat.gui controls
var fc = new FresnelControls();

//Create the GUI
var gui = new dat.GUI();

//Add 2 folders
var f1 = gui.addFolder('Particle Dynamics');
var f2 = gui.addFolder('Particle Colours');
       
//Add the moving particles controller to folder 1
f1.add(fc, 'movingParticles', 0, 5000).step(1);

//Add the colour controller, store in a var to attach events
var seedColor = f2.addColor(fc, 'seedColor');

//Colour change event
seedColor.onChange(function(value) {
    //Do something on color change...
});

I decided to dig out an old demo I created last year and adapt it to use dat.gui. Originally I used jQuery + jQuery UI to control the JavaScript variables. It worked well, but it really added page weight (jQuery + UI came to over 90Kb); not great when you are only using it for the sliders.

Following the documentation you start off simple and progressively add more of the dat.gui functionality. You can see my adapted demo here. The dat.gui code is highlighted if you want to see how it was set up.

Dat.gui in action on the Euler Spiral demo I created.

You can see dat.gui in action on my modified Euler Spiral demo.

Dat.gui really has some excellent features available. I was able to make use of the colour picker, presets and folder functionality; but there’s a whole host of others I didn’t, such as the custom placement and updating the display automatically. Personally I love the presets functionality; supply the GUI with a little bit of JSON and away you go!

As always, a big thank you goes out to the Data Arts Team in Google’s Creative Lab for creating such a useful little library! One I will be using in every demo I create from now on.

Currently on page 1 of 1212345Last »