Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best pattern for responsive apps in famo.us

Tags:

famo.us

By way of example, in a bootstrap based app I might write markup to make a grid be 8 columns wide for large screens and 2 columns wide for small.

Screen size certainly has an impact on screen design, and I want to know what is a decent pattern to follow before I start trying things in famo.us. Seeing as famo.us is 'opiniated', there should really only be one answer here :)

I'm all for mobile-first design, but what I don't want is a desktop app that is just a mobile app stretched by 400%.

Thanks,

Andrew

like image 245
aleith Avatar asked Apr 17 '14 17:04

aleith


People also ask

How do I choose a responsive breakpoint?

Always keep the common breakpoints for responsive design in mind. The former usually matches common screen sizes (480px, 768px, 1024px, and 1280px). Before choosing major breakpoints, use website analytics to discern the most commonly used devices from which your site is accessed.

What are the standard breakpoints for responsive design?

What are common breakpoints? Common breakpoints are 320px — 480px for mobile devices, 481px — 768px for iPads & tablets, 769px — 1024px for small screens like laptop, 1025px — 1200px for large screens like Desktops, and 1201px and above for extra large screens like TV.

Does Google prefer responsive design?

“Responsive design is Google's recommended design pattern.” The responsiveness of your website is unequivocally an important factor in improving user experience and avoiding common SEO pitfalls that can hinder your Google rankings.


2 Answers

Based on the example in the Famo.us Examples on Github..

https://github.com/Famous/examples/blob/master/src/examples/views/GridLayout/example.js

You could very easily do something like this..

var Engine     = require("famous/core/Engine");
var Surface    = require("famous/core/Surface");
var GridLayout = require("famous/views/GridLayout");

var mainContext = Engine.createContext();

var contextSize = mainContext.getSize()

var dimensions;

if (contextSize[0] < 480 || contextSize[1] < 480) {
    dimensions = [2,8];
} else {
    dimensions = [8,2];
};

var grid = new GridLayout({
    dimensions: dimensions
});

var surfaces = [];
grid.sequenceFrom(surfaces);

for(var i = 0; i < 16; i++) {
    surfaces.push(new Surface({
        content: "I am panel " + (i + 1),
        size: [undefined, contextSize[1] / 2.0],
        properties: {
            backgroundColor: "hsl(" + (i * 360 / 16) + ", 100%, 50%)",
            color: "black",
            lineHeight: window.innerHeight / 2 + 'px',
            textAlign: 'center'
        }
    }));
}

mainContext.add(grid);

EDIT:

Being that the end goal is Javascript as a sole development language for modern web applications.. Sometimes you just have to manage things yourself.

This is especially true for a framework like Famo.us, which is strongly dependent on absolute positioning.. Things just don't flow as smoothly as in the box model

To handle all the subtle differences I build a StateHash class that manages the state and returns different values for the same keys based on the current state..

var DESKTOP, MOBILE, StateHash, screen_state, sh;

StateHash = (function() {

  function StateHash(states) {
    this.set_state = __bind(this.set_state, this);

    this.get_state = __bind(this.get_state, this);

    this.set = __bind(this.set, this);

    this.get = __bind(this.get, this);

    var i, _i, _ref;
    if (!states) {
      states = 2;
    }
    this.state = 0;
    this.hash = {};
    for (i = _i = 0, _ref = states - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
      this.hash[i] = {};
    }
  }

  StateHash.prototype.get = function(key) {
    return this.hash[this.state][key];
  };

  StateHash.prototype.set = function(state, key, val) {
    return this.hash[state][key] = val;
  };

  StateHash.prototype.get_state = function() {
    return this.state;
  };

  StateHash.prototype.set_state = function(state) {
    return this.state = state;
  };

  return StateHash;

})();

// Usage

MOBILE = 0;
DESKTOP = 1;

screen_state = some_check_mobile_function() ? MOBILE : DESKTOP;

sh = new StateHash();
sh.set_state(screen_state);

sh.set(MOBILE, "top-margin", "10px");
sh.set(DESKTOP, "top-margin", "20px");

sh.get("top-margin");

I will let you know if I learn of any other better way!

Good Luck!

like image 128
johntraver Avatar answered Oct 12 '22 10:10

johntraver


The approach is improvised version of using grids based on window size. Just added a resize listener to observe resize events.

function ResponsiveGridView() {

    View.apply(this, arguments);

    this.rootModifier = new StateModifier({
        align: [.5, .5],
        origin: [.5, .5]
    });

    this.mainNode = this.add(this.rootModifier);

    this.slides = [];

    _createGrid.call(this);
    _createSlides.call(this);

    Engine.on('resize', function(){
        _reflowGrid.call(this);
    }.bind(this));
}
function _createGrid(){
    this.grid = new GridLayout({
         dimensions: window.innerWidth < 490?[1,8]:[4, 2],
         transition: {curve: 'easeInOut',duration: 200}
        });
    this.grid.sequenceFrom(this.slides);
    this.mainNode.add(this.grid);
}
function _reflowGrid(){
    this.grid.setOptions({dimensions: window.innerWidth < 490?[1,8]:[4, 2]});
}
like image 35
sabithpocker Avatar answered Oct 12 '22 08:10

sabithpocker