1. JavaScript on the server: Growing the Node.js Community

    Cloud9 IDE and Mozilla have been working together ever since their Bespin and ACE projects joined forces. Both organizations are committed to the success of Node.js, Mozilla due to its history with Javascript and Cloud9 IDE as a core contributor to Node.js and provider of the leading Node.js IDE. As part of this cooperation, this is a guest post written by Ruben Daniels and Zef Hemel of Cloud9 IDE.

    While we all know and love JavaScript as a language for browser-based scripting, few remember that, early on, it was destined to be used as a server-side language as well. Only about a year after JavaScript’s original release in Netscape Navigator 2.0 (1995), Netscape released Netscape Enterprise Server 2.0:

    Netscape Enterprise Server is the first web server to support the Java(TM) and JavaScript(TM) programming languages, enabling the creation, delivery and management of live online applications.

    This is how the web got started, all the way back in the mid-nineties. Sadly, it was not meant to be then. JavaScript on the server failed, while JavaScript in the browser became a hit. At the time, JavaScript was still very young. The virtual machines that executed JavaScript code were slow and heavy weight, and there were no tools to support and manage large JavaScript code bases. This was fine for JavaScript’s use case in the browser at the time, but not sufficient for server-side applications.

    Continued…

  2. Faster Canvas Pixel Manipulation with Typed Arrays

    Edit: See the section about Endiannes.

    Typed Arrays can significantly increase the pixel manipulation performance of your HTML5 2D canvas Web apps. This is of particular importance to developers looking to use HTML5 for making browser-based games.

    This is a guest post by Andrew J. Baker. Andrew is a professional software engineer currently working for Ibuildings UK where his time is divided equally between front- and back-end enterprise Web development. He is a principal member of the browser-based games channel #bbg on Freenode, spoke at the first HTML5 games conference in September 2011, and is a scout for Mozilla’s WebFWD innovation accelerator.


    Eschewing the higher-level methods available for drawing images and primitives to a canvas, we’re going to get down and dirty, manipulating pixels using ImageData.

    Conventional 8-bit Pixel Manipulation

    The following example demonstrates pixel manipulation using image data to generate a greyscale moire pattern on the canvas.

    Let’s break it down.

    First, we obtain a reference to the canvas element that has an id attribute of canvas from the DOM.

    var canvas = document.getElementById('canvas');

    The next two lines might appear to be a micro-optimisation and in truth they are. But given the number of times the canvas width and height is accessed within the main loop, copying the values of canvas.width and canvas.height to the variables canvasWidth and canvasHeight respectively, can have a noticeable effect on performance.

    var canvasWidth  = canvas.width;
    var canvasHeight = canvas.height;

    We now need to get a reference to the 2D context of the canvas.

    var ctx = canvas.getContext('2d');

    Armed with a reference to the 2D context of the canvas, we can now obtain a reference to the canvas’ image data. Note that here we get the image data for the entire canvas, though this isn’t always necessary.

    var imageData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);

    Again, another seemingly innocuous micro-optimisation to get a reference to the raw pixel data that can also have a noticeable effect on performance.

    var data = imageData.data;

    Now comes the main body of code. There are two loops, one nested inside the other. The outer loop iterates over the y axis and the inner loop iterates over the x axis.

    for (var y = 0; y < canvasHeight; ++y) {
        for (var x = 0; x < canvasWidth; ++x) {

    We draw pixels to image data in a top-to-bottom, left-to-right sequence. Remember, the y axis is inverted, so the origin (0,0) refers to the top, left-hand corner of the canvas.

    The ImageData.data property referenced by the variable data is a one-dimensional array of integers, where each element is in the range 0..255. ImageData.data is arranged in a repeating sequence so that each element refers to an individual channel. That repeating sequence is as follows:

    data[0]  = red channel of first pixel on first row
    data[1]  = green channel of first pixel on first row
    data[2]  = blue channel of first pixel on first row
    data[3]  = alpha channel of first pixel on first row
     
    data[4]  = red channel of second pixel on first row
    data[5]  = green channel of second pixel on first row
    data[6]  = blue channel of second pixel on first row
    data[7]  = alpha channel of second pixel on first row
     
    data[8]  = red channel of third pixel on first row
    data[9]  = green channel of third pixel on first row
    data[10] = blue channel of third pixel on first row
    data[11] = alpha channel of third pixel on first row
     
     
    ...

    Before we can plot a pixel, we must translate the x and y coordinates into an index representing the offset of the first channel within the one-dimensional array.

            var index = (y * canvasWidth + x) * 4;

    We multiply the y coordinate by the width of the canvas, add the x coordinate, then multiply by four. We must multiply by four because there are four elements per pixel, one for each channel.

    Now we calculate the colour of the pixel.

    To generate the moire pattern, we multiply the x coordinate by the y coordinate then bitwise AND the result with hexadecimal 0xff (decimal 255) to ensure that the value is in the range 0..255.

            var value = x * y & 0xff;

    Greyscale colours have red, green and blue channels with identical values. So we assign the same value to each of the red, green and blue channels. The sequence of the one-dimensional array requires us to assign a value for the red channel at index, the green channel at index + 1, and the blue channel at index + 2.

            data[index]   = value;	// red
            data[++index] = value;	// green
            data[++index] = value;	// blue

    Here we’re incrementing index, as we recalculate it with each iteration, at the start of the inner loop.

    The last channel we need to take into account is the alpha channel at index + 3. To ensure that the plotted pixel is 100% opaque, we set the alpha channel to a value of 255 and terminate both loops.

            data[++index] = 255;	// alpha
        }
    }

    For the altered image data to appear in the canvas, we must put the image data at the origin (0,0).

    ctx.putImageData(imageData, 0, 0);

    Note that because data is a reference to imageData.data, we don’t need to explicitly reassign it.

    The ImageData Object

    At time of writing this article, the HTML5 specification is still in a state of flux.

    Earlier revisions of the HTML5 specification declared the ImageData object like this:

    interface ImageData {
        readonly attribute unsigned long width;
        readonly attribute unsigned long height;
        readonly attribute CanvasPixelArray data;
    }

    With the introduction of typed arrays, the type of the data attribute has altered from CanvasPixelArray to Uint8ClampedArray and now looks like this:

    interface ImageData {
        readonly attribute unsigned long width;
        readonly attribute unsigned long height;
        readonly attribute Uint8ClampedArray data;
    }

    At first glance, this doesn’t appear to offer us any great improvement, aside from using a type that is also used elsewhere within the HTML5 specification.

    But, we’re now going to show you how you can leverage the increased flexibility introduced by deprecating CanvasPixelArray in favour of Uint8ClampedArray.

    Previously, we were forced to write colour values to the image data one-dimensional array a single channel at a time.

    Taking advantage of typed arrays and the ArrayBuffer and ArrayBufferView objects, we can write colour values to the image data array an entire pixel at a time!

    Faster 32-bit Pixel Manipulation

    Here’s an example that replicates the functionality of the previous example, but uses unsigned 32-bit writes instead.

    NOTE: If your browser doesn’t use Uint8ClampedArray as the type of the data property of the ImageData object, this example won’t work!

    The first deviation from the original example begins with the instantiation of an ArrayBuffer called buf.

    var buf = new ArrayBuffer(imageData.data.length);

    This ArrayBuffer will be used to temporarily hold the contents of the image data.

    Next we create two ArrayBuffer views. One that allows us to view buf as a one-dimensional array of unsigned 8-bit values and another that allows us to view buf as a one-dimensional array of unsigned 32-bit values.

    var buf8 = new Uint8ClampedArray(buf);
    var data = new Uint32Array(buf);

    Don’t be misled by the term ‘view’. Both buf8 and data can be read from and written to. More information about ArrayBufferView is available on MDN.

    The next alteration is to the body of the inner loop. We no longer need to calculate the index in a local variable so we jump straight into calculating the value used to populate the red, green, and blue channels as we did before.

    Once calculated, we can proceed to plot the pixel using only one assignment. The values of the red, green, and blue channels, along with the alpha channel are packed into a single integer using bitwise left-shifts and bitwise ORs.

            data[y * canvasWidth + x] =
                (255   << 24) |	// alpha
                (value << 16) |	// blue
                (value <<  8) |	// green
                 value;		// red
        }
    }

    Because we’re dealing with unsigned 32-bit values now, there’s no need to multiply the offset by four.

    Having terminated both loops, we must now assign the contents of the ArrayBuffer buf to imageData.data. We use the Uint8ClampedArray.set() method to set the data property to the Uint8ClampedArray view of our ArrayBuffer by specifying buf8 as the parameter.

    imageData.data.set(buf8);

    Finally, we use putImageData() to copy the image data back to the canvas.

    Testing Performance

    We’ve told you that using typed arrays for pixel manipulation is faster. We really should test it though, and that’s what this jsperf test does.

    At time of writing, 32-bit pixel manipulation is indeed faster.

    Wrapping Up

    There won’t always be occasions where you need to resort to manipulating canvas at the pixel level, but when you do, be sure to check out typed arrays for a potential performance increase.

    EDIT: Endianness

    As has quite rightly been highlighted in the comments, the code originally presented does not correctly account for the endianness of the processor on which the JavaScript is being executed.

    The code below, however, rectifies this oversight by testing the endianness of the target processor and then executing a different version of the main loop dependent on whether the processor is big- or little-endian.

    A corresponding jsperf test for this amended code has also been written and shows near-identical results to the original jsperf test. Therefore, our final conclusion remains the same.

    Many thanks to all commenters and testers.

  3. Firefox – tons of tools for web developers!

    One of the goals of Firefox have always been to make the lives of web developers as easy and productive as possible, by providing tools and a very extensible web browser to enable people to create amazing things. The idea here is to list a lot of the tools and options available to you as web developers using Firefox.

    Continued…

  4. WDC2011: Tomorrow’s Web (and Future Technologies)

    Last Friday I had the pleasure of attending and speaking at the Web Developer Conference in Bristol. This was the fifth conference in the event’s history and was attended by well over 200 Web designers and developers from across the UK.

    In my talk I covered some Web technologies that are on the horizon and coming your way in the near future. Some topics of particular interest are the WebAPIs that we’re working on, with the WebVibrator API easily being the most popular amongst the attendees (no idea why).

    But in all seriousness, it was a great event and I’m glad to see some of the attendees exploring these new technologies as a result of the talk.

    You can check out the slides below:

  5. Tagging docs for sprint at JSConf.eu October 1-2

    We’re very excited to announce that Mozilla is sponsoring the Hacker Lounge at JSConf.eu and we will be holding a doc sprint at and during the conference. The focus of this doc sprint will naturally be docs for JavaScript and DOM. We hope to encourage attendees at the conference to contribute at least a little to improving the JS and DOM docs on MDN. I and a handful of MDN community members will be there to show them how.

    To that end, we want to tag as many JS and DOM articles as possible, with tags indicating what work needs to be done on those articles. That way, anybody dropping in during the sprint (or anytime later) can look for tagged articles and find something to work on.

    Here are some of the tags we use to indicate that an article needs help:

    • NeedsTechnicalReview: needs someone to verify that the technical information is complete and correct.
    • NeedsExample: needs one or more illustrative code examples of the item documented.
    • NeedsContent: the item is incomplete and needs to be filled out.
    • NeedsJSVersion: needs information about the version of JavaScript and EcmaScript this item first appears in.
    • NeedsBrowserCompatibility: needs a browser compatibility table or needs the table filled out.
    • MakeBrowserAgnostic: the article is written with a focus on Gecko, when it is actually about a standard function or feature, which should be rewritten to be generic.

    Please help by tagging articles in MDN that need work with the appropriate tag. You can use the Talk page for each article to elaborate on what needs to be done, if the tag is not descriptive enough. To modify tags on an article, login to MDN and click Edit Tags at the bottom of the page.

    The wiki page for the doc sprint has links to queries for some of these tags.

    If you will be at JSConf.eu, I look forward to seeing you there! If you will be participating remotely, I’ll see you online!

  6. Detecting and generating CSS animations in JavaScript

    When writing of the hypnotic spiral demo the issue appeared that I wanted to use CSS animation when possible but have a fallback to rotate an element. As I didn’t want to rely on CSS animation I also considered it pointless to write it by hand but instead create it with JavaScript when the browser supports it. Here’s how that is done.

    Testing for the support of animations means testing if the style attribute is supported:

    var animation = false,
        animationstring = 'animation',
        keyframeprefix = '',
        domPrefixes = 'Webkit Moz O ms Khtml'.split(' '),
        pfx  = '';
     
    if( elm.style.animationName ) { animation = true; }    
     
    if( animation === false ) {
      for( var i = 0; i < domPrefixes.length; i++ ) {
        if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) {
          pfx = domPrefixes[ i ];
          animationstring = pfx + 'Animation';
          keyframeprefix = '-' + pfx.toLowerCase() + '-';
          animation = true;
          break;
        }
      }
    }

    [Update - the earlier code did not check if the browser supports animation without a prefix - this one does]

    This checks if the browser supports animation without any prefixes. If it does, the animation string will be ‘animation’ and there is no need for any keyframe prefixes. If it doesn’t then we go through all the browser prefixes (to date :)) and check if there is a property on the style collection called browser prefix + AnimationName. If there is, the loop exits and we define the right animation string and keyframe prefix and set animation to true. On Firefox this will result in MozAnimation and -moz- and on Chrome in WebkitAnimation and -webkit- so on. This we can then use to create a new CSS animation in JavaScript. If none of the prefix checks return a supported style property we animate in an alternative fashion.

    if( animation === false ) {
     
      // animate in JavaScript fallback
     
    } else {
      elm.style[ animationstring ] = 'rotate 1s linear infinite';
     
      var keyframes = '@' + keyframeprefix + 'keyframes rotate { '+
                        'from {' + keyframeprefix + 'transform:rotate( 0deg ) }'+
                        'to {' + keyframeprefix + 'transform:rotate( 360deg ) }'+
                      '}';
     
      if( document.styleSheets && document.styleSheets.length ) {
     
          document.styleSheets[0].insertRule( keyframes, 0 );
     
      } else {
     
        var s = document.createElement( 'style' );
        s.innerHTML = keyframes;
        document.getElementsByTagName( 'head' )[ 0 ].appendChild( s );
     
      }
     
    }

    With the animation string defined we can set a (shortcut notation) animation on our element. Now, adding the keyframes is trickier. As they are not part of the original Animation but disconnected from it in the CSS syntax (to give them more flexibility and allow re-use) we can’t set them in JavaScript. Instead we need to write them out as a CSS string.

    If there is already a style sheet applied to the document we add this keyframe definition string to that one, if there isn’t a style sheet available we create a new style block with our keyframe and add it to the document.

    You can see the detection in action and a fallback JavaScript solution on JSFiddle:

    Quite simple, but also a bit more complex than I originally thought. You can also dynamically detect and change current animations as this post by Wayne Pan and this demo by Joe Lambert explains but this also seems quite verbose.

    I’d love to have a CSSAnimations collection for example where you could store different animations in JSON or as a string and have their name as the key. Right now, creating a new rule dynamically and adding it either to the document or append it to the ruleset seems to be the only cross-browser way. Thoughts?

  7. Calculated drop shadows in HTML5 canvas

    One of the best new features of HTML5 when it comes to visual effects is the canvas element and its API. On the surface, it doesn’t look like much – just a rectangle in the page you can paint on and wipe. Much like an etch-a-sketch. However, the ability to transform, rotate and scale its coordinate system is very powerful indeed once you master it.

    Today I want to quickly show how you can do (well simulate) something rather complex with it, like a calculated drop shadow on an element. To see what I mean with this, check out the following demo which is also available on the Demo Studio:


    See animated version on JSFiddle

    (This is using JSFiddle to show you the demos, so you can click the different tabs to see the JavaScript and CSS needed for the effects. All of the demos are also available on GitHub.)

    As you can see, the shadow becomes more blurred and less pronounced the further away the “sun” is from it. You can use the mouse to see the effect in the following demo:


    See mouse enabled demo on JSFiddle

    Let’s take a look how that is done. The first step is to have a canvas we can paint on – you do this simply by having a mouse detection script (which we used for years and years) and a canvas with access to its API:


    See step one on JSFiddle

    Click the play button of the above example and you see that you can paint on the canvas. However, the issue is that you keep painting on the canvas instead of only having the orb follow the cursor. To do this, we need to wipe the canvas every time the mouse moves. You do this with clearRect()


    See step two on JSFiddle

    Running the above example now shows that the orb moves with the mouse. Cool, so this is going to be our “sun”. Now we need to place an object on the canvas to cast a shadow. We could just plot it somewhere, but what we really want is it to be in the middle of the canvas and the shadow to go left and right from that. You can move the origin of the canvas’ coordinate system using translate(). Which means though that our orb is now offset from the mouse:


    See step three on JSFiddle

    If you check the “fix mouse position” checkbox you see that this is fixed. As we move the coordinate system to the half of the width of the canvas and half of its height, we also need to substract these values from the mouse x and y position.

    Now we can draw a line from the centre of the canvas to the mouse position to see the distance using c.moveTo( 0, 0 );c.lineTo( distx, disty ); where distx and disty are the mouse position values after the shifting:


    See step four on JSFiddle

    In order to find out the distance of the shadow, all we need to do is multiply the mouse coordinates with -1 – in this demo shown as a red line:


    See step five on JSFiddle

    This gives us a shadow distance from the centre opposite of the mouse position, but we don’t want the full length. Therefore we can apply a factor to the length, in our case 0.6 or 60%:


    See step six on JSFiddle

    Now we are ready for some drop shadow action. You can apply shadows to canvas objects using shadowColor and its distance is shadowOffsetX and shadowOffsetY. In our case, this is the end of the red line, the inversed and factored distance from the mouse position to the centre of the canvas:


    See step seven on JSFiddle

    Now, let’s blur the shadow. Blurring is done using the shadowBlur property and it is a number starting from 0 to the strength of the blur. We now need to find a way to calculate the blur strength from the distance of the mouse to the centre of the canvas. Luckily enough, Pythagoras found out for us years ago how to do it. As the x and y coordinate of the mouse are the catheti of a right-angled triangle, we can calculate the length of the hypothenuse (the distance of the point from the centre of the canvas) using the Square root of the squares of the coordinates or Math.sqrt( ( distx * distx ) + ( disty * disty ) ).

    This gives us the distance in pixels, but what the really want is a number much lower. Therefore we can again calculate a factor for the blur strength – here we use an array for the weakest and strongest blur blur = [ 2, 9 ]. As the canvas itself also has a right-angled triangle from the centre to the top edge points we can calculate the longest possible distance from the center using longest = Math.sqrt( ( hw * hw ) + ( hh * hh ) ) where hw is half the width of the canvas and hh half the height. Now all we need to do is to calculate the factor to multiply the distance with as blurfactor = blur[1] / longest. The blur during the drawing of the canvas is the distance of the mouse position multiplied with the factor or currentblur = parseInt( blurfactor * realdistance, 10 );. We disregard blur values below the range we defined earlier and we have our blurred shadow:


    See step eight on JSFiddle

    In order to make the shadow weaker the further away the mouse is we can use the alpha value of its rgba() colour. The same principle applies as with the blur, we set our edge values as shadowalpha = [ 3, 8 ] and after calculating them from the distance we apply their inverse as the alpha value with c.shadowColor = 'rgba(0,0,0,' + (1 - currentalpha / 10) + ')';. This blurs and weakens the shadow:


    See step nine on JSFiddle

    You can do a lot more with this, for example we could also scale the sun orb the further out it gets or use a second shape to resize and blur it. You can also go completely overboard.

    Found a way to optimise this? Tell us about it!