0

I don't think I understand what it means to size a famo.us node with a true size.

In this example, I'm just trying to center a View with a fixed size. But I eventually want these BlueView's to calculate their size based on their content, and have an array of them in a Scrollview.

So, I guess my questions are:

What does true size really mean? What's the math behind it? I'm assuming that a size of true triggers the node, blueModifier, to get that value from its direct child node, in this case my blueView instance. Am I wrong?

If that is the case, how to I get BlueView's to publish their size? Reading the famo.us source and their documentation is just confusing. It looks like if a View has just a single child, it should use that child's size. Or you can use setOptions() on a view to set its size. Or you can override a views getSize() function. But I can't get any of those to work.

function BlueView() {
  View.call(this)

  this
    .add(new Modifier({
      size: [400, 200],
      origin: [0, 0],
      align: [0, 0]
    }))
    .add(new Surface({
      properties: {
        backgroundColor: 'blue'
      }
    }));

};
BlueView.prototype = Object.create(View.prototype);
BlueView.prototype.constructor = BlueView;



var blueModifier = new Modifier({
  size: [true, true],
  origin: [0.5, 0.5],
  align: [0.5, 0.5],
});

var blueView = new BlueView();


mainContext.add(blueModifier).add(blueView);

http://jsbin.com/gopeli/1/edit?html,output

