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.

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.

A little bit of MicroJS

Recently there was a flurry of talk around a little something called MicroJS, mainly thanks to a website of the same name created by Thomas Fuchs, author of the script.aculo.us user interface library. I’m not sure if Thomas coined the term “MicroJS” or if it’s been in use for a while, but it describes the micro-framework methodology perfectly. So what is a micro-framework? The best way to answer that is to first ask what is a JavaScript framework?

JavaScript frameworks have been around since around 2005 (looking at the Prototype and jQuery history); their purpose is to allow developers to easily add interactivity to a page by creating a JavaScript abstraction layer to build from. The library takes care of any cross browser issues and quirks, allowing developers to focus on the “cool” stuff, building websites. As a developer I can’t thank all the library authors enough; without them my working life would be so much more stressful (and my hair would be even grayer than it is now!).

Once you know what a JavaScript framework is, it doesn’t take a genius to guess what a micro-framework is. Where as a full framework will have many tools (methods) a developer can use, a micro-framework only focuses on a very specific set of functions. I like the knife analogy: a full-framework like Dojo would be a Swiss Army knife where as a micro-framework could be considered a small pen knife. So which do you use in a project? This completely depends on the project in hand. I’ve put together a small list of pros and cons for each (let me know if you have any others):

Full Framework

  • Pros
  • Extensive set of features to cater for most eventualities.
  • Consistent API across features.
  • Large user base with lots of community support.
  • Huge number of working examples available.
  • Many developers to fix bugs and add additional functionality.
  • Single point of reference of documentation.
  • Cons
  • Large code base could be very daunting to new users.
  • Large page footprint.
  • Many features of the library may not be needed.

Micro-Framework

  • Pros
  • Small page weight, usually less than 5K.
  • Small set of features so very quick to pick up and use.
  • Main focus on a very specific set of functionality.
  • No feature creep or excess code.
  • Use the right tool for the right job.
  • Cons
  • Small number of developers, bugs and issues may take a while to be fixed.
  • Development of the framework may stop completely.
  • May be very little support from the author and the community.
  • Fellow developers in your team may not be familiar with the framework.
  • Mixing micro-frameworks could conflict if badly coded.
  • Multiple frameworks could mean multiple HTTP requests.
  • Multiple points of reference for API docs.
  • Multiple frameworks could lead to an overlap in functionality.

Many of the cons for micro-frameworks stem from using more than one at a time, but if you only plan on using one then they can be ignored.

Micro-frameworks caught my eye recently due to a couple of small projects I’d been working on. The projects all used vanilla JavaScript as there was no need for a helper library. I later realised I needed to attach a few events and manipulate the DOM but I wanted to avoid including jQuery in the project as I only needed a small fraction of its functionality. Luckily the MicroJS website came to the rescue.

The examples below are taken from Query, Bonzo, Events.js and Bean. As you can see the usage for each is pretty self-explanatory with lots more functionality is available from each library’s website. If you’re a jQuery user the syntax will look very familiar.

CSS selector and DOM utility

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
Query - Dustin Diaz
https://github.com/ded/qwery
CSS selector engine
*/

query("#myid");
query(".myclass");
query("#myid .myclass div a");
query("a, div, strong");

/*
Query Paired with Bonzo - Dustin Diaz
https://github.com/ded/bonzo
DOM utility
*/

query("#myid").show();
query(".myclass").offset(50, 100);
query("#myid .myclass div a").addClass("anchorClass");
query("a, div, strong").remove();

Events

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
27
28
29
30
31
32
33
34
35
/*
Events.js - James Brumond
https://github.com/kbjr/Events.js
Event handler library
*/

Events.bind(window, 'load', function(e) {
    //Page loaded, do something
});
//Invoke the page load event
Events.invoke(window, 'load');
//Mouse click event
Events.bind(selectedElements, 'click', function(e) {
    //Mouse has been clicked
});
//Very handy keystroke event
Events.bind(document, 'keystroke.Ctrl+Shift+Alt+S', function(e) {
    saveMySlices();
});

/*
Bean - Dustin Diaz
https://github.com/fat/bean
Event handler library
*/

bean.add(selectedElements, 'click', function (e) {
    //Mouse has been clicked
});
//DOM has loaded
bean.add(document, 'DOMContentLoaded', function(e){
    //Page loaded, do something
});
//Invoke an event on an element
bean.fire(selectedElement, 'click');
//Remove the event from an element
bean.remove(selectedElement, 'click');

I’ll be trying out a few more of these micro-frameworks for my personal projects in the future as the ability to select only the functionality you need really appeals to me. Are there any other micro-frameworks you’ve used that you’d recommend? Leave me a comment and I’ll check them out.

Update: It just so happens that a handy library website has emerged inspired by the MicroJS website called EveryJS. The website lists all library’s rather than just micro versions. Not all are listed but I’m sure they will be added soon so it’s one to keep your eye on.

Fun with Space Invaders and Parallax scrolling

Back when I was a young wippersnapper (many moons ago) one of my good friends had a Sega Mega Drive. As with any new console it was on every kids Christmas list but compared to the current generation of games consoles it looks very primitive. The games were immense fun and you didn’t need an instruction manual to play them. Two of my favourite games were Golden Axe and Sonic the Hedgehog. Sonic the Hedgehog used a technique called Parallax scrolling; this is where background images move slower than “closer” foreground images giving the illusion of depth in a 2D plane.

I’m quite late to the web parallax party as the effect was recreated and popularised back in 2008. I first remember seeing it being used by the holding page for Clearleft’s Silverback application, but it may have appeared elsewhere before that. Three years on the web is a long time and technology has moved on, so I set myself a little project to recreate the effect using the HTML5 canvas element.

Parallax scrolling using a Space Invaders alien

Move your mouse to see the Parallax scrolling effect.

To demonstrate the effect I used a few graphics from another iconic retro game: Space Invaders. As you move the mouse the scary alien separates into its constituent pixels. The foreground pixels move faster than the background pixels creating a slight parallax effect. You have three aliens to choose from: Dave, Julian and Brian, which I’ve named for no particular reason. I think the names quite suit them. I’ve also added a little randomness to the demo in how they are generated, which you can see by reloading the page.

Hooray for retro games and pointless demo’s! :)

Currently on page 1 of 1212345Last »