Badass JavaScript

A showcase of awesome JavaScript that pushes the boundaries of what's possible on the web, by @devongovett.

An Iron Man Like 3d Hologram Controlled by Leap Motion and Three.js

March 7th 2013

The Leap Motion is a very cool piece of technology.  It’s a small $80 box that you can put on your desk to control an ordinary computer using hand motions.  It’s extremely accurate, allowing for very fine motor control using all of your fingers.  If you haven’t seen it, be sure to check it out.  I’m definitely getting in line for one to play with myself.

Robbie Tilton has put together an amazing video demo showing a Leap Motion controlling a Three.js rendered 3d hologram of the earth.  It is projected on a 4-sided prism, and while it’s not quite as good as what Tony Stark has in Iron Man, it’s still pretty darn cool.  And it’s controlled by JavaScript!  Check out the video, embedded below.

As you can see, the four sides of the earth image are projected onto a table and then onto the four sided prism, giving the hologram-like effect.  Thanks to tools like Three.js and WebGL, this can all be done quite simply using JavaScript.  Now imagine your web apps projected onto a hologram and controlled using Leap Motion.  Will you build the next JARVIS? 😃

I have no doubt that there will be many more amazing demos like this as developers get their hands on the Leap Motion, which is slated to ship in May of this year for $80.  If you have a great idea, you may even be able to get early developer access by signing up on their site.

Rawson.js: A JavaScript Camera RAW File Viewer Ported with Emscripten

March 5th 2013

Rawson.js, by Franz Buchinger, is a JavaScript renderer for RAW image files in the browser.  It uses an Emscripten port of the dcraw C library to JavaScript to render in a canvas element.  Rawson.js can also extract metadata from RAW images, as you can see in the demo.

image

Thanks to the dcraw C library, Rawson.js enables viewing of RAW images from over 500 different cameras and many file types.  The thing about RAW files is that each manufacturer has their own file format, and libraries and viewers must be updated when new cameras are released.  This is why you will sometimes see operating system updates and other program updates for RAW image support ever now and again.

Rawson.js is currently a bit slow, especially for large images.  The image shown in the screenshot above is almost 30MB and it took about 30 seconds to render on my system.  I have found it to be a lot faster in Firefox Nightly thanks to asm.js I think, so try it there if you can.  It sounds like they are perhaps working on a smarter renderer for the next version of Rawson, that doesn’t have to render the whole image at 100% quality before displaying anything.  My suggestion is to only render the visible parts, perhaps in parallel using Web Workers (which they should use in any case) in tiles if possible.  They’ve also mentioned using the embedded JPEG previews in many RAW files to speed up initial rendering while the real thing is processed.

Once it is sped up a bit using some smarter rendering techniques, I think Rawson will be very important for browser based photo editing applications, since many professionals only work with RAW files for their quality.  You can check out the source on Github, the project page, and the demo.

Parallel.js: A JavaScript Multicore Processing Library Using Web Workers

February 26th 2013

Parallel.js is a very nice looking wrapper around JavaScript Web Workers making some interesting applications of multicore/parallelized processing in JavaScript much easier.  Usually with Web Workers, you must write a totally separate script and load it into the worker thread.  This isn’t very convenient in some cases, especially when you need to share code between the main and worker threads.  Parallel.js solves that problem and provides a nice API abstraction to perform common tasks.

Parallel.js allows you to spawn a worker containing one or more functions, defined in your parent thread rather than as a separate file.  You just pass the function names and some arguments to call the function with, and Parallel.js will spawn a worker thread, run the function with the passed arguments, and send the result back to the main thread asynchronously using a Promise based API.

There is also a MapReduce API for processing large datasets that will split the data into chunks to be processed in parallel by an arbitrary number of worker threads.  When all of the processing is complete, the result is merged back together and returned to the main thread.

As web applications do more of their processing on the client side, we will need to take advantage of the multicore machines that modern systems have in order to maintain a good user experience.  As a rule of thumb, we never want to do a lot of processing on the main UI thread since the user will notice the lag.  Web Workers are great, but in general quite difficult to use.  I’m glad to see libraries beginning to make things easier in this department.

As always, you can check out Parallel.js on Github and its website.

Holla: A Sugary API Abstraction for WebRTC Voice and Video Calling in the Browser

