Home

FlexibleLayout

The idea behind FlexibleLayout is very similar to HTML5 Flexbox, in that you specify a set of coefficients that map to the size of a particular renderable based on the total of all of the coefficients. FlexibleLayout is great for situations that GridLayout and HeaderFooterLayout cannot handle.

Basic use

To start using the FlexibleLayout, we will need two things:

Each of the renderables will be sized according to the coefficient in the array of coefficients. To figure out the ratio of each renderable, first get the sum of all of the coefficients, then divide by the individual coefficient. (For example, if we had the coefficients [1,2,3], the sum total would be 6, giving us the ratios [1/6, 2/6, 3/6] respectively.

// @famous-block
// @famous-block-option preset famous-0.3.0-globals
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var FlexibleLayout = famous.views.FlexibleLayout;

var mainContext = Engine.createContext();

var colors = [
    'rgba(256, 0, 0, .7)',
    'rgba(0, 256, 0, .7)',
    'rgba(0, 0, 256, .7)'
];

// Since the sum of our array of ratios is 9,
// the red Surface will take up 1/9 of the entire screen,
// the green Surface will take up 3/9,
// and the blue Surface will take up 5/9.
var ratios = [1, 3, 5];

var layout = new FlexibleLayout({
    ratios: ratios
});

var surfaces = [];

for (var i = 0; i < 3; i++) {
    surfaces.push(new Surface({
        size: [undefined, undefined],
            properties: {
                backgroundColor: colors[i % 3]
            }
    }));
}

layout.sequenceFrom(surfaces);

mainContext.add(layout);

Ratio equality

Let’s say we wanted a side bar that took up 25 percent of the screen and a content area that took up 75 percent. Any array where there first element is one third of the second element would produce the correct layout. This feature allows the developer to pick the base that makes the most sense in the context of their application.

// @famous-block
// @famous-block-option preset famous-0.3.0-globals
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var FlexibleLayout = famous.views.FlexibleLayout;

var mainContext = Engine.createContext();

var colors = [
    'rgba(256, 0, 0, .7)',
    'rgba(0, 256, 0, .7)',
    'rgba(0, 0, 256, .7)'
];

var ratios = [1, 3];
var layout = new FlexibleLayout({
    ratios: ratios
});

var surfaces = [];

for (var i = 0; i < 2; i++) {
    surfaces.push(new Surface({
        size: [undefined, undefined],
        properties: {
            backgroundColor: colors[i % 3]
        }
    }));
}

layout.sequenceFrom(surfaces);

mainContext.add(layout);

Vertical FlexibleLayouts

By default, FlexibleLayouts arranges its renderables horizontally. You can make it lay out its renderables vertically by setting the direction option on the FlexibleLayout.

// @famous-block
// @famous-block-option preset famous-0.3.0-globals
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var FlexibleLayout = famous.views.FlexibleLayout;

var mainContext = Engine.createContext();

var colors = [
 'rgba(256, 0, 0, .7)',
 'rgba(0, 256, 0, .7)',
 'rgba(0, 0, 256, .7)'
];

var ratios = [1, 3, 5];
var layout = new FlexibleLayout({
  direction: 1,
  ratios: ratios
});

var surfaces = [];


for (var i = 0; i < 3; i++) {
 surfaces.push(new Surface({
   size: [undefined, undefined],
   properties: {
     backgroundColor: colors[i % 3]
   }
 }));
}

layout.sequenceFrom(surfaces);

mainContext.add(layout);

FlexibleLayout with Modifiers

By default, FlexibleLayouts expand to fill their parent size. If we attach the FlexibleLayout to a modifier with a specific size, we can see that the layout will only fill that size versus the entire context.

// @famous-block
// @famous-block-option preset famous-0.3.0-globals
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var StateModifier = famous.modifiers.StateModifier;
var FlexibleLayout = famous.views.FlexibleLayout;

var mainContext = Engine.createContext();

var colors = [
 'rgba(256, 0, 0, .7)',
 'rgba(0, 256, 0, .7)',
 'rgba(0, 0, 256, .7)'
];

var ratios = [1, 3, 6];
var layout = new FlexibleLayout({
  ratios: ratios
});

var surfaces = [];

for (var i = 0; i < 3; i++) {
  surfaces.push(new Surface({
    size: [undefined, undefined],
    properties: {
      backgroundColor: colors[i % 3]
    }
  }));
}

layout.sequenceFrom(surfaces);

var mod = new StateModifier({
 size: [400, 400]
});

mainContext.add(mod).add(layout);

True ratios

Sometimes, we may only want parts out our layout to be flexible and others to remain the same size regardless of the size of the container. FlexibleLayout provides an easy interface for this.

By setting the particular coefficient to true, we can defer to the defined size of the renderable instead of calculating it based on come percentage of the parent size.

// @famous-block
// @famous-block-option preset famous-0.3.0-globals
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var StateModifier = famous.modifiers.StateModifier;
var FlexibleLayout = famous.views.FlexibleLayout;

var mainContext = Engine.createContext();

var colors = [
 'rgba(256, 0, 0, .7)',
 'rgba(0, 256, 0, .7)',
 'rgba(0, 0, 256, .7)'
];

var ratios = [1, true, 1];
var layout = new FlexibleLayout({
  ratios: ratios
});

var surfaces = [];

for (var i = 0; i < 3; i++) {
 var size = i === 1 ? [20, undefined] : [undefined, undefined];
 surfaces.push(new Surface({
   size: size,
   properties: {
     backgroundColor: colors[i % 3]
   }
 }));
}

layout.sequenceFrom(surfaces);

var mod = new StateModifier({
 size: [400, 400]
});

mainContext.add(mod).add(layout);

Transitions

FlexibleLayout also has a transition option that defines how the layout responds to changes in sizing and dimension. By default, transition is false, meaning that changes are instantly seen on the next frame of animation. You can override this by giving it a specific transition, such as an easing curve. The transition will get called every time the layout has to reflow itself. (This occurs when adding, new renderables, new ratios, and when the parent size changes.)

(Note: Depending on the changes, this action very well may lead to a lot of browser repaints since transitioning size will always trigger repaints.)

// @famous-block
// @famous-block-option preset famous-0.3.0-globals
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var FlexibleLayout = famous.views.FlexibleLayout;

var mainContext = Engine.createContext();

var colors = [
 'rgba(256, 0, 0, .7)',
 'rgba(0, 256, 0, .7)',
 'rgba(0, 0, 256, .7)'
];

var ratios = [1, 3, 5];

var layout = new FlexibleLayout({
  ratios: ratios,
  transition: {
    curve: 'easeInOut',
    duration: 2000
  }
});

var surfaces = [];

for (var i = 0; i < 3; i++) {
 surfaces.push(new Surface({
   size: [undefined, undefined],
   properties: {
     backgroundColor: colors[i % 3]
   }
 }));
}

layout.sequenceFrom(surfaces);

mainContext.add(layout);

Engine.on('click', function() {
  ratios = ratios.reverse();

  layout.setRatios(ratios)
});

Next: GridLayout »