【问题标题】:how can we get the size of a surface within famo.us?我们如何在 famo.us 中获取表面的大小?
【发布时间】:2023-04-03 11:24:01
【问题描述】:

如果我创建一个大小为 [true, true] 的 famo.us 表面 并将一些任意的html内容放入其中, 有没有一种干净的方法来检索对象的大小?

surface.getSize() 只是返回相同的[true,true]

我注意到有一些显然是私有的方法,例如: s._currTarget.clientHeight 但是使用这些似乎是在自找麻烦!

【问题讨论】:

    标签: meteor famo.us


    【解决方案1】:

    有几种方法可以解决此问题。 Famo.us 意识到了这个限制,它应该在优先级列表中非常高..

    在此示例中,创建了一个新的表面类,它在部署函数中或在渲染表面时发出一个事件。我肯定会在构建过程中获取对原始部署函数的引用,以便以后可以正常调用。收到渲染事件后,您可以按照自己的方式编辑表面。

    祝你好运!

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

    【讨论】:

    • 感谢您的快速回复。获取表面的宽度有点复杂。即使在调用 peek 函数之前设置超时,我也会得到Exception in queued task: TypeError: Cannot read property 'clientWidth' of null,大概是因为它在调用之前评估过?您更详细的解决方案应该会解决这个问题。
    • 是的..如果您查看任何表面类的正常部署功能..您可以看到它将目标作为第一个参数。这可以在 Surface 的核心代码中完成,但最好只是子类化。
    • 这次活动也让它变得更加精致。您始终可以在覆盖的部署函数中应用相同的逻辑,而不必担心事件。
    • 感谢详细的回复。我想这是目前唯一的方法>.
    • 不幸的是!在 IRC 频道上已经提到了很多,似乎很快就会修复!
    【解决方案2】:

    true 传递给.getSize 当前返回Surface 的DOM 大小。

    surface.getSize(true)

    【讨论】:

      【解决方案3】:

      获取表面实际大小的最简单方法是surface.getSize(true)。你不需要继承 Surface。

      但是,如果表面尚未渲染到 DOM,您将收到错误消息。当一个表面被渲染时,它会发出一个“部署”事件。你可以这样听:

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

      您很可能还必须将代码包装在 Timer.setTimeout() 中。这是因为surface.getSize(true) 方法的执行速度将比下一个渲染周期(每秒 60 帧或每个周期约 16 毫秒)更快。最终代码将如下所示:

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

      我也是 Famo.us 的新手,但我不得不针对我的项目中的几种不同情况实施此修复,而且它似乎工作得很好。

      让我知道它是否适合你。

      【讨论】:

      • 如果你想让函数在下一帧执行,你可以使用 Timer.nextTick()。
      猜你喜欢
      • 1970-01-01
      • 2011-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多