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?
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);
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.
Passing true
into .getSize
currently returns the DOM size of the Surface
.
surface.getSize(true)