Jumping JavaScript! Hands-on with the Famo.us framework

Take a guided tour of the fast and flashy JavaScript framework that promises to reinvent the Web

Famo.us is an open source JavaScript framework for building high-performance mobile Web and hybrid mobile apps. The framework gets its speed and sizzle by replacing the browser's slow, DOM-based rendering mechanism with its own rendering engine and by tapping the GPU acceleration provided by CSS3's 3D transformation functions -- no plug-ins or native code required.

In the lore of Famo.us, the origin of the framework was the original team's struggle with HTML5, CSS3, and the DOM (Document Object Model). According to architect Dave Valdman, writing on the Famo.us site, "We wondered if we could move a square <div> at 60 FPS entirely in JavaScript without relying on CSS3 keyframe animations... then we built a framework around it." Valdman now adds one comment to that for context: "Animation is our humble roots, but our library has matured into much more."

To introduce you to the way Famo.us works, I've captured and explained a series of screens from the Famo.us tutorials, demos, and samples. When the company can clear up its backlog of beta applicants (more than 80,000 at the time of my visit) and fix the issues that inevitably surface after a developer product launch, you'll be able to try the framework yourself.

Hello, Famo.us
In Figure 1 below, you see the "Hello Famo.us" introductory lesson from Famo.us University, an online set of courses to help you learn the Famo.us framework. Famo.us University runs in a browser, preferably Chrome, and it includes a live mini editor (middle), instructions (left), and a live preview (right).

Figure 1: Hello Famo.us
Figure 1 (click image to enlarge)

The "Hello Famo.us" lesson creates a device emulator (shown here as an iPhone), then adds a background surface in color #FA5C4F, three slide images, and onClick logic to the slide surface to create a simple slideshow app. The most impressive part of the demo is that the preview updates instantly as you change the code online.

Note the settings near the top of the code. Transition animations can follow standard or custom easing curves or physical simulations between endpoints, vary opacity, and change the translation, rotation, origin, and size of surfaces.

Displaying content
The first actual lesson in Famo.us 101 covers how to display and style content in Famo.us using JavaScript, HTML, and CSS. You'll notice that styling surfaces in Famo.us is just like writing CSS, except that the properties are written using camelCase instead of dashes. That's because the standard CSS property names with dashes are not valid JavaScript -- the dash is interpreted as a minus sign or subtraction operator. Ultimately, these styles become their equivalent CSS properties.

Figure 2: Famo.us sizing
Figure 2 (click image to enlarge)

Note the use of require statements in the code above. The require statement is not standard JavaScript, but comes from the RequireJS framework, a JavaScript file and module loader. Famo.us expects to eventually eliminate the use of RequireJS for its own framework.

The second lesson in Famo.us 101 starts by covering translations and state modifiers. In this example the createSurface function defines the 100-by-100-pixel square in the upper left with the text "surface," and the createModifiedSurface function creates the other square with the text "modified surface" and translates it 150 pixels to the right and 100 pixels down.

Note that the translation parameters include values for the x, y, and z axes. Also note that chained modifiers apply from right to left: mainContext.add(stateModifier).add(modifiedSurface) means that modifiedSurface has stateModifier, defined as  Transform.translate(150, 100, 0), applied before it is added to mainContext and displayed.

Figure 3: Famo.us transforms
Figure 3 (click image to enlarge)

Famo.us uses matrix3d WebKit transforms on <div> elements with absolute positions rather than using a conventional nested DOM tree in which child elements are positioned relative to their parent elements. Famo.us gains performance by using the hardware-accelerated matrix3d WebKit transforms and avoiding the relatively slow layout flow calculations of a typical HTML5 page.

Overall, the way Famo.us does transforms and rendering feels a lot more like the way console games do their graphics than the way Web browsers normally work.

Lesson 2 goes on to explain chaining modifiers and applying rotations. As you probably remember from your high school analytic geometry, a translation followed by a rotation will give you different results than a rotation followed by a translation.

Figure 4: Famo.us chaining
Figure 4 (click image to enlarge)

As discussed earlier, chaining is applied right to left, so mainContext.add(translateMod).add(rotateMod).add(surface) adds the surface to the main context, rotates it Pi/4 radians (45 degrees), and translates it down 100 pixels and to the right 100 pixels.

Reversing the order -- mainContext.add(rotateMod).add(translateMod).add(surface), for example -- would give us a rectangle cut off at the left:

Figure 5: Famo.us translate and rotate
Figure 5 (click image to enlarge)

Famo.us Render Tree
As we discussed earlier, Famo.us uses matrix3d WebKit transforms on <div> elements with absolute positions rather than using a conventional nested DOM tree in which child elements are positioned relative to their parent elements. The table in Figure 6 compares the elements of the Famo.us Render Tree with the standard DOM.

Figure 6: Famo.us vs. the Document Object Model

 Famo.us Render TreeDOM
Tree structure Yes Yes
Nodes Renderables and modifiers HTML elements
Reflows No Yes
Encapsulation Views and widgets Shadow DOM
Meaning Structure Structure and rendering
Render cycle Retain mode Immediate mode
Language JavaScript HTML

Famo.us keeps the structure of HTML in the JavaScript Render Tree and renders to absolutely positioned <div> elements, creating a flat HTML DOM that doesn't require any flow calculations for a redraw. The HTML <body> tag corresponds to a Famo.us Context, more or less. The Context corresponds to an isolated drawing universe. You need at least one Context, but you could have many in the same <body>.