nicholas
  • 14,184
  • 22
  • 82
  • 138
  • Hi [@nicholas](http://stackoverflow.com/users/586181/nicholas), I hope the answer below clears up any confusion. – talves Mar 28 '15 at 19:40

1 Answers1

1

Sizing in Famo.us can get confusing real quick (currently version 0.3.5). We all hope they fix this in MixedMode. Here is a stab at explaining it to try to clear it up for you.

Types of Sizing:

  • True - [true, true]
  • Undefined - [undefined, undefined]
  • Actual - [Xpx, Ypx] e.g. [100, 100]

Each of these have a snippet that you can see the sizes returned on a click of the BlueView. I took liberty to refactor by extending View, so we can access the renderables for the examples.

True

True sizing in Famo.us is a way of telling your renderable to size to it's contents. Basically it is the equivalent of having a <div> with no height and width. The renderable does not get the size direct from the child, so there is no math going on here. The developer needs to understand the size may not be transparent to the getSize method when using True sizing.

There may be ways to get the real size of the renderable, but depend on how and when it is rendered to the context. A good time may be on deploy of the renderable, and get the real true size from the target.

define('main', function(require, exports, module) {
  var Engine = require("famous/core/Engine");
  var View = require("famous/core/View");
  var Surface = require("famous/core/Surface");
  var StateModifier = require("famous/modifiers/StateModifier");
  var Modifier = require("famous/core/Modifier");

  var BlueView = require("BlueView");

  var mainContext = Engine.createContext();

  // Grid lines to show the center of the context.

  var sizeShow = new Surface({
    content: 'Click BlueView Surface to get sizes',
    size: [true, true],
    properties: {
      backgroundColor: 'rgba(0,0,0,0.15)'
    }
  });

  var outerBlueBack = new Surface({
    size: [undefined, undefined],
    properties: {
      backgroundColor: 'rgba(0,0,255,0.15)'
    }
  });

  var horizontalRule = new Surface({
    content: '',
    size: [undefined, 1],
    properties: {
      backgroundColor: '#aaaaaa'
    }
  });

  var verticalRule = new Surface({
    content: '',
    size: [1, undefined],
    properties: {
      backgroundColor: '#aaaaaa'
    }
  });

  var originModifier = new StateModifier({
    origin: [0.5, 0.5],
    align: [0.5, 0.5]
  });

  var node = mainContext.add(originModifier);
  node.add(verticalRule);
  node.add(horizontalRule);


  var sizeBlueModifier = new Modifier({
    //size: [true, true]
    //size: [undefined, undefined]
    size: [400, 200]
  });

  var centerBlueModifier = new Modifier({
    origin: [0.5, 0.5],
    align: [0.5, 0.5],
  });

  var blueView = new BlueView({
    content: 'set to true',
    size: [true, true]
  });
  blueView.on('deploy', function() {
    var sizeInfo = sizeShow.getContent() + '<br/><hr>';
    var target = this.surface._currentTarget;
    var targetSize = [target.clientWidth, target.clientHeight];
    
    sizeInfo += 'target size = ' + targetSize;
    sizeShow.setContent(sizeInfo);
  });
  blueView.on('click', function(e) {
    console.log(e);
    var target = e.target;
    var targetSize = [target.clientWidth, target.clientHeight];
    
    var sizeInfo = 'target size = ' + targetSize + '<br/><hr>';
    sizeInfo += 'BlueView size = ' + this.sizeMod.getSize() + '<br/>';
    sizeInfo += 'BlueView.sizeMod = ' + this.sizeMod.getSize() + '<br/>';
    sizeInfo += 'BlueView.surface = ' + this.surface.getSize() + '<br/><hr>';
    sizeInfo += 'sizeBlueModifier = ' + sizeBlueModifier.getSize() + '<br/>';
    sizeInfo += 'outerBlueBack = ' + outerBlueBack.getSize() + '<br/>';
    
    sizeShow.setContent(sizeInfo);
  });


  mainContext.add(sizeShow);
  var centerBlueNode = mainContext.add(centerBlueModifier);
  var outerBlueNode = centerBlueNode.add(sizeBlueModifier);
  outerBlueNode.add(outerBlueBack);
  centerBlueNode.add(blueView);
});
define('BlueView', function(require, exports, module) {
  var View = require("famous/core/View");
  var Surface = require("famous/core/Surface");
  var Modifier = require("famous/core/Modifier");

  function BlueView(options) {
    View.apply(this, arguments);

    this.sizeMod = new Modifier({
      size: this.options.size,
    });
    this.placeMod = new Modifier({
      origin: this.options.origin,
      align: this.options.align
    });
    this.surface = new Surface({
      content: this.options.content,
      properties: {
        backgroundColor: 'blue',
        cursor: 'pointer'
      }
    });

    this
      .add(this.sizeMod)
      .add(this.placeMod)
      .add(this.surface);

    this.surface.pipe(this._eventOutput);

  };

  BlueView.DEFAULT_OPTIONS = {
    size: [undefined, undefined]
  };

  BlueView.prototype = Object.create(View.prototype);
  BlueView.prototype.constructor = BlueView;

  module.exports = BlueView;
});
require(['main']);
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>

<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />

<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>

Undefined

Undefined sizing tells the renderable to size to it's 'parent'. In this case, the size should be referenced from the parent. If you do not know who the parent is, you can always get the size from the actual target renderable after deploy.

Note: When the size is not set it is like setting undefined.

define('main', function(require, exports, module) {
  var Engine = require("famous/core/Engine");
  var View = require("famous/core/View");
  var Surface = require("famous/core/Surface");
  var StateModifier = require("famous/modifiers/StateModifier");
  var Modifier = require("famous/core/Modifier");

  var BlueView = require("BlueView");

  var mainContext = Engine.createContext();

  // Grid lines to show the center of the context.

  var sizeShow = new Surface({
    content: 'Click BlueView Surface to get sizes',
    size: [true, true],
    properties: {
      backgroundColor: 'rgba(0,0,0,0.15)'
    }
  });

  var outerBlueBack = new Surface({
    size: [undefined, undefined],
    properties: {
      backgroundColor: 'rgba(0,0,255,0.15)'
    }
  });

  var horizontalRule = new Surface({
    content: '',
    size: [undefined, 1],
    properties: {
      backgroundColor: '#aaaaaa'
    }
  });

  var verticalRule = new Surface({
    content: '',
    size: [1, undefined],
    properties: {
      backgroundColor: '#aaaaaa'
    }
  });

  var originModifier = new StateModifier({
    origin: [0.5, 0.5],
    align: [0.5, 0.5]
  });

  var node = mainContext.add(originModifier);
  node.add(verticalRule);
  node.add(horizontalRule);


  var sizeBlueModifier = new Modifier({
    //size: [true, true]
    //size: [undefined, undefined]
    size: [200, 200]
  });

  var centerBlueModifier = new Modifier({
    origin: [0.5, 0.5],
    align: [0.5, 0.5],
  });

  var blueView = new BlueView({
    content: 'set to undefined',
    size: [undefined, undefined]
  });
  blueView.on('deploy', function() {
    var sizeInfo = sizeShow.getContent() + '<br/><hr>';
    var target = this.surface._currentTarget;
    var targetSize = [target.clientWidth, target.clientHeight];
    
    sizeInfo += 'target size = ' + targetSize;
    sizeShow.setContent(sizeInfo);
  });
  blueView.on('click', function(e) {
    console.log(e);
    var myTarget = e.target;
    var myTargetSize = [myTarget.clientWidth, myTarget.clientHeight];
    
    var sizeInfo = 'target size = ' + myTargetSize + '<br/><hr>';
    sizeInfo += 'BlueView size = ' + this.sizeMod.getSize() + '<br/>';
    sizeInfo += 'BlueView.sizeMod = ' + this.sizeMod.getSize() + '<br/>';
    sizeInfo += 'BlueView.surface = ' + this.surface.getSize() + '<br/><hr>';
    sizeInfo += 'sizeBlueModifier = ' + sizeBlueModifier.getSize() + '<br/>';
    sizeInfo += 'outerBlueBack = ' + outerBlueBack.getSize() + '<br/>';
    
    sizeShow.setContent(sizeInfo);
  });


  mainContext.add(sizeShow);
  var centerBlueNode = mainContext.add(centerBlueModifier);
  var outerBlueNode = centerBlueNode.add(sizeBlueModifier);
  outerBlueNode.add(outerBlueBack);
  outerBlueNode.add(blueView);
});
define('BlueView', function(require, exports, module) {
  var View = require("famous/core/View");
  var Surface = require("famous/core/Surface");
  var Modifier = require("famous/core/Modifier");

  function BlueView(options) {
    View.apply(this, arguments);

    this.sizeMod = new Modifier({
      size: this.options.size,
    });
    this.placeMod = new Modifier({
      origin: this.options.origin,
      align: this.options.align
    });
    this.surface = new Surface({
      content: this.options.content,
      properties: {
        backgroundColor: 'blue',
        cursor: 'pointer'
      }
    });

    this
      .add(this.sizeMod)
      .add(this.placeMod)
      .add(this.surface);

    this.surface.pipe(this._eventOutput);

  };

  BlueView.DEFAULT_OPTIONS = {
    size: [undefined, undefined]
  };

  BlueView.prototype = Object.create(View.prototype);
  BlueView.prototype.constructor = BlueView;

  module.exports = BlueView;
});
require(['main']);
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>

<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />

<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>

Actual

The actual size is self explanatory. [100, 100] says to make the renderable 100 pixels in width by 100 pixels in height.

define('main', function(require, exports, module) {
  var Engine = require("famous/core/Engine");
  var View = require("famous/core/View");
  var Surface = require("famous/core/Surface");
  var StateModifier = require("famous/modifiers/StateModifier");
  var Modifier = require("famous/core/Modifier");

  var BlueView = require("BlueView");

  var mainContext = Engine.createContext();

  // Grid lines to show the center of the context.

  var sizeShow = new Surface({
    content: 'Click BlueView Surface to get sizes',
    size: [true, true],
    properties: {
      backgroundColor: 'rgba(0,0,0,0.15)'
    }
  });

  var outerBlueBack = new Surface({
    size: [undefined, undefined],
    properties: {
      backgroundColor: 'rgba(0,0,255,0.15)'
    }
  });

  var horizontalRule = new Surface({
    content: '',
    size: [undefined, 1],
    properties: {
      backgroundColor: '#aaaaaa'
    }
  });

  var verticalRule = new Surface({
    content: '',
    size: [1, undefined],
    properties: {
      backgroundColor: '#aaaaaa'
    }
  });

  var originModifier = new StateModifier({
    origin: [0.5, 0.5],
    align: [0.5, 0.5]
  });

  var node = mainContext.add(originModifier);
  node.add(verticalRule);
  node.add(horizontalRule);


  var sizeBlueModifier = new Modifier({
    //size: [true, true]
    //size: [undefined, undefined]
    size: [200, 200]
  });

  var centerBlueModifier = new Modifier({
    origin: [0.5, 0.5],
    align: [0.5, 0.5],
  });

  var blueView = new BlueView({
    content: 'Actual<br/>[100, 100]',
    size: [100, 100]
  });
  blueView.on('click', function(e) {
    console.log(e);
    var target = e.target;
    var targetSize = [target.clientWidth, target.clientHeight];
    
    var sizeInfo = 'target size = ' + targetSize + '<br/><hr>';
    sizeInfo += 'BlueView size = ' + this.sizeMod.getSize() + '<br/>';
    sizeInfo += 'BlueView.sizeMod = ' + this.sizeMod.getSize() + '<br/>';
    sizeInfo += 'BlueView.surface = ' + this.surface.getSize() + '<br/><hr>';
    sizeInfo += 'sizeBlueModifier = ' + sizeBlueModifier.getSize() + '<br/>';
    sizeInfo += 'outerBlueBack = ' + outerBlueBack.getSize() + '<br/>';
    
    sizeShow.setContent(sizeInfo);
  });


  mainContext.add(sizeShow);
  var centerBlueNode = mainContext.add(centerBlueModifier);
  var outerBlueNode = centerBlueNode.add(sizeBlueModifier);
  outerBlueNode.add(outerBlueBack);
  centerBlueNode.add(blueView);
});
define('BlueView', function(require, exports, module) {
  var View = require("famous/core/View");
  var Surface = require("famous/core/Surface");
  var Modifier = require("famous/core/Modifier");

  function BlueView(options) {
    View.apply(this, arguments);

    this.sizeMod = new Modifier({
      size: this.options.size,
    });
    this.placeMod = new Modifier({
      origin: this.options.origin,
      align: this.options.align
    });
    this.surface = new Surface({
      content: this.options.content,
      properties: {
        backgroundColor: 'blue',
        cursor: 'pointer'
      }
    });

    this
      .add(this.sizeMod)
      .add(this.placeMod)
      .add(this.surface);

    this.surface.pipe(this._eventOutput);

  };

  BlueView.DEFAULT_OPTIONS = {
    size: [undefined, undefined]
  };

  BlueView.prototype = Object.create(View.prototype);
  BlueView.prototype.constructor = BlueView;

  module.exports = BlueView;
});
require(['main']);
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>

<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />

<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>
talves
  • 13,993
  • 5
  • 40
  • 63