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
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.
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).
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.
Note the use of
require statements in the code above. The
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
stateModifier, defined as
Transform.translate(150, 100, 0), applied before it is added to
mainContext and displayed.
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.
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:
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 Tree||DOM|
|Nodes||Renderables and modifiers||HTML elements|
|Encapsulation||Views and widgets||Shadow DOM|
|Meaning||Structure||Structure and rendering|
|Render cycle||Retain mode||Immediate mode|
<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
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
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.
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
dampingRatio of the spring transform, the bouncing speed and decay curve change. You can adjust the numbers and immediately see the new animation behavior.
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
trigger method. Downstream handlers can listen for the event with the
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.
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.
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.
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.
Microsoft buried a Get Windows 10 ad generator inside this month's Internet Explorer security patch for...
Hot or not? From the Web to the motherboard to the training ground, get the scoop on what's in and...
Microsoft’s 'Fall Update' promised to put the finishing touches on Windows 10 -- it doesn’t
Stop procrastinating and make the switch from SHA-1 to SHA-2. You may already be getting errors -- and...
What is blindingly obvious to many is still something new to many others, reflecting the reality of how...
Cloud migrations often expose a decades-old architectural decision that can require expensive rework ...
Memcached is sometimes more efficient, but Redis is almost always the better choice