The Render Tree has two types of nodes: renderables, such as a Surface, and modifiers, which are responsible for the layout and visibility of the Render Tree below them. Modifiers can be chained, as I mentioned earlier.

In Famo.us, views are encapsulations of groups of renderables and modifiers that you wish to hide from the master Render Tree. Views are typically what a Unix UI developer would call a widget, but implemented as a Famo.us RenderNode paired with an input EventHandler and an output EventHandler. The views in the Famous Example repository as of this writing are Deck, EdgeSwapper, GridLayout, HeaderFooterLayout, RenderController, Scrollview, and SequentialLayout. The expectation is that you'll subclass views to extend and customize them into your own widgets, or write your own renderable items from more basic components.

The red square in Figure 7 started in the upper-left corner with no text content, slid down the left side over the course of a second, then slid down and to the right and wiggled over the course of 800 milliseconds, and finally showed the text content "finished." This demonstrates the chaining of two easing transforms. There are more than 30 easing curves predefined in the Famo.us library. Easing transitions take a fixed and configurable amount of time.

Figure 7: Famo.us animation
Figure 7 (click image to enlarge)

Physics transitions
Famo.us has a physics engine that can do a lot of game-like simulation, the least of which is to make animations bounce in a realistic-feeling way by using a spring model to guide the transitions. In this lesson, the red square drops from the top, overshoots the final position, and bounces three times in the span of about two seconds. If you adjust the period and dampingRatio of the spring transform, the bouncing speed and decay curve change. You can adjust the numbers and immediately see the new animation behavior.

Figure 8: Famo.us physics
Figure 8 (click image to enlarge)

Famo.us has plans to surface visual controls for animations as part of the platform in the future, so designers can achieve the behavior they want without involving a software engineer in tweaking the simulation parameters. I have seen an unreleased prototype of one example of this running on an iPhone.

Famo.us has an EventHandler API that allows a user to broadcast, listen for, pipe to, and subscribe from events. Event handlers can broadcast with the emit or trigger method. Downstream handlers can listen for the event with the on method.

Event handlers can pipe events to downstream event handlers, and subscribe to events from upstream event handlers. Pipes can be chained. In general, the best practice is to use a subscription pattern, especially when listening on DOM events. Note that this explicit piping stands in contrast to the implicit event bubbling in the HTML DOM.

The Famo.us View base class, and therefore every derived view and widget, includes both input and output event handlers. The event library comes with convenience modules for conditionally processing events, including event filtering, mapping, and arbitration.

Famo.us does all positioning using transforms, which are basically four-by-four matrices applied to surfaces with absolute positions. As I mentioned earlier, transforms can perform translation and rotation. In addition, they can scale a surface, size it, and set its origin. The matrix multiplications that apply transforms to surfaces are straightforward, which is how the game-like Famo.us engine can render faster than a Web browser would calculate and display all the flow required for deeply nested HTML documents.

Famo.us Toolbelt
When you are admitted to Famo.us University, you can download any of the Famo.us demo and tutorial projects. In order to work with the supplied projects on your own machine and to create new projects, you'll want to install the Famo.us Toolbelt. This is basically a set of Yeoman generator and Grunt scripts to create projects and views, run a local development Web server, and package your project for distribution. You'll need Git, Node.js, Grunt, and Bower. On a Mac, you can install Node.js using Homebrew, and you can install Grunt and Bower from the Node package manager Npm.

As of this writing, 15 demos are available from the Famo.us site. In all cases, you can play with the demo online and download the project zip file.

Figure 9, at left below, shows a screen from the Ultravisual demo, an example of a scrolling parallax effect. By swiping or scrolling up and down, you can navigate through the various sections. Figure 10, at right below, shows a screen from the PHQ4 demo, which shows a parallax effect. Clicking anywhere on the screen will open or close this cover. When you open it, the red menu squares snap into place while the photos continue to move from right to left until they become centered.

Figure 9: Famo.us Ultravisual demoFigure 10: Famo.us PHQ4 demo
Figure 9 (click image to enlarge) Figure 10 (click image to enlarge)

Hello, Famo.us?
Famo.us is currently being beta tested by some 5,000 developers, with rollout to 500 new beta testers each day. The company expects the beta to be fully open by May 19. Meanwhile, the Famo.us Docs (basically formatted comments from the framework) and Guides (actual tutorial material) are available to all. The installation instructions, Demos, and Famo.us University lessons, however, require a login password.  

Famo.us promises significantly better performance than standard mobile websites, it's more flexible for UI development than HTML5, and it's easier for developers to use than native code. But as I hope you've seen from this walk-through, the framework currently looks and feels more like an animation or game system than a conventional Web toolkit.

The company plans to make the product much easier to learn and use in the future -- even for designers who don't know JavaScript. But if you want to "be Famo.us" right now, you would be well served by serious JavaScript experience or a game development background.

This article, "Jumping JavaScript! Hands-on with the Famo.us framework," was originally published at InfoWorld.com. Follow the latest developments in JavaScript and application development at InfoWorld.com. For the latest business technology news, follow InfoWorld.com on Twitter.

Copyright © 2014 IDG Communications, Inc.

How to choose a low-code development platform