how can we get the size of a surface within famo.us?

回眸只為那壹抹淺笑 提交于 2019-11-29 11:56:47

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);

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.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!