visualization. code. markets.

how to become Famo.us...

in 99 days – or so…

Enter

viz-cod.de started in July 2014.

The first series of articles focuses on my journey to famo.us.

And just my two cents


Posts about everything

Read the newest

Posts about Famo.us

Read from start

Posts about everything else

Read just my 2¢

23.05.2015

Famo.us 0.5.0 MixedMode out (Developer Preview)

The long awaited Famous Mixed Mode Developer Preview (version 0.5.0) is out now (released on May 21st).

Download it at http://famous.org/ or use my codepen-template for playing around…

  • MixedMode support: DOM and GL in the same coordinate space
  • New physics engine
  • Famous CDN / cloud support: Deploy your Famous app to the CDN and embed it easily as a container in your website / project
  • New website with updated documentation and tutorials

For a first impression check out their (quite trashy…) release video:

 

Video content:

0:00:00 Intro by Steve Newcomb, Announcements about license, Best framework
0:19:30 Get started with Famous Engine: How to install
0:26:10 Structure of a seed project
0:27:50 Structure of the seed index.js: Famous engine, scene, nodes
0:34:10 Sizing, Aligning
0:37:20 Now you can see code… 😉
0:40:45 onUpdate method for animation/rotation
0:42:50 Adding WebGL / Mesh
0:50:10 Deploy to famous CDN: Containers and embedding it in existing websites
0:56:50 Browser support, documentation overviews
– PAUSE –
Repeat again…
1:24:30 famous.org Website: Overview
1:26:10 How to install
1:30:10 Structure of a seed project
1:32:00 Structure of the seed index.js: Famous engine, scene, nodes
1:39:00 Adding and styling a DIV / DOMEelement
1:40:00 Sizing, Aligning
1:48:00 Adding WebGL / Mesh
1:52:20 Deploy to famous CDN: Containers and embedding it in existing websites

 

More infos:

08.05.2015

Why Windows 10 uses hamburger menus for Windows Phone/Mobile

There is some debate on the reincarnation of the „hamburger menu“ for the upcoming version of Windows 10 Phone/Mobile:

Windows Phone 8 does not use the hamburger navigation so far. Its original interaction model puts actions at the bottom and navigation on the sides (swipe / pivot).

 

This is still a convincing navigation concept, because one handed navigation is much more comfortable with action buttons placed at the bottom, especially for bigger phones (phablets).

So why will this be changed in Windows 10?

According to a former MS employee there are two main reasons:

  1. People do not use phones one-handed as much as we think. People use phones quite often with both hands, eg. while typing on the on-screen-keyboard.
  2. People get used to the „hamburger navigation“ and its placement at the top of the screen across all devices, including desktop (where more and more hamburger navigations appear these days)

The question is: Why not put both concepts together and use a hamburger menu at the bottom of the screen? People will recognize it immediately and can use it much more comfortable: Even when using the phone with both hands the navigation at the bottom is much more accessible.

 

07.05.2015

Notes on Gunter Dueck: Stupidity of the crowd (re:publica 2015)

re:publica 2015 – Gunter Dueck: Schwarmdummheit!

 

Notizen:

  • Über die Entstehung von Dummheit in Meetings…
  • Wenn mehrere intelligente Menschen zusammenkommen, wird’s nicht unbedingt intelligenter
  • Scharmintelligenz funktioniert in Unternehmen nicht zwingend, da die meisten Mitarbeiter nicht frei über Team-/Hierarchiezuordnungen entscheiden können
  • Von Klugen, Helfern und Banditen: Wer hilft wem?
  • Dummheit ist der Akt anderen zu schaden, ohne sich selbst zu nützen (Die Prinzipien der Dummheit, von C. Cipolla)
  • Utopiensyndrome: Unerfüllbare Ziele als Ursache von Dummheit
  • Wenn intelligente Leute vergessen, dass das, was sie wollen, nicht geht.
  • Dummheit beginnt mit der Annahme: Maxiumum = Optimum
  • BWLer glauben: Mitarbeiter, die 10% rumsitzen, sind faul
  • Aber jetzt kommt Mathe: Anzahl Leute im System = Nutzungsgrad / (1-Nutzungsgrad)
  • Von Warteschlangen vor Kassen und Notaufnahmen
  • Was tun? Nach dem Optimum ausrichten: Die magische Auslastung heisst 85%, dann ist die Warteschlange im Schnitt 4-5
  • Aber: “Das traut sich hier keiner”
  • Unsichtbar ist die Dummheit, wenn sie genügend grosse Ausmasse angenommen hat (Brecht)
  • Innovation, Beschäftigung mit der Zukunft zerschellt an der Schwarmdummheit, an der Überlastung durch die zu lange Warteschlange
  • Noch ein Beispiel für Dummheit: Correlation für Kausalität halten