February 19th 2013

I posted about PeerJS recently, which is a nice API on top of WebRTC for peer-to-peer networking of arbitrary data.  However, one of the main selling points for WebRTC is its voice and video calling support.  Holla is a JavaScript library that aims to make working with WebRTC’s voice and video calling APIs much easier.  WebRTCs APIs are pretty low level and not something everyone wants to deal with directly, so a nice API abstraction is very much welcome.

Like PeerJS, Holla has both a client and a Node.js server component.  The server helps broker the peer-to-peer calls between clients with usernames.  Once usernames are registered, the clients can make voice or video call requests as well as send chat messages to other client usernames.  On the other end, the second client can either answer or decline the call, and then send the video stream to a <video> element to be displayed.  The API looks really simple to use, and thanks to WebRTC will make pretty much anyone able to build their own Skype in a couple minutes.

The demo allows you to declare your username and then call and chat with other usernames, and shows the power of the API to do a lot with a very small amount of code.  It’s a simple demo, and it only works in Chrome and Firefox Aurora so far, I think, but I’m looking forward to future widespread adoption of WebRTC.  You can see the code for the demo on Github to get a feel for the niceness of the API, and then look at the rest of the code for the client and server to see what it’s doing for you.

WebRTC is the way of the future and it’s good to see adoption and 3rd party library abstractions already being created.  As always, you can find the code for the library and its demo on Github.

asm.js: A Low Level, Highly Optimizable Subset of JavaScript for Compilers

February 18th 2013

David Herman, Luke Wagner, and Alon Zakai (also the developer of Emscripten) of Mozilla have been working on the asm.js spec, which aims to be a subset of the JavaScript language that can be highly optimized after you have opted in.  It is designed mostly for compilers like Emscripten to target, but the best part is that it’s backwards compatible with the existing JS syntax since it is a strict subset.  This means that asm.js code will still run on older browsers, although not in the optimized path taken in enhanced JS engines.

You opt-in to using asm.js by including the "use asm"; string at the top of your file or individual function, just like you opt into strict mode with "use strict";.  Once you’ve done that, the ahead-of-time (AOT) optimizing compiler will kick in in supported engines, looking for type annotations and validating the code to make sure it really is optimizable.  The type annotations are interesting, and not similar at all to other attempts like Microsoft’s TypeScript since they must be backwardly compatible with normal JavaScript.  Instead, asm.js uses existing JavaScript operators as type hints, for example +a would annotate the a variable as a double.  a|0 would annotate it as an integer.

Once the engine has determined that the code is valid asm.js, it can compile it ahead of time and not have to worry about deoptimizing later on, runtime type checking, garbage collection, and bailouts.  There is no garbage collector since memory manually managed in a large HEAP typed array, using malloc and free like functions.  All of this obviously makes programs much faster since there is simply less work for the JavaScript engine to do while running your program since it has done it all ahead of time.  This will allow JavaScript programs to get closer to native code speed, and for certain classes of applications in the browser, this will be important for the platform.

If all of this sounds a bit tedious to write, I would agree, although it’s far from the worst syntax we could have.  However, it isn’t really targeted at human authors, but compilers like EmscriptenMandreelLLJS, or perhaps even TypeScript which can generate the cleverly backwards compatible but not terribly clear type annotations for you from another existing language like C, or a new language like LLJS or TypeScript.  Emscripten already generates valid asm.js output and was one of the main impetuses behind the the project, and Firefox will be landing their asm.js optimizing compiler in the near future.  The benchmarks look very impressive indeed.

These are exciting times for JavaScript application performance, and asm.js can only help.  It definitely seems like Mozilla’s response to Google’s Native Client (NaCl) project, which actually runs compiled code on the web in a sandboxed environment.  Since asm.js is actually a subset of JavaScript that is backwardly compatible, I see it as a much more likely winner in the highly optimized code space on the web.  NaCl is not available anywhere right now, but asm.js is already available everywhere even though no engines have implemented official support.

Be sure to check out the asm.js spec, David Herman’s prototype asm.js validator on Github (written in JS!), and Emscripten developer Alon Zakai’s presentation about Emscripten, asm.js and the future.  I’m looking forward to watching all of these projects as they develop!