Mozilla

JavaScript Articles

Sort by:

View:

  1. No Single Benchmark for the Web

    Google released a new JavaScript benchmark a few days ago called Octane. New benchmarks are always welcome, as they push browsers to new levels of performance in new areas. I was particularly pleased to see the inclusion of pdf.js, which unlike most benchmarks is real-world code, as well as the GB Emulator which is a very interesting type of performance-intensive code. However, every benchmark suite has limitations, and it is worth keeping that in mind, especially given the new benchmark’s title in the announcement and in the project page as “The JavaScript Benchmark Suite for the Modern Web” – which is a high goal to set for a single benchmark.

    Now, every benchmark must pick some code to run out of all the possible code out there, and picking representative code is very hard. So it is always understandable that benchmarks are never 100% representative of the code that exists and is important. However, even taking that into account, I have concerns with some of the code selected to appear in Octane: There are better versions of two of the five new benchmarks, and performance on those better versions is very different than the versions that do appear in Octane.

    Benchmarking black boxes

    One of the new benchmarks in Octane is “Mandreel”, which is the Bullet physics engine compiled by Mandreel, a C++ to JS compiler. Bullet is definitely interesting code to include in a benchmark. However the choice of Mandreel’s port is problematic. One issue is that Mandreel is a closed-source compiler, a black box, making it hard to learn from it what kind of code is efficient and what should be optimized. We just have a generated code dump, which, as a commercial product, would cost money for anyone to reproduce those results with modifications to the original C++ being run or a different codebase. We also do not have the source code compiled for this particular benchmark: Bullet itself is open source, but we don’t know the specific version compiled here, nor do we have the benchmark driver code that uses Bullet, both of which would be necessary to reproduce these results using another compiler.

    An alternative could have been to use Bullet compiled by Emscripten, an open source compiler that similarly compiles C++ to JS (disclaimer: I am an Emscripten dev). Aside from being open, Emscripten also has a port of Bullet (a demo can be seen here) that can interact in a natural way with regular JS, making it usable in normal web games and not just compiled ones, unlike Mandreel’s port. This is another reason for preferring the Emscripten port of Bullet instead.

    Is Mandreel representative of the web?

    The motivation Google gives for including Mandreel in Octane is that Mandreel is “used in countless web-based games.” It seems that Mandreel is primarily used in the Chrome Web Store (CWS) and less outside in the normal web. The quoted description above is technically accurate: Mandreel games in the CWS are indeed “web-based” (written in JS+HTML+WebGL) even if they are not actually “on the web”, where by “on the web” I mean outside of the walled garden of the CWS and in the normal web that all browsers can access. And it makes perfect sense that Google cares about the performance of code that runs in the CWS, since Google runs and profits from that store. But it does call into question the title of the Octane benchmark as “The JavaScript Benchmark Suite for the Modern Web.”

    Performance of generated code is highly variable

    With that said, it is still fair to say that compiler-generated code is increasing in importance on the web, so some benchmark must be chosen to represent it. The question is how much the specific benchmark chosen represents compiled code in general. On the one hand the compiled output of Mandreel and Emscripten is quite similar: both use large typed arrays, the same Relooper algorithm, etc., so we could expect performance to be similar. That doesn’t seem to always be the case, though. When we compare Bullet compiled by Mandreel with Bullet compiled by Emscripten – I made a benchmark of that a while back, it’s available here – then on my MacBook pro, Chrome is 1.5x slower than Firefox on the Emscripten version (that is, Chrome takes 1.5 times as long to execute in this case), but 1.5x faster on the Mandreel version that Google chose to include in Octane (that is, Chrome receives a score 1.5 times larger in this case). (I tested with Chrome Dev, which is the latest version available on Linux, and Firefox Aurora which is the best parallel to it. If you run the tests yourself, note that in the Emscripten version smaller numbers are better while the opposite is true in the Octane version.)

    (An aside, not only does Chrome have trouble running the Emscripten version quickly, but that benchmark also exposes a bug in Chrome where the tab consistently crashes when the benchmark is reloaded – possibly a dupe of this open issue. A serious problem of that nature, that does not happen on the Mandreel-compiled version, could indicate that the two were optimized differently as a result of having received different amounts of focus by developers.)

    Another issue with the Mandreel benchmark is the name. Calling it Mandreel implies it represents all Mandreel-generated code, but there can be huge differences in performance depending on what C/C++ code is compiled, even with a single compiler. For example, Chrome can be 10-15x slower than Firefox on some Emscripten-compiled benchmarks (example 1, example 2) while on others it is quite speedy (example). So calling the benchmark “Mandreel-Bullet” would have been better, to indicate it is just one Mandreel-compiled codebase, which cannot represent all compiled code.

    Box2DWeb is not the best port of Box2D

    “Box2DWeb” is another new benchmark in Octane, in which a specific port of Box2D to JavaScript is run, namely Box2DWeb. However, as seen here (see also this), Box2DWeb is significantly slower than other ports of Box2D to the web, specifically Mandreel and Emscripten’s ports from the original C++ that Box2D is written in. Now, you can justify excluding the Mandreel version because it cannot be used as a library from normal JS (just as with Bullet before), but the Emscripten-compiled one does not have that limitation and can be found here. (Demos can be seen here and here.)

    Another reason for preferring the Emscripten version is that it uses Box2D 2.2, whereas Box2DWeb uses the older Box2D 2.1. Compiling the C++ code directly lets the Emscripten port stay up to date with the latest upstream features and improvements far more easily.

    It is possible that Google surveyed websites and found that the slower Box2DWeb was more popular, although I have no idea whether that was the case, but if so that would partially justify preferring the slower version. However, even if that were true, I would argue that it would be better to use the Emscripten version because as mentioned earlier it is faster and more up to date. Another factor to consider is that the version included in Octane will get attention and likely an increase in adoption, which makes it all the more important to select the one that is best for the web.

    I put up a benchmark of Emscripten-compiled Box2D here, and on my machine Chrome is 3x slower than Firefox on that benchmark, but 1.6x faster on the version Google chose to include in Octane. This is a similar situation to what we saw earlier with the Mandreel/Bullet benchmark and it raises the same questions about how representative a single benchmark can be.

    Summary

    As mentioned at the beginning, all benchmarks are imperfect. And the fact that the specific code samples in Octane are ones that Chrome runs well does not mean the code was chosen for that reason: The opposite causation is far more likely, that Google chose to focus on optimizing those and in time made Chrome fast on them. And that is how things properly work – you pick something to optimize for, and then optimize for it.

    However, in 2 of the 5 new benchmarks in Octane there are good reasons for preferring alternative, better versions of those two benchmarks as we saw before. Now, it is possible that when Google started to optimize for Octane, the better options were not yet available – I don’t know when Google started that effort – but the fact that better alternatives exist in the present makes substantial parts of Octane appear less relevant today. Of course, if performance on the better versions was not much different than the Octane versions then this would not matter, but as we saw there were in fact significant differences when comparing browsers on those versions: One browser could be significantly better on one version of the same benchmark but significantly slower on another.

    What all of this shows is that there cannot be a single benchmark for the modern web. There are simply too many kinds of code, and even when we focus on one of them, different benchmarks of that particular task can behave very differently.

    With that said, we shouldn’t be overly skeptical: Benchmarks are useful. We need benchmarks to drive us forward, and Octane is an interesting new benchmark that, even with the problems mentioned above, does contain good ideas and is worth focusing on. But we should always be aware of the limitations of any single benchmark, especially when a single benchmark claims to represent the entire modern web.

     

  2. The Web Developer Toolbox: Modernizr

    This is the third in a series of articles dedicated to useful libraries that all web developers should have in their toolbox. The intent is to show you what those libraries can do and help you to use them at their best. This third article is dedicated to the Modernizr library.

    Introduction

    Modernizer is a library originally written by Faruk Ateş.

    It is one of the key libraries for building cross-browser websites or applications in a modern fashion. The heart of the library is the web design pattern known as Progressive enhancement & Graceful degradation. This design pattern does not require Modernizr, but Modernizr can make things a lot easier. It detects the availability of native implementations for next-generation web technologies such as HTML5 or CSS3 and allow you to adapt your application accordingly, which is way better than trying some ugly voodoo user-agent sniffing.

    Basic usage

    Using this library is amazingly simple: Download it, link it to your pages—you’re done!

    Modernizr will automatically add some CSS classes to the root html element. For example if you want to test Web Sockets support, it will add a websockets class to the html element if the browser supports that feature, otherwise it will add the no-websockets class. It will do the same with JavaScript by adding a global variable Modernizr.websocket with a boolean value.

    Let’s see a simple example: Doing some stuff with RGBa colors.

    First: Download a customized version of Modernizr

    Modernizr, download page.

    Second: Link it to your document

    <!DOCTYPE html>
    <!--
    The "no-js" class is here as a fallback.
    If Modernizr is not running, you'll know
    something is wrong and you will be able to act
    accordingly. In contrast, if everything goes well,
    Modernizr will remove that special class.
    -->
    <html class="no-js">
    <head>
        <meta charset="utf-8">
        <title>I want to do stuff with RGBa</title>
        <script src="modernizr.js"></script>
    </head>
    <body>
    ...
    </body>
    </html>

    Third: Use it

    With CSS

    .rgba div {
        /* Do things with CSS for browsers that support RGBa colors */
    }
     
    .no-rgba div {
        /* Do things with CSS for browsers that DO NOT support RGBa colors */
    }

    With JavaScript

    if(Modernizr.rgba) {
        // Do things with JS for browsers that support RGBa colors
    } else {
        // Do things with JS for browsers that DO NOT support RGBa colors
    }

    Let’s see this silly example in action:

    %CODEtoolbox-3-1%

    Advanced usage

    The basic usage is already awesome when you have to deal with a heterogeneous environment (such as mobile browsers for example), but there’s more.

    Conditional loading

    Modernizr offers a convenient way to do conditional loading. Actually, the YepNope library is a standalone spin-off of the Modernizr project. So, if you wish, you can bundled YepNope directly inside Modernizr. It’s perfect if you want to load based polyfills depending on specific browser capacity.

    Modernizr.load({
        test: Modernizr.indexeddb,
        nope: "indexeddb-polyfill.js"
    });

    This is a very powerful tool: do not hesitate to read the documentation. Note that the Modernizr team maintain a list of very accurate polyfills. Feel free to use whatever you need (with caution, of course).

    Custom tests

    Modernizr come with a set of 44 tests for mainstream technologies. If you need to test some other technologies, Modernizr provide an API to build and plug your own tests.

    // Let's test the native JSON support ourselves
    Modernizr.addTest('json', function(){
        return window.JSON
            && window.JSON.parse
            && typeof window.JSON.parse === 'function'
            && window.JSON.stringify
            && typeof window.JSON.stringify === 'function';
    });
    

    Assuming the above test passes, there will be now a json class on the HTML element and Modernizr.json will be true. Otherwise, there will be a no-json class on the HTML element and Modernizr.json will be false.

    Dealing with CSS prefix

    CSS prefixes is a very sensitive subject. Modernizr provides cross-browser code to take care of this issue. Modernizr offers a very useful tool to deal with this: Modernizr.prefixed(). This method works with CSS properties (in the CSS OM camelCase style) as well as with DOM properties.

    For example, Modernizr.prefixed("transition") will return “MozTransition” with Firefox but “WebkitTransition” with Safari and Chrome.

    Testing media-queries

    There is currently no simple way to test a media query from JS in any browser. To help with that, Modernizr has a special tool: Modernizr.mq(). This method will test the media query of your choice and will return true or false accordingly.

    if(Modernizr.mq("screen and (max-width: 400px)")) {
        // Do some stuff for small screens
    }

    Limits and precautions

    This library is a fantastic tool but it’s not magic. You should use it with caution and do not forget about other techniques to deal with unpredictable behaviors. For example, do not forget to rely on the CSS cascade when it’s sufficient.

    The following example is a huge misuse of Modernizr:

    div {
        color : white;
    }
     
    .rgba div {
        background : rgba(0,0,0,.8);
    }
     
    .no-rgba div {
        background : #333;
    }

    If for some reason Modernizr is not executed, your text will not be readable (white text over a white background). In this specific case, you are better doing the following (which, by the way, is also easier to read and maintain):

    div {
        color : white;
        background : #333;
        background : rgba(0,0,0,.8);
    }

    So, don’t be blind when you use this library, take the time to think about what will happen if Modernizr is not available. In many case you have existing fallbacks, don’t forget to use them.

    Conclusion

    Modernizr is the most useful tool when you have to build large cross-browser stuff, from the oldest Internet Explorer 6 to the latest Firefox Nightly. Once you master it, you will be able to add some magic to your sites and applications. However, as with all the powerful tools, it takes some time to become comfortable with and to use it wisely at its full potential. But, Modernizr is definitely worth the effort.

  3. The Web Developer Toolbox: ThreeJS

    This is the second of a series of articles dedicated to the useful libraries that all web developers should have in their toolbox. The intent is to show you what those libraries can do and help you to use them at their best. This second article is dedicated to the ThreeJS library.

    Introduction

    ThreeJS is a library originally written by Ricardo Cabello Miguel aka “Mr. Doob“.

    This library makes WebGL accessible to common human beings. WebGL is a powerful API to manipulate 3D environments. This web technology is standardized by the Kronos group and Firefox, Chrome and Opera now implement it as a 3D context for the HTML canvas tag. WebGL is basically a web version of another standard : OpenGL ES 2.0. As a consequence, this API is a “low level” API that require skills and knowledge beyond what web designers are used to. That’s where ThreeJS comes into play. ThreeJS gives web developers access to the power of WebGL without all the knowledge required by the underlying API.

    Basic usage

    The library has good documentation with many examples. You’ll notice that some parts of the documentation are not complete yet (feel free to help). However, the library and examples source code are very well structured, so do not hesitate to read the source.

    Even though ThreeJS simplifies many things, you still have to be comfortable with some basic 3D concepts. Basically, ThreeJS uses the following concepts:

    1. The scene: the place where all 3D objects will be placed and manipulated in a 3D space.
    2. The camera: a special 3D object that will define the rendering point of view as well as the type of spatial rendering (perspective or isometric)
    3. The renderer: the object in charge of using the scene and the camera to render your 3D image.

    Within the scene, you will have several 3D objects which can be of the following types:

    • A mesh: A mesh is an object made of a geometry (the shape of your object) and a material (its colors and texture)
    • A light point: A special object that defines a light source to highlight all your meshes.
    • A camera, as described above.

    The following example will draw a simple wireframe sphere inside an HTML element with the id “myPlanet”.

    /**
     * First, let's prepare some context
     */
     
    // The WIDTH of the scene to render
    var __WIDTH__  = 400,
     
    // The HEIGHT of the scene to render
        __HEIGHT__ = 400,
     
    // The angle of the camera that will show the scene
    // It is expressed in degrees
        __ANGLE__ = 45,
     
    // The shortest distance the camera can see
        __NEAR__  = 1,
     
    // The farthest distance the camera can see
        __FAR__   = 1000
     
    // The basic hue used to color our object
        __HUE__   = 0;
     
    /**
     * To render a 3D scene, ThreeJS needs 3 elements:
     * A scene where to put all the objects
     * A camera to manage the point of view
     * A renderer place to show the result
     */
    var scene  = new THREE.Scene(),
        camera = new THREE.PerspectiveCamera(__ANGLE__,
                                             __WIDTH__ / __HEIGHT__,
                                             __NEAR__,
                                             __FAR__),
        renderer = new THREE.WebGLRenderer();
     
    /**
     * Let's prepare the scene
     */
     
    // Add the camera to the scene
    scene.add(camera);
     
    // As all objects, the camera is put at the
    // 0,0,0 coordinate, let's pull it back a little
    camera.position.z = 300;
     
    // We need to define the size of the renderer
    renderer.setSize(__WIDTH__, __HEIGHT__);
     
    // Let's attach our rendering zone to our page
    document.getElementById("myPlanet").appendChild(renderer.domElement);
     
    /**
     * Now we are ready, we can start building our sphere
     * To do this, we need a mesh defined with:
     *  1. A geometry (a sphere)
     *  2. A material (a color that reacts to light)
     */
    var geometry, material, mesh;
     
    // First let's build our geometry
    //
    // There are other parameters, but you basically just
    // need to define the radius of the sphere and the
    // number of its vertical and horizontal divisions.
    //
    // The 2 last parameters determine the number of
    // vertices that will be produced: The more vertices you use,
    // the smoother the form; but it will be slower to render.
    // Make a wise choice to balance the two.
    geometry = new THREE.SphereGeometry( 100, 20, 20 );
     
    // Then, prepare our material
    var myMaterial = {
        wireframe : true,
        wireframeLinewidth : 2
    }
     
    // We just have to build the material now
    material = new THREE.MeshPhongMaterial( myMaterial );
     
    // Add some color to the material
    material.color.setHSV(__HUE__, 1, 1);
     
    // And we can build our the mesh
    mesh = new THREE.Mesh( geometry, material );
     
    // Let's add the mesh to the scene
    scene.add( mesh );
     
    /**
     * To be sure that we will see something,
     * we need to add some light to the scene
     */
     
    // Let's create a point light
    var pointLight = new THREE.PointLight(0xFFFFFF);
     
    // and set its position
    pointLight.position.x = -100;
    pointLight.position.y = 100;
    pointLight.position.z = 400;
     
    // Now, we can add it to the scene
    scene.add( pointLight );
     
     
    // And finally, it's time to see the result
    renderer.render( scene, camera );

    And if you want to animate it (for example, make the sphere spin), it’s this easy:

    function animate() {
        // beware, you'll maybe need a shim
        // to use requestAnimationFrame properly
        requestAnimationFrame( animate );
     
        // First, rotate the sphere
        mesh.rotation.y -= 0.003;
     
        // Then render the scene
        renderer.render( scene, camera );
    }
     
    animate();

    JSFiddle demo.

    Advanced usage

    Once you master the basics, ThreeJS provides you with some advanced tools.

    Rendering system

    As an abstraction layer, ThreeJS offer options to render a scene other than with WebGL. You can use the Canvas 2D API as well as SVG to perform your rendering. There is some difference between all these rendering contexts. The most obvious one is performance. Because WebGL is hardware accelerated, the rendering of complex scene is amazingly faster with it. On the other hand, because WebGL does not deal always well with anti-aliasing, the SVG or Canvas2D rendering can be better if you want to perform some cell-shading (cartoon-like) stuff. As a special advantage, SVG rendering gives you a full DOM tree of objects, which can be useful if you want access to those objects. It can have a high cost in term of performance (especially if you animate your scene), but it allows you to not rebuild a full retained mode graphic API.

    Mesh and particles

    ThreeJS is perfect for rendering on top of WebGL, but it is not an authoring tool. To model 3D objects, you have a choice of 3D software. Conveniently, ThreeJS is available with many scripts that make it easy to import meshes from several sources (Examples include: Blender, 3DSMax or the widely supported OBJ format).

    It’s also possible to easily deploy particle systems as well as using Fog, Matrix and custom shaders. ThreeJS also comes with a few pre-built materials: Basic, Face, Lambert, Normal, and Phong). A WebGL developer will be able to build his own on top of the library, which provide some really good helpers. Obviously, building such custom things requires really specific skills.

    Animating mesh

    If using requestAnimationFrame is the easiest way to animate a scene, ThreeJS provides a couple of useful tools to animate meshes individually: a full API to define how to animate a mesh and the ability to use “bones” to morph and change a mesh.

    Limits and precaution

    One of the biggest limitations of ThreeJS is related to WebGL. If you want to use it to render your scene, you are constrained by the limitations of this technology. You become hardware dependent. All browsers that claim to support WebGL have strong requirements in terms of hardware support. Some browsers will not render anything if they do not run with an appropriate hardware. The best way to avoid trouble is to use a library such as modernizr to switch between rendering systems based on each browser’s capabilities. However, take care when using non-WebGL rendering systems because they are limited (e.g. the Phong material is only supported in a WebGL context) and infinitely slower.

    In terms of browser support, ThreeJS supports all browsers that support WebGL, Canvas2D or SVG, which means: Firefox 3.6+, Chrome 9+, Opera 11+, Safari 5+ and even Internet Explorer 9+ if you do not use the WebGL rendering mode. If you want to rely on WebGL, the support is more limited: Firefox 4+, Chrome 9+, Opera 12+, Safari 5.1+ only. You can forget Internet Explorer (even the upcoming IE10) and almost all mobile browsers currently available.

    Conclusion

    ThreeJS drastically simplifies the process of producing 3D images directly in the browser. It gives the ability to do amazing visual effects with an easy to use API. By empowering you, it allow you to unleash your creativity.

    In conclusion, here are some cool usages of ThreeJS:

  4. Using window.matchMedia to do media queries in JavaScript

    For people building web sites, Responsive Web Design has become a natural approach to making sure the content is available for as many users as possible. This is usually attended to via CSS media queries. However, there is a JavaScript alternative as well.

    Introducing window.matchMedia

    The way to approach media queries in JavaScript is through window.matchMedia. Basically, you just use the same approach as with CSS, but with a JavaScript call:

    var widthQuery = window.matchMedia("(min-width: 600px)");

    This query returns a MediaQueryList object, on which you can do a few things:

    matches
    Boolean whether the query matched or not.
    media
    Serialized media query list.
    addListener
    Adding event listener to a media query. Much preferred over polling values or similar.
    removeListener
    Removing event listener from a media query.

    Therefore, the easy way to determine if a media query matched is using the matches property:

    var widthMatch = window.matchMedia("(min-height: 500px)").matches;

    Adding listeners is very easy:

    function getOrientationValue (mediaQueryList) {
        console.log(mediaQueryList.matches);
    }
     
    portraitOrientationCheck = window.matchMedia("(orientation: portrait)");
    portraitOrientationCheck.addListener(getOrientationValue);

    Demo and code

    I’ve put together a window.matchMedia demo where you can see some queries in action. Try resizing the window and see the values change.

    The complete JavaScript code for that demo, which is of course available on GitHub, is as follows:


    (function () {
        var matchMediaSupported = document.querySelector("#matchmedia-supported"),
            width600 = document.querySelector("#width-600"),
            height500 = document.querySelector("#height-500"),
            portraitOrientation = document.querySelector("#portrait-orientation"),
            width600Check,
            height500Check,
            portraitOrientationCheck;
     
        if (window.matchMedia) {
            matchMediaSupported.innerHTML = "supported";
     
            // Establishing media check
            width600Check = window.matchMedia("(min-width: 600px)"),
            height500Check = window.matchMedia("(min-height: 500px)"),
            portraitOrientationCheck = window.matchMedia("(orientation: portrait)");
     
            // Add listeners for detecting changes
            width600Check.addListener(setWidthValue);
            height500Check.addListener(setHeightValue);
            portraitOrientationCheck.addListener(setOrientationValue);
        }
     
        function setWidthValue (mediaQueryList) {
            width600.innerHTML = mediaQueryList.media;
        }
     
        function setHeightValue (mediaQueryList) {
            height500.innerHTML = mediaQueryList.matches;
        }
     
        function setOrientationValue (mediaQueryList) {
            portraitOrientation.innerHTML = mediaQueryList.matches;
        }
     
        // Setting initial values at load
        function setValues () {
            width600.innerHTML = width600Check.matches;
            height500.innerHTML = height500Check.matches;
            portraitOrientation.innerHTML = portraitOrientationCheck.matches;
        }
     
        window.addEventListener("DOMContentLoaded", setValues, false);
    })();

    Web browser support

    At this time, window.matchMedia has been implemented in:

    • Firefox 6+
    • Google Chrome 9+
    • Safari 5.1+. Note: doesn’t support addListener.
    • Firefox mobile
    • Google Chrome beta on Android. Note: doesn’t support addListener.
    • Safari 5 on iOS. Note: doesn’t support addListener.
    • Android stock browser. Note: doesn’t support addListener.

    It is also planned to be in Internet Explorer 10.

    For older/unsupported web browsers, you can try the matchMedia() polyfill, although it doesn’t support addListener.

  5. The Web Developer Toolbox: Raphaël

    This is the first of a series of articles dedicated to the useful libraries that all web developers should have in their toolbox. My intent is to show you what those libraries can do and help you to use them at their best. This first article is dedicated to the Raphaël library.

    Introduction

    Raphaël is a library originally written by Dmitry Baranovskiy and is now part of Sencha Labs.

    The goal of this library is to simplify work with vector graphics on the Web. Raphaël relies on the SVG W3C Recommendation (which is well supported in all modern browsers) and falls back to the Micrsoft VML language in order to address legacy versions of Internet Explorer. It also tries to harmonize some working issues across SVG implementations such as the SVG Animations. As a consequence, Raphaël is a very nice wrapper to produce consistent kick-ass graphics all over the Web.

    Basic usage

    The library has very good documentation with many examples. Do not hesitate to use it extensively.

    The following example will draw a simple red circle inside an HTML element with the id “myPaper”.

    // the following example creates a drawing zone
    // that is 100px wide by 100px high.
    // This drawing zone is created at the top left corner
    // of the #myPaper element (or its top right corner in
    // dir="rtl" elements)
    var paper = Raphael("myPaper", 100, 100);
     
    // The circle will have a radius of 40
    // and its center will be at coordinate 50,50
    var c = paper.circle(50, 50, 40);
     
    // The circle will be filled with red
    // Note that the name of each element property
    // follow the SVG recommendation
    c.attr({
        fill: "#900"
    });

    Advanced usage

    Despite the fact that Raphaël reduces the possibilities offered by SVG (mainly because of the VML fallback) it allows one to perform very advanced stuff:

    • Advance Matrix transformation
    • Advance event handler
    • Cross browser animations
    • Easy drag system
    • Path intersection detection

    Raphaël is also extensible through an extension system that allows you to build custom functions.

    For example, here’s an extension to draw pie charts:

    /**
     * Pie method
     *
     * cx: x position of the rotating center of the pie
     * cy: y position of the rotating center of the pie
     * r : radius of the pie
     * a1: angle expressed in degrees where the pie start
     * a2: angle expressed in degrees where the pie end
     */
    Raphael.fn.pie = function (cx, cy, r, a1, a2) {
        var d,
            flag = (a2 - a1) &gt; 180;
     
        a1 = (a1 % 360) * Math.PI / 180;
        a2 = (a2 % 360) * Math.PI / 180;
     
        d = [
            // Setting the rotating axe of the pie
            "M", cx, cy,
     
            // Go to the start of the curve
            "l", r * Math.cos(a1), r * Math.sin(a1),
     
            // Drawing the curve to its end
            "A", r, r, "0", +flag, "1",
            cx + r * Math.cos(a2), cy + r * Math.sin(a2),
     
            // Closing the path
            "z"
        ];
     
        return this.path(d.join(' '));
    };

    Note: In the example above, you have to be familiar with the SVG path syntax (Raphaël will convert it to the VML syntax under the hood), but once it’s done you can reuse it as any other Raphaël primitive. Look at this extension working to draw a color wheel on jsFiddle.

    JSFiddle demo.

    Limits and precaution

    If you are not familiar with SVG and/or want to support legacy MS Internet Explorer browsers, this tool is made for you. However, it’s a JavaScript library, which means that you have to know JavaScript to use it. You cannot use SVG and ask Raphaël to parse it and interpret it (to do that, it exists other libraries).

    In terms of browser support, Raphaël gives you a large base. Raphaël currently supports Firefox 3.0+, Safari 3.0+, Chrome 5.0+, Opera 9.5+ and Internet Explorer 6.0+.

    In fact, the only browser that can not take advantage of Raphaël is the native browser for Android 1.x and 2.x (and obviously many feature phone browsers). This is due to the fact that those browsers do not support any vector language. Android starts (partially) supporting SVG with Android 3.0 so take care if you want to work with all mobile devices.

    Conclusion

    Raphaël was the first library to allow web designers and web developers to use SVG in the wild. If you want to write some nice applications without the need of the full SVG DOM API or if you have to support legacy browsers, this library will give you some power.

    In conclusion, here are some cool usages of Raphaël:

  6. Click highlights with CSS transitions

    When you watch screencasts from time to time you’ll see that some software adds growing dots to the clicks the person explaining does to make them more obvious. Using CSS transitions this can be done very simply in JavaScript, too.
    click highlighting with CSS

    Check out the following demo on JSFiddle and you see what we mean. When you click on the document a dot grows where you clicked and it vanishes again. If you keep the mouse pressed the dot stays and you can move it around.

    JSFiddle demo.

    Moving the dot

    The code is incredibly simple. We generate a DIV element and move it with the mouse. For this, we need JavaScript. Check the comments to see what is going on:

    (function(){
     
      // create a DIV element, give it an ID and add it
      // to the body
      var plot = document.createElement('div'),
          pressed = false;
      plot.id = 'clickhighlightplot';
      document.body.appendChild(plot);
     
      // define offset as half the width of the DIV
      // (this is needed to put the mouse cursor in
      // its centre)
      var offset = plot.offsetWidth / 2;
     
      // when the mouse is moved and the mouse button is pressed,
      // move the DIV to the current position of the mouse cursor
      document.addEventListener('mousemove', function(ev) {
        if (pressed) { moveplot(ev.pageX, ev.pageY); }
      }, false);
     
      // when the mouse button is pressed, add a class called
      // 'down' to the body of the element and define pressed
      // as true. Then move the DIV to the current mouse
      // position.
      document.addEventListener('mousedown', function(ev) {
        document.body.classList.add('down');
        pressed = true;
        moveplot(ev.pageX, ev.pageY);
      }, false);
     
      // when the mouse is released, remove the 'down' class
      // from the body and set pressed to false
      document.addEventListener('mouseup', function(ev) {
        document.body.classList.remove('down');
        pressed = false;
      },  false);
     
      // move the DIV to x and y with the correct offset
      function moveplot(x, y) {
        plot.style.left = x - offset + 'px';
        plot.style.top = y - offset + 'px';
      }
    })();

    This takes care of creating and moving the DIV and also gives us classes on the body element to play with.

    Growing the dot

    The growing of the dot uses CSS transitions. We change the scale of the dot from 0,0 to 1,1 in a certain amount of time. Notice that we need to scale down rather than up as Webkit zooms scaled elements instead of leaving crisp outlines like Firefox does (the first iteration of this script scaled a 10×10 pixel dot upwards and looked horrible).

    #clickhighlightplot {
      cursor: pointer;
      pointer-events: none;
      background: rgba(255, 255, 10, 0.7);
      width:100px;
      height: 100px;
      position: absolute;
      border-radius: 100px;
      -webkit-transition: -webkit-transform 1s;
         -moz-transition: -moz-transform 1s;
          -ms-transition: -ms-transform 1s;
           -o-transition: -o-transform 1s;
              transition: transform 1s;
       -webkit-transform: scale(0, 0);
          -moz-transform: scale(0, 0);
           -ms-transform: scale(0, 0);
            -o-transform: scale(0, 0);
               transform: scale(0, 0);
    }
    .down #clickhighlightplot {
      -webkit-transform: scale(1, 1);
         -moz-transform: scale(1, 1);
          -ms-transform: scale(1, 1);
           -o-transform: scale(1, 1);
              transform: scale(1, 1);
    }

    Fixing the “covered clickable elements” issue

    The main annoyance with the way the script works now is that you cover elements with the growing dot making them effectively unclickable. That might not be what you want which is why we need to make sure the dot covers them but still allows for clicks to go through. The good news is that there is a thing called pointer events for that. This is supported in Firefox and Webkit but sadly enough not in IE and Opera.

    Moving from JS and CSS to pure JS (but using CSS)

    Now, whilst it is cool to be able to maintain all the look and feel in CSS, the issue is that we need to repeat all the vendor prefixes and we run into issues that browsers might not support what we want to do. That’s why sometimes it makes more sense to move the whole functionality into JavaScript as we have the chance to test support there and write less code.

    Clickhighlight.js does all that. Instead of keeping the maintenance in the CSS (and requiring you to add all the vendor prefixes) you can now have the effect by simply adding the script and calling its init() method:

    <script src="clickhighlight.js"></script>
    <script>clickhighlight.init();</script>

    Elements with the class “nohighlight” will not get the effect. You can change the look by passing an initialisation object:

    clickhighlight.init({
      size:        '300px', // the maximum size of the dot
      duration:    '2s',    // duration of the effect (seconds)
      colour:      'green', // the dot colour - RGBA = transparency
      nohighlight: 'notme'  // class of elements not highlighted
    });

    You can see it in action in this video on YouTube:

    The next steps could be to add touch support and to turn this into a bookmarklet so you can use it on any page. Any other ideas?

  7. Porting "Me & My Shadow" to the Web – C++ to JavaScript/Canvas via Emscripten

    Editors note: This is a guest post by Alon Zakai of the Mozilla Emscripten team. Thanks Alon!

    Me & My Shadow is an open source 2D game, with clever gameplay in which you control not one character but two. I happened to hear about it recently when they released a 0.3 version:

    Since I’m looking for games to port to the web, I figured this was a good candidate. It was quite easy to port, here is the result: Me & My Shadow on the Web

    Me and my shadow

    You can also get the source on GitHub.

    The port was done automatically by compiling the original code to JavaScript using Emscripten, an open-source C++ to JavaScript compiler that uses LLVM. Using a compiler like this allows the game to just be compiled, instead of manually rewriting it in JavaScript, so the process can take almost no time.

    The compiled game works almost exactly like the desktop version does on the machines and browsers I’ve tested on. Interestingly, performance looks very good. In this case, it’s mainly because most of what the game does is blit images. It uses the cross-platform SDL API, which is a wrapper library for things like opening a window, getting input, loading images, rendering text, etc. (so it is exactly what a game like this needs). Emscripten supports SDL through native canvas calls, so when you compile a game that uses SDL into JavaScript, it will use Emscripten’s SDL implementation. That implementation implements SDL blit operations using drawImage calls and so forth, which browsers generally hardware accelerate these days, so the game runs as fast as it would natively.

    For example, if the C++ code has

    SDL_BlitSurface(sprite, NULL, screen, position)

    then that means to blit the entire bitmap represented by sprite into the screen, at a specific position. Emscripten’s SDL implementation does some translation of arguments, and then calls

    ctx.drawImage(src.canvas, sr.x, sr.y, sr.w, sr.h, dr.x, dr.y, sr.w, sr.h);

    which draws the sprite, contained in src.canvas, into the context representing the screen, at the correct position and size. In other words, the C++ code is translated automatically into code that uses native HTML canvas operations in an efficient manner.

    There are some caveats though. The main problem is browser support for necessary features, the main problems I ran into here are typed arrays and the Blob constructor:

    • Typed arrays are necessary to run compiled C++ code quickly and with maximum compatibility. Emscripten can compile code without them, but the result is slower and needs manual correction for compatibility. Thankfully, all browsers are getting typed arrays. Firefox, Chrome and Opera already have them, Safari was only missing FloatArray64 until recently I believe, and IE will get them in IE10.
    • The Blob constructor is necessary because this game uses Emscripten’s new compression option. It takes all the datafiles (150 or so), packs them into a single file, does LZMA on that, and then the game in the browser downloads that, decompresses, and splits it up. This makes the download much smaller (but does mean there is a short pause to decompress). The issue though is that we end up with data for each file in a typed array. It’s easy to use the BlobBuilder for images, but for audio, they need the mimetype set or they fail to decode, and only the Blob constructor supports that. It looks like only Firefox has the Blob constructor so far, I’ve been told on Twitter there might be a workaround for Chrome that I am hoping to hear more about. Not sure about other browsers. But, the game should still work, just without sound effects and music.

    Another caveat is that there is some unavoidable amount of manual porting necessary:

    JavaScript main loops must be written in an asynchronous way: A callback for each frame. Thankfully, games are usually written in a way that the main loop can easily be refactored into a function that does one iteration, and that was the case here. Then that function that does one main loop iteration is called each frame from JavaScript. However, there are other cases of synchronous code that are more annoying, for example fadeouts that happen when a menu item is picked are done synchronously (draw, SDL_Delay, draw, etc.). This same problem turned up when I ported Doom, I guess it’s a common code pattern. So I just disabled those fadeouts for now; if you do want them in a game you port, you’d need to refactor them to be asynchronous.

    Aside from that, everything pretty much just worked. (The sole exception was that this code fell prey to an LLVM LTO bug, but Rafael fixed it.) So in conclusion I would argue that there is no reason not to run games like these on the web: They are easy to port, and they run nice and fast.

  8. Old tricks for new browsers – a talk at jQuery UK 2012

    Last Friday around 300 developers went to Oxford, England to attend jQuery UK and learn about all that is hot and new about their favourite JavaScript library. Imagine their surprise when I went on stage to tell them that a lot of what jQuery is used for these days doesn’t need it. If you want to learn more about the talk itself, there is a detailed report, slides and the audio recording available.

    The point I was making is that libraries like jQuery were first and foremost there to give us a level playing field as developers. We should not have to know the quirks of every browser and this is where using a library allows us to concentrate on the task at hand and not on how it will fail in 10 year old browsers.

    jQuery’s revolutionary new way of looking at web design was based on two main things: accessing the document via CSS selectors rather than the unwieldy DOM methods and chaining of JavaScript commands. jQuery then continued to make event handling and Ajax interactions easier and implemented the Easing equations to allow for slick and beautiful animations.

    However, this simplicity came with a prize: developers seem to forget a few very simple techniques that allow you to write very terse and simple to understand JavaScripts that don’t rely on jQuery. Amongst others, the most powerful ones are event delegation and assigning classes to parent elements and leave the main work to CSS.

    Event delegation

    Event Delegation means that instead of applying an event handler to each of the child elements in an element, you assign one handler to the parent element and let the browser do the rest for you. Events bubble up the DOM of a document and happen on the element you want to get and each of its parent elements. That way all you have to do is to compare with the target of the event to get the one you want to access. Say you have a to-do list in your document. All the HTML you need is:

    <ul id="todo">
      <li>Go round Mum's</li>
      <li>Get Liz back</li>
      <li>Sort life out!</li>
    </ul>

    In order to add event handlers to these list items, in jQuery beginners are tempted to do a $('#todo li').click(function(ev){...}); or – even worse – add a class to each list item and then access these. If you use event delegation all you need in JavaScript is:

    document.querySelector('#todo').addEventListener( 'click',
      function( ev ) {
        var t = ev.target;
        if ( t.tagName === 'LI' ) {
          alert( t + t.innerHTML );
          ev.preventDefault();
        }
    }, false);

    Newer browsers have a querySelector and querySelectorAll method (see support here) that gives you access to DOM elements via CSS selectors – something we learned from jQuery. We use this here to access the to-do list. Then we apply an event listener for click to the list.

    We read out which element has been clicked with ev.target and compare its tagName to LI (this property is always uppercase). This means we will never execute the rest of the code when the user for example clicks on the list itself. We call preventDefault() to tell the browser not to do anything – we now take over.

    You can try this out in this fiddle or embedded below:

    JSFiddle demo.

    The benefits of event delegation is that you can now add new items without having to ever re-assign handlers. As the main click handler is on the list new items automatically will be added to the functionality. Try it out in this fiddle or embedded below:

    JSFiddle demo.

    Leaving styling and DOM traversal to CSS

    Another big use case of jQuery is to access a lot of elements at once and change their styling by manipulating their styles collection with the jQuery css() method. This is seemingly handy but is also annoying as you put styling information in your JavaScript. What if there is a rebranding later on? Where do people find the colours to change? It is a much simpler to add a class to the element in question and leave the rest to CSS. If you think about it, a lot of times we repeat the same CSS selectors in jQuery and the style document. Seems redundant.

    Adding and removing classes in the past was a bit of a nightmare. The way to do it was using the className property of a DOM element which contained a string. It was then up to you to find if a certain class name is in that string and to remove and add classes by adding to or using replace() on the string. Again, browsers learned from jQuery and now have a classList object (support here) that allows easy manipulation of CSS classes applied to elements. You have add(), remove(), toggle() and contains() to play with.

    This makes it dead easy to style a lot of elements and to single them out for different styling. Let’s say for example we have a content area and want to show one at a time. It is tempting to loop over the elements and do a lot of comparison, but all we really need is to assign classes and leave the rest to CSS. Say our content is a navigation pointing to articles. This works in all browsers:

    <header>
      <h1>Profit plans</h1>
    </header>
    <section id="content">
      <nav id="nav">
        <ul>
          <li><a href="#step1">Step 1: Collect Underpants</a></li>
          <li><a href="#step2">Step 2: ???</a></li>
          <li><a href="#step3">Step 3: Profit!</a></li>
        </ul>
      </nav>
      <article id="step1">
        <header><h1>Step 1: Collect Underpants</h1></header>
        <section>
          <p>
            Make sure Tweek doesn't expect anything, then steal underwear
            and bring it to the mine.
          </p>
        </section>
        <footer><a href="#nav">back to top</a></footer>
      </article>
      <article id="step2">
        <header><h1>Step 2: ???</h1></header>
        <section>
          <p>WIP</p>
        </section>
        <footer><a href="#nav">back to top</a></footer>
      </article>
      <article id="step3">
        <header><h1>Step 3: Profit</h1></header>
        <section>
          <p>Yes, profit will come. Let's sing the underpants gnome song.</p>
        </section>
        <footer><a href="#nav">back to top</a></footer>
      </article>
    </section>

    Now in order to hide all the articles, all we do is assign a ‘js’ class to the body of the document and store the first link and first article in the content section in variables. We assign a class called ‘current’ to each of those.

    /* grab all the elements we need */
    var nav = document.querySelector( '#nav' ),
        content = document.querySelector( '#content' ),
     
    /* grab the first article and the first link */
        article = document.querySelector( '#content article' ),
        link = document.querySelector( '#nav a' );
     
    /* hide everything by applying a class called 'js' to the body */
    document.body.classList.add( 'js' );
     
    /* show the current article and link */
    article.classList.add( 'current' );
    link.classList.add( 'current' );

    Together with a simple CSS, this hides them all off screen:

    /* change content to be a content panel */
    .js #content {
      position: relative;
      overflow: hidden;
      min-height: 300px;
    }
     
    /* push all the articles up */
    .js #content article {
      position: absolute;
      top: -700px;
      left: 250px;
    }
    /* hide 'back to top' links */
    .js article footer {
      position: absolute;
      left: -20000px;
    }

    In this case we move the articles up. We also hide the “back to top” links as they are redundant when we hide and show the articles. To show and hide the articles all we need to do is assign a class called “current” to the one we want to show that overrides the original styling. In this case we move the article down again.

    /* keep the current article visible */
    .js #content article.current {
      top: 0;
    }

    In order to achieve that all we need to do is a simple event delegation on the navigation:

    /* event delegation for the navigation */
    nav.addEventListener( 'click', function( ev ) {
      var t = ev.target;
      if ( t.tagName === 'A' ) {
        /* remove old styles */
        link.classList.remove( 'current' );
        article.classList.remove( 'current' );
        /* get the new active link and article */
        link = t;
        article = document.querySelector( link.getAttribute( 'href' ) );
        /* show them by assigning the current class */
        link.classList.add( 'current' );
        article.classList.add( 'current' );
      }
    }, false);

    The simplicity here lies in the fact that the links already point to the elements with this IDs on them. So all we need to do is to read the href attribute of the link that was clicked.

    See the final result in this fiddle or embedded below.

    JSFiddle demo.

    Keeping the visuals in the CSS

    Mixed with CSS transitions or animations (support here), this can be made much smoother in a very simple way:

    .js #content article {
      position: absolute;
      top: -300px;
      left: 250px;
      -moz-transition: 1s;
      -webkit-transition: 1s;
      -ms-transition: 1s;
      -o-transition: 1s;
      transition: 1s;
    }

    The transition now simply goes smoothly in one second from the state without the ‘current’ class to the one with it. In our case, moving the article down. You can add more properties by editing the CSS – no need for more JavaScript. See the result in this fiddle or embedded below:

    JSFiddle demo.

    As we also toggle the current class on the link we can do more. It is simple to add visual extras like a “you are here” state by using CSS generated content with the :after selector (support here). That way you can add visual nice-to-haves without needing the generate HTML in JavaScript or resort to images.

    .js #nav a:hover:after, .js #nav a:focus:after, .js #nav a.current:after {
      content: '➭';
      position: absolute;
      right: 5px;
    }

    See the final result in this fiddle or embedded below:

    JSFiddle demo.

    The benefit of this technique is that we keep all the look and feel in CSS and make it much easier to maintain. And by using CSS transitions and animations you also leverage hardware acceleration.

    Give them a go, please?

    All of these things work across browsers we use these days and using polyfills can be made to work in old browsers, too. However, not everything is needed to be applied to old browsers. As web developers we should look ahead and not cater for outdated technology. If the things I showed above fall back to server-side solutions or page reloads in IE6, nobody is going to be the wiser. Let’s build escalator solutions – smooth when the tech works but still available as stairs when it doesn’t.

    Translations

  9. 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…