Question

If i create a famo.us surface giving a size of [true, true] and put some arbitrary html content into it, is there a clean way to retrieve the size of the object?

surface.getSize() just returns the same [true,true]

I noticed there are some apparently private methods such as: s._currTarget.clientHeight but it seems asking for trouble to use those!

Was it helpful?

Solution

There are a couple of ways to solve this issue. Famo.us is aware of this limitation and it should be pretty high on the priority list..

In this example, a new surface class is created that emits an event in the deploy function or when the surface is rendered. I am sure to grab the reference to the original deploy function during construction, so that can be called normally later on. Once you receive the render event you can edit the surface any way you wish..

Good Luck!

var Engine            = require('famous/core/Engine');
var Surface           = require('famous/core/Surface');
var StateModifier     = require('famous/modifiers/StateModifier');
var EventHandler      = require('famous/core/EventHandler');


function MySurface(options) {
    Surface.apply(this, arguments);
    this._superDeploy = Surface.prototype.deploy;
}

MySurface.prototype = Object.create(Surface.prototype);
MySurface.prototype.constructor = MySurface;


MySurface.prototype.deploy = function deploy(target) {
  this._superDeploy(target);
  this.eventHandler.trigger('surface-has-rendered', this);
};

var context = Engine.createContext();

var event_handler = new EventHandler();

event_handler.on('surface-has-rendered', function(surface){

  var size = surface.getSize();
  var width = (size[0] == true) ? surface._currTarget.offsetWidth : size[0] ;
  var height = (size[1] == true) ? surface._currTarget.offsetHeight : size[1] ;

  surface.setSize([width,height]);

  console.log(surface.getSize());

})

var surface = new MySurface({
  size: [true,true],
  content: "Hello",
  properties: {
    color: 'white',
    textAlign: 'center',
    padding: '20px',
    backgroundColor: 'green'
  }
})

surface.pipe(event_handler);

context.add(new StateModifier({origin:[0.5,0.5]})).add(surface);

OTHER TIPS

Passing true into .getSize currently returns the DOM size of the Surface.

surface.getSize(true)

The easiest way to get the actual size of a surface is surface.getSize(true). You don't need to subclass Surface.

However, you will get an error if the surface isn't rendered to DOM yet. When a surface is rendered, it will emit a 'deploy' event. You can listen for it like this:

surface.on('deploy', function () {
    // Your Code Here
}.bind(this));

More than likely you will also have to wrap your code in a Timer.setTimeout() too. This is because the surface.getSize(true) method will execute faster than the next render cycle (60 frames per second or ~16 milliseconds per cycle). The final code will look like this:

// With the rest of your require statements
var Timer = require('famous/utilities/Timer');

surface.on('deploy', function () {
    Timer.setTimeout( function () {
        // Your code here
        // this.surface.getSize(true)
    }.bind(this), 16);
}.bind(this));

I'm new to Famo.us too but I have had to implement this fix for a few different situations in my project and it seems to work perfectly.

Let me know if it works for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top