Notes:

  • On the Origin of stupidity in meetings
  • If more than one smart people come together, it is not necessarily more intelligent
  • The crowd’s intelligence does not work in companies, as most employees can not decide freely team / hierarchy assignments
  • About smart ones, helpers and bandits: Who helps whom?
  • Stupidity is harming someone else without profiting for yourself (The principles of stupidity, by C. Cipolla)
  • Utopia Syndrome: Unrealistic goals as the cause of stupidity
  • When intelligent people forget that their goal is impossible.
  • Stupidity begins with the assumption: Maximum equals optimum
  • Managers believe those people who sit around for 10% of their time are lazy
  • But here’s the math: Number of people in the system = utilization / (1-utilization)
  • Queues in front of checkouts and emergency rooms
  • What to do? Reach for the optimum: The magical utilization is 85%. Then the queue is on average 4-5
  • But: „Nobody dares!“
  • Another example of stupidity: Mix up correlation and causality

06.05.2015

Clef: Secure 2-Factor Authentification with your smartphone

Clef is a cool Wordpress plugin which helps you to login to your site via smartphone:

  • Easy to use – just open your smartphone (iPhone, Android) and point to your webbrowser (a little bit like scanning a QR code)
  • Secure 2 Factor Authentification
  • No more password reminders
  • Last but not least: It looks really cool:

 

https://getclef.com/

01.05.2015

Wallaby.js: Turbo unit testing

Wow – this is really fast testing in your IDE: At least 10 times faster than manual karma tests in Angular projects, in bigger projects even (drastically) more.

Wallaby.js is an intelligent test runner for JavaScript that continuously runs your tests. It reports code coverage and other results directly to your code editor immediately as you change your code.

Wallaby.js uses various tricks to run your tests as fast as possible, such as dependency analysis to only execute tests affected by your code changes and parallel test execution.

Highlights:

  • Runs in your IDE (IntelliJ, Webstorm…)
  • Zero Config (nearly…): No fiddling with karma, phantom.js configs…
  • Supports ES5, ES 6, TypeScript, CoffeeScript

 

30.03.2015

A little Cheatsheet for positioning, animating and some styling with Famo.us/Angular

I just set up a small collection of design patterns, surfaces, modifiers and animations.

Just as a quick helper for the daily work:

  • Centering horizontally and vertically inside surfaces
  • Rotating around center (while positioning with origin 0/0)
  • Nesting surfaces and modifiers (again: centering with the help of size-modifiers)
  • Positioning with pull and push (static values vs. functions which are updated on every tick)
  • Usage of plain vanilla Famo.us javascript inside of Famo.us/Angular

 

cheatsheet

http://codepen.io/aknip/pen/zxbJpW

 

 

17.03.2015

Quick reminder: How to build your own directives using „Vanilla Famo.us“ or „Famo.us Angular“

Directives are a great way to build reusable components in your applications. If you want to build your own Famo.us based directives here are two recipes:

 

1. Directive using „Vanilla Famo.us“

angular.module('widget')
     .directive('yourDirectiveName', function ($famous, $famousDecorator) {
       return {
          template: '<div></div>',
          transclude: true,
          scope: true,
          restrict: 'EA',
          compile: function(tElement, tAttrs, transclude){
          var View = $famous['famous/core/View'];
          var Surface = $famous['famous/core/Surface'];
 
          return {
             pre: function(scope, element, attrs){
             // pre: executed before child elements are linked
             // NOT safe to do DOM transformations here
             // start Famo.us vanilla code here...
             // 'view' will be attached to the directive
             var view = new View({
                // read attribute fa-size !
                size: scope.$eval(attrs.faSize) || [undefined, undefined]
              });
             var surface = new Surface({
                   content: 'hello world',
                   size: [100, 100],
                   properties: {
                       backgroundColor: 'red'
                   }
               });
              view.add(surface);
              // end of Famo.us vanilla code
              // $famousDecorator:
              // http://famo.us/integrations/angular/docs/unstable/api/service/$famousDecorator/index.html
              //
              // .ensureIsolate() checks the passed in scope for an existing isolate property.
              // If scope.isolate does not already exist, create it.
              var isolate = $famousDecorator.ensureIsolate(scope);
              isolate.children = [];
              isolate.renderNode = view;
              $famousDecorator.addRole('renderable',isolate);
              isolate.show();
              // Attach a listener for registerChild events.
              $famousDecorator.sequenceWith(scope, function(data) {
                   isolate.renderNode.add(data.renderGate);
                   isolate.children.push(data);
              });
           },
        post: function(scope, element, attrs){
           // post: executed after the child elements are linked
           // IS safe to do DOM transformations here
           var isolate = $famousDecorator.ensureIsolate(scope);
           transclude(scope, function(clone) {
              element.find('div').append(clone);
           });
           // Register a child isolate's renderNode to the nearest parent that can sequence it,
           // and set up an event listener to remove it when the associated element is destroyed by Angular.
           $famousDecorator.registerChild(scope, element, isolate);
         }
       };
     }
   };
 });

 

2. Directive using „Famo.us / Angular“

angular.module('widget')
    .directive('yourDirectiveName', ["$famous", "$famousDecorator", function ($famous, $famousDecorator) {
       return {
          template: '\
                    <fa-surface fa-size="[200,200]" fa-background-color="\'#ddd\'">\
                      {{myTest}} Attribute:{{myattr}}\
                    </fa-surface>',
          // template may be defined inline via "template: ..." (see above) or in external file via "templateUrl: ..."
          // templateUrl: 'modules/your/path/to/template.html',
          controller: 'yourCtrl',
          // Isolate scope for a full reusable component, otherwise use scope: true
          scope: {},
          restrict: 'EA',
          compile: function(tElement, tAttrs, transclude){
             return {
               pre: function(scope, element, attrs){
               // pre: executed before child elements are linked
               // NOT safe to do DOM transformations here
               // $famousDecorator:
               // http://famo.us/integrations/angular/docs/unstable/api/service/$famousDecorator/index.html
               // .ensureIsolate() checks the passed in scope for an existing isolate property.
               // If scope.isolate does not already exist, create it.
               $famousDecorator.ensureIsolate(scope);
             },
              post: function(scope, element, attrs){
              // post: executed after the child elements are linked
              // IS safe to do DOM transformations here
              // demo: bind directive's attribute "myattr" to the directive's scope
              scope.myattr = attrs.myattr;
             }
           };
         }
      };
 }])
 .controller('yourCtrl', function ($scope, $famous) {

     $scope.myTest = "Hello World!";
});

 

 

 

 

02.03.2015

Integration of Famo.us-Flex into Famo.us/Angular

Famous-flex offers some nice ready-to-use widgets, animatable layouts and a very flexible FlexScrollView.

The famous-flex demo shows how easy it is to switch between different layout styles, eg. GridLayout, ListLayout and CoverLayout:

famous-flex

 

The library is delivered for usage in plain vanialla Famo.us javascript projects – there are no out of the box Angular directives.

But thanks to the <fa-render-node> directive it’s quite simple to integrate it seamlessly into a Famo.us-Angular project.

 

1. Include the famous-flex library: 

<script src="bower_components/famous-flex/dist/famous-flex-global.js"></script>

 

2. In your Angular view insert something like this:

<fa-render-node fa-node="myFamousCode"></fa-render-node>

 

3. And in your Angular controller add something like this:

var StateModifier = $famous["famous/modifiers/StateModifier"];
var ViewSequence = $famous["famous/core/ViewSequence"];
var FlexScrollView = famousflex.FlexScrollView;
$scope.myFamousCode = new View({
  size: [undefined, undefined]
});
var viewSequence = new ViewSequence();
var scrollView = new FlexScrollView({
});
$scope.myFamousCode .add(scrollView);

 

Two things to note here:

  • The FlexScrollView object is provided by the global famousflex. – not by the global $famous[] !
  • The current version of famous-flex 0.2.0 only works with famous-angular 0.5.2 and famous 0.3.5 – see the bower.json file in the demo project below

 

I prepared a little Famo.us/Angular project which shows the FlexScrollView in action – including the „sticky categories“ implementation of the FlexScrollView, which is really nice (and note the flexible heights of the different elements…!):

 

 

You can download this sample project here:
https://github.com/aknip/famous-angular-with-famous-flex

 

Javascript ES6: A template for Angular JS 1.3 including lazy loading (ES6 modules)

This is a very nice and lean template for using ES6 (via Babel) and lazy loading ES6 modules:

https://github.com/Swimlane/angular-systemjs-seed

  • ES6 Syntax via Babel with source map
  • Lazy loading ES6 modules by ui-router: As users click around in your app, the related files for those routes are lazy loaded as needed. This cuts down on initial application load times, boosts performance and often JS-bundling/-minifying is not needed at all!
  • Dynamic CSS-theme switching
  • Karma / Jasmine unit tests with coverage report

 

How to:

  1. npm install -g jspm
  2. npm install
  3. gulp watch serve
  4. Browse to http://localhost:9000

 

20.02.2015

Javascript ES6: The easiest way to start

This video gives you the best ES6 hands-on in 10 minutes and a full automatic build workflow system:

 

The main steps are:

  1. npm install -g jspm
  2. npm install -g live-server
  3. jspm init (answer all setup question with yes / default)
  4. live-server

Now you can code in ES6, all changes are watched and transpiled to ES5 automatically

To build a minified production bundle:

  1. jspm bundle-sfx –minify lib/main

 

EDIT: If you are interested in how to use ES6 with Angular 1.3 including lazy loading via ES6 modules look here!

15.02.2015

Scrollviews performance: Famo.us vs. Famo.us/Angular

When working with larger scrollviews (some hundred items) in Famo.us/Angular I noticed that they feel a little bit slower compared to native Famo.us scrollviews.

To analyze this I wrote a small application (Famo.us/Angular 0.5.0, ui-router) which containins just one scrollview.

The idea was to measure the total time from
– changing of the ui-router-state until
– drawing the last item in the scrollview.

This would be comparable to the real user experience and shows the time from clicking the button until the view is rendered on the screen.

Here are the results:

Famo.us Performance Test

How to read:

  • Each line shows a different application setup, measured for different numbers of list items in the scrollview. The first 5 results are measured on a Desktop Chrome Browser (v39, MacBook Pro), the last 5 results are measured on an Android Chrome Browser (v39, Galaxy Note 3)
  • Line 1: My Benchmark scenario without Famo.us: Just a plain ngRepeat with one DIV. The measured time is the minimal time Angular JS can deliver. Or in other words: The additional time in the other lines are caused by Famo.us/Angular
  • Line 2: The same simple ngRepeat as a data source for a Famo.us/Angular scrollview with one surface per item
  • Line 3: A native Famo.us scrollview embedded via a custom directive into the application (see code below)
  • Line 4: The same as Line 2 plus one transitionable per item
  • Line 5: The same as Line 3 plus one transitionable per item

 

Results:

  • The performance correlates to the number of items in a linear way: A scrollview with 800 items needs twice the time compared to a scrollview with 400 items. This is mainly caused by data handling/looping. The pure render time of the DOM can be neglected.
  • Angular repeats get very slow for several hundred items, and Famo.us/Angular makes it even worse: 400 items need 408ms. And if you add a transitionable per item it gets up to 919 ms !
  • Angular repeats on mobile devices are even more worse: The examples from above need 2 sec / 5 sec – on a fast device! An average Android phone needs roughly double of the time. This is not acceptable from a usability point of view.
  • Native Famo.us is the solution: The examples are executed 20 times (!) faster.

 

