Famo.us UI framework: Elements

Famo.us: near native experiences on mobile, 60FPS, works across all screen sizes, browsers, operating systems, and is entirely in Javascript. Everyone wants the advantages of Famo.us, but nobody wants to learn it. And for good reason, it’s a burgeoning framework, it has a steep learning curve (what in the world are surfaces and modifiers), and is still pretty buggy.

Over the past month, I’ve been working with 3 other software engineers from Hack Reactor. And with the help from the VP of product at Famo.us, we have designed a framework on top of Famo.us that provides a low level abstraction layer to lower the barrier to entry for developers.

Famo.us UI

We call it Famo.us UI. There are no more surfaces and modifiers. There are no more syncs for each input (scroll, touch, mouse). And there is less code to write, a LOT of less code to write. In this post, I’ll discuss the high level overview of what Famo.us UI is, specifically the role of elements. There won’t be much code in this post.

Elements

Elements are the best of surfaces and modifiers put together. You interact with them like surfaces but they behave like modifiers. In the standard Famo.us, creating something as simple as creating and centering a button on the screen went something like this.

Standard Famo.us

  • Create a button surface
  • Set the size, content, and CSS properties on the button surface
  • Create a button modifier
  • Set the align and origin on the modifier to [0.5, 0.5]
  • Add the button modifier to the main context
  • Add the button surface to the main context

Famo.us UI

  • Create a button element
  • Set the size, content, CSS properties, align, and origin on the element
  • Add the button element to the main context

Problems Solved

We have reduced the number of required steps in half and the mental load of working with Famo.us UI is much lower. We have reduced the code by about 40-60% and have completely abstracted away surfaces and modifiers into something much more intuitive – elements.

Some of you might have seen us at the last Famo.us meetup where we had a demo booth alongside Adobe, Intel, Facebook and Angular. Famo.us UI is currently in the private Famo.us Gitlabs. More to come later, with code samples as well.

How to Run Javascript Code in Sublime Text

Had many Hack Reactor students ask how I was running our daily toy problems straight from Sublime.

Disclaimer: This is not an interpreter and only allows you to see console.log() output. Alert() will not work. Besides that, it’s a quick way to test code. For those wanting an entire interpreter, try out SublimeREPL

Here’s how you can create a Javascript Sublime console:

  1. Open Sublime
  2. Go to ‘Tools’ on the tab bar
  3. Hover over ‘Build System’
  4. Click on ‘New Build System’

At this point, Sublime should have opened up a new tab for you, that looks like this:

Screen Shot 2014-06-17 at 9.57.29 AM

Delete the default text and paste this in:

{
"cmd": ["node", "$file"],
"selector": "source.js"
}

Save it as node.

Now the next time you want to code in JS, go to Tools > Build System > Javascript.

To run your code, simply Command-B.

EDIT: If the above does not work, try this instead:


{
"cmd": ["/usr/local/bin/node", "$file", "$file_base_name"],
"working_dir": "${project_path:${folder}}",
"selector": "*.js"
}

N-Queens Implementation in Javascript

Week 2, Day 4 of Hack Reactor:

Having already passed the data structures sprint where we implemented 4 different instantiation patterns in JavaScript. Our next two-day sprint focused on algorithms and working on an implementation of the classic N-Queens problem.

The problem is simple: How many ways are there to arrange n queens on an n by n chessboard such that no queens are in a direct line of attack.

Our first implementation was very, very slow, taking ~15 minutes for N=8.

How we stored the chessboard: 2D-array


[ [0,1,0],

  [1,0,0],

  [0,0,1] ]

Having (barely) passed the core requirements, we then set our eyes on the extra-credit section. There was a lot of room for improvement in the time complexity. Since the nature of the problem requires a brute-force technique along with a collision detect on every queen being placed. I discovered that the large majority of our code’s time was being spent checking for collisions. Since our algorithm spent most of its time checking collisions, that was the first place to improve. At a glance, our implementation of collision detection had a time complexity of O(n^2) on each row for a total time complexity of O(n^3)…(after n^2, it pretty much goes downhill from there).

My initial thought for improving efficiency was a different way of representing the chessboard that was more efficient than the 2D-array we were currently using.

From a 2D-array to a 1D-array:


[1, 0, 2]

Since we know that every solution will have a queen in every row, we don’t care about the spaces where there aren’t queens. We only care about the locations of each queen in the row. With this implementation, each index of the array represents the row, and the value represents the location of the queen in that row.

For example, row 0 has a queen in position 1, row 1 has a queen in position 0, and row 2 has a queen in position 2. By using this representation, the time complexity for checking collisions is O(N) since we are only traversing one array.

But  how we can do better? I’ll give you a hint: hash tables.

From a 2D-array to an object:


{0: 1, 1: 0, 2: 2}

Using the same logic as rows, the keys represent the rows and the values represent the location of the queen in that row. However, since objects are implemented as hash tables in javascript, we can take advantage of the constant time lookup, O(1).

We had less than a day at this point to refactor our original N-Queens implementation. We felt the other two implementations, although more efficient, would not give us much of a challenge. We instead went with a bitwise implementation because who doesn’t love a good bitwise from time to time.

Following this very old code, here is our bitwise javascript implementation of N-Queens:


var countNQueens = function(n){
  var all = Math.pow(2,n) - 1;
  var solutionCount = 0;

  var findSolutions = function(cols,ld,rd){

    var pos = ~(cols | ld | rd) & all;

    while(pos>0){
      var bit = -pos & pos;
      pos = pos ^ bit;

      findSolutions((cols | bit), (ld | bit) << 1, (rd | bit) >> 1);

    }
    if (cols === all) {
      solutionCount++;
    }
  };
  findSolutions(0, 0, 0);
  console.log(solutionCount);
  return solutionCount;
};