Recommendations:

  • Use Famo.us/Angular scrollviews (ngRepeat) only for very small lists, approx. up to 50 items.
  • The higher the number of items and the more complex your scrollview (several surfaces and/or transitionables per item) the longer the time to execute (linear scale)
  • Use native / plain vanilla Famo.us scrollviews for high performance scrollviews. Large lists with several hundred items are no problem – even on older phones.

 

 

Example Code for an Angular directive using a „plain vanilla Famo.us scrollview“
Execute it by using the directive <vanilla-scrollview></vanilla-scrollview>
The directive uses $scope data to populate the scrollview: scope.views[i].headline

angular.module('myModule')
    .directive('vanillaScrollview', function ($famous, $famousDecorator) {
        return {
            template: '<div></div>',
            transclude: true,
            scope: true,
            restrict: 'EA',
            compile: function(tElement, tAttrs, transclude){

                var View = $famous['famous/core/View'];
                var Surface = $famous['famous/core/Surface'];
                var Transform       = $famous['famous/core/Transform'];
                var StateModifier = $famous['famous/modifiers/StateModifier'];
                var ScrollView = $famous['famous/views/Scrollview'];

                return {
                    pre: function(scope, element, attrs){
                        // pre: executed before child elements are linked
                        // NOT safe to do DOM transformations here

                        // start Famo.us vanilla code here...
                        // 'view' will be attached to the directive

                        var view = new View({
                            // read attribute fa-size !
                            size: scope.$eval(attrs.faSize) || [undefined, undefined]
                        });

                        var scrollview = new ScrollView({
                            paginated: false,
                            friction: 0.001
                            //speedLimit: 200
                        });

                        var surfaces = [];

                        scrollview.sequenceFrom(surfaces);

                        var surface1, view1;

                        for (var i = 0; i < scope.views.length; i++) {
                            var html = '<strong>'+scope.views[i].headline + '</strong><br>' + scope.views[i].content;     
                            surface1 = new Surface({
                                content: html,
                                size: [undefined, 100],
                                properties: {
                                    backgroundColor: scope.views[i].color,
                                    lineHeight: '40px',
                                    textAlign: 'left'
                                }
                            });


                            surface1.pipe(scrollview);

                            surfaces.push(surface1);

                        }



                        view.add(scrollview);

                        // end of Famo.us vanilla code

                        // $famousDecorator:
                        // http://famo.us/integrations/angular/docs/unstable/api/service/$famousDecorator/index.html
                        //
                        // .ensureIsolate() checks the passed in scope for an existing isolate property.
                        // If scope.isolate does not already exist, create it.
                        var isolate = $famousDecorator.ensureIsolate(scope);

                        isolate.children = [];

                        isolate.renderNode = view;
                        $famousDecorator.addRole('renderable',isolate);

                        isolate.show();

                        // Attach a listener for registerChild events.
                        $famousDecorator.sequenceWith(scope, function(data) {
                            isolate.renderNode.add(data.renderGate);
                            isolate.children.push(data);
                        });

                    },
                    post: function(scope, element, attrs){
                        // post: executed after the child elements are linked
                        // IS safe to do DOM transformations here

                        var isolate = $famousDecorator.ensureIsolate(scope);

                        transclude(scope, function(clone) {
                            element.find('div').append(clone);
                        });

                        // Register a child isolate's renderNode to the nearest parent that can sequence it,
                        // and set up an event listener to remove it when the associated element is destroyed by Angular.
                        $famousDecorator.registerChild(scope, element, isolate);
                    }
                };
            }
        };
    });

28.10.2014

How to Famo.us-ify your Angular app (v0.5.0)

Just a quick note how to add Famo.us/Angular to your existing Angular app:

 

1.
Add sources:

By adding the CDN-URLs:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="http://code.famo.us/famous/0.3/famous-global.min.js"></script>
<script src="http://code.famo.us/famous-angular/0.4.0/famous-angular.min.js"></script>
<link rel="stylesheet" href="http://code.famo.us/famous-angular/0.4.0/famous-angular.min.css"/>

Or by adding your local dependencies:

<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/famous/dist/famous-global.js"></script>
<script src="bower_components/famous-angular/dist/famous-angular.js"></script>
<link rel="stylesheet" href="bower_components/famous-angular/dist/famous-angular.css"/>

Use the following bower configuration to get the correct local artifacts:

"dependencies": {
   "angular": "1.2.26",
   "famous-angular": "0.5.0"
}

2.
Add Famo.us directives inside your application’s HTML:

Define your ng-app and inside your fa-app:

<div ng-app="myApp">
  <fa-app id="app">
    <fa-modifier fa-size="[100, 100]"
      fa-translate="[50, 10, 0]"
      fa-rotate-z="0.4">
        <fa-surface fa-background-color="'#FA5C4F'"
           fa-color="'white'">
             This is Famo.us!
        </fa-surface>
    </fa-modifier>
  </fa-app>
</div>

 

3.
Include the Famo.us-Angular module in your Angular app:

angular.module('myApp', ['famous.angular']);

 

That’s it – now you can see the Famo.us surface inside your existing Angular app, e.g. this Bootstrap styled web application:

famous-integration

28.09.2014

Famo.us/Angular 0.4.0 released

  • Enhanced documentation with more code examples.
  • Support removing children from fa-header-footer-layout
  • fa-option directive
  • fa-draggable
  • Piping to/from Modifiers (e.g. Draggable) with fa-pipe-to and fa-pipe-from
  • Observe on faSize of faSurface
  • and some bugfixes, especially the annoying exception when fa-container-surface’s children were removed

See all changes on Github.

 

06.09.2014

My Little Private Famo.us/Angular University – Course 02. Step 3

Goals

  • Create a scrollable list with a detail view
  • The first iteration should be very simple: A combination of a Famo.us scrollview and a surface for the detail.
  • The detail view should be accessible by a deep link URL, thus a UI router based solution should be implemented

 

 

Local Development

To code in your local environment you can pull everything from Github (for more details see Step 1):

Details

1.

Some refactorings:

  • Renaming of app/partials/homeview.html to appview.html
  • Renaming of app/scripts/controllers/homeview.js to appview.js
  • Small CSS fixes

 

2.

Adding new views to the router:

  • The state „app“ is now our root state. It is an abstract route and never called directly.
  • The state „app.list“ maps to the new view partials/listview.html
  • The state „app.list.detail“ maps to the new view partials/listview-detail.html

These changes can be seen in the router configuration file app/scripts/app.js

 

3.

The new scrollview in partials/listview.html

  • A simple „out of the box“ Famo.us scrollview with some colored surfaces.
    • The list’s data is defined in line 57 of the controller (array $scope.list)
    • Remember the fa-pipe-to=“myscrollEventHandler“ directive
    • The corresponding function is defined in line 64 of the controller: $scope.myscrollEventHandler = new EventHandler(); 

 

4.

The new detailview in partials/listview-detail.html

  • This view is bound to the state app.list.detail (see above) and the ui-view=“detailView“ in line 13 of the listview.html
  • Whenever a URL like #/app/list/123 is called, this state is used and the corresponding template listview-detail.html is inserted in the ui-view=“detailView“ (see above).: The blue surface is shown.
  • The last part of the URL „123“ is a state parameter named „detail“ (see router configuration). Think of it as a kind of ID of this detail information, eg. a product id.

The „trick“ is, that the surface is shown in an animated way: It flies in from the bottom of the page.

As far as I know a router based animation is not supported by Famo.us/Angular so far (but it’s on the roadmap). So I had the idea to catch the router event $stateChangeStart and animate the changes by changing the transitionable of the detail view (the blue surface):

  • By default the blue surface is positioned outside of the content view (controller code line 88: Y set to 600)
  • If the URL state changes the event handler is called (controller code line92:  $scope.$on(‚$stateChangeStart‘)
  • Depending on the „detail“ parameter of the URL the blue surface (the Y position of it’s transitionable) is set to 20 or to 600. If the „detail“ parameter is „0“ (default / nothing selected) the position is 600.

It’s a very simple approach and it does not scale very good (in terms of many lists and detail views in parallel) but for a small application it a solid solution and you have full control of everything. I think it is a nice example for combining the strengths of Angular (UI router / events) and Famo.us (animation).

 

02.09.2014

My Little Private Famo.us/Angular University – Course 02. Step 2

Goals

  • Create the side navigation
  • Design the view with Famo.us/Angular directives, create a controller to toggle the visibility of the navigation (show/hide)
  • A similar codebase was implemented using plain vanilla Famo.us in My Little Private Famo.us University – Course 01 – see a Codepen here.

 

 

 

Local Development

To code in your local environment you can pull everything from Github (for more details see Step 1):

Details

The main changes are modelling the view in app/views/homeview.html and coding the controller in  app/scripts/controllers/homeview.js

  • The view is constructed by two views: view id=side contains the side navigation and view id=main contains the main screen, which is a Famo.us header-footer-layout
  • Both views are encapsulated by a modifier <fa-modifier fa-translate = „sideTransitionable1.get()“>. This modifier is defined by a function, you can find it in the controller homeview.js in line 13
    • By clicking the navigation button the modifier’s attributes are changed in line 21: Both views are shifted 50 pixels to the right or back to position. This results in the „sliding in“ effect for the side navigation and the main screen.
  • The y-axis rotation of the side navigation is defined by a modifier <fa-modifier fa-rotate = „sideTransitionable3.get()“>. This modifier is defined by a function, you can find it in the controller homeview.js in line 17
    • By clicking the navigation button the modifier’s attributes are changed in line 22: The rotation is set to 0 or back to  -Math.PI/2.5
  • The side navigation itself is built via <ng-repeat> and the object sidenavelements defined in line 32 of the controller homeview.js

 

<fa-modifier fa-translate = "sideTransitionable1.get()">
  <fa-view id="side">
     <fa-modifier fa-size="[50, undefined]">
       <fa-modifier fa-origin="[1, 0]" fa-translate = "sideTransitionable2.get()">
         <fa-modifier fa-rotate = "sideTransitionable3.get()">
           <fa-grid-layout fa-options="{ dimensions: [1, 6] }">
             <fa-surface ng-repeat="element in sideNavElements" ng-class="['side-view-button']" fa-background-color="element.bgcolor"> 
                   <i class="fa {{element.iconclass}}" ></i>
             </fa-surface>
           </fa-grid-layout>
         </fa-modifier>
       </fa-modifier>
     </fa-modifier>
 </fa-view>
<fa-view id="main">
 <fa-header-footer-layout>
   <fa-modifier fa-translate = "[0,0,1]">
     <fa-surface fa-size="[undefined, 50]" fa-background-color="'#2d5d81'" fa-click="menuToggle($event)"> 
         <i class="fa fa-arrows-alt"></i><span class="headertext">acme management app</span>
     </fa-surface>
   </fa-modifier>
   <fa-surface fa-background-color="'#ddd'"><p>hello world</p></fa-surface>
  </fa-header-footer-layout>
</fa-view>
</fa-modifier>

 

This concept of binding modifiers to the scope’s functions and inside the function setting or changing a Transitionable object is one of the key concepts to control the layout of your application!

You can learn this in detail in the official Famo.us university here.

28.08.2014

New Video: „Famo.us/Angular – A case study of AngularJS as a framework for frameworks“

The Google AngularJS team published a new video with the main talk held by Zack Brown (Thomas Street, the „father“ of the Famo.us/Angular project).

In his talk Zack describes the technical challenges and considerations of integrating these two seemingly orthogonal yet complementary libraries, while highlighting AngularJS’s ability to be a “framework for frameworks.”

One highlight of the talk is his „Flickrous“ Demo

 

The demo shows:

  • REST API integration example (Flickr)
  • Usage of customs directive „photoCube“ – an enhancement of the <fa-cuboid> directive showing a nice 3D-cube
  • Usage of animations triggered by Angular data-changes

 

Links: