使用famo.us RenderController切换回时,曲面顺序会混乱

时间:2014-05-10 16:56:33

标签: javascript css famo.us

初学者问题。我试图建立一个famo.us应用程序。到目前为止,我在一个简单的实验中得到了很好的结果。

现在我的应用程序正在增长,我想允许在"屏幕之间移动" :登陆屏幕 - >信息屏幕 - >回到登陆屏幕 - >等

我的"屏幕"是View()的表面,修饰符等添加到View()

我使用RenderController()在屏幕之间切换hide()show()功能。

问题在于,当回到以前使用的屏幕时,表面不再显示了!

代码: var app_render_controller = new RenderController(); app_render_controller.show(landing_screen); // ok app_render_controller.hide(landing_screen); // ok app_render_controller.show(info_screen); // ok app_render_controller.hide(info_screen); // ok app_render_controller.show(landing_screen); // NOK -> I only see my background surface !

在检查DOM时,我能够在他们应该看到的地方看到我的表面轮廓,但它们是隐藏的。看起来背景表面现在位于内容表面(ScrollView)的前面。如果我隐藏背景,我会再次看到Scrollview。

我读到元素的重叠与它们添加到渲染树的顺序相对应。所以,因为我的View()基于"屏幕"还没有改变,Scrollview应该像第一次一样在背景之上绘制?

这是预期的吗?难道我做错了什么 ?我想念一下吗?

-------编辑------

我的代码(大致):

var main_context = Engine.createContext();

var root_render_controller = new RenderController();
main_context.add(root_render_controller);

var landing_screen = new View();
landing_screen.add(new Surface(...background texture...));
var scrollview = new Scrollview();
landing_screen.add(scrollview);
// (add stuff to the scrollview)

var info_screen = new View();
info_screen.add(new Surface(...background texture...));
info_screen.add(new Surface(...some message...));

root_render_controller.show(landing_screen);
// display is fine
root_render_controller.hide(landing_screen);
root_render_controller.show(info_screen);
// display is fine
root_render_controller.hide(info_screen);
root_render_controller.show(landing_screen); // again
// display is wrecked : the background surface is now hiding the scrollview !

在查看DOM时,我们可以看到翻转:

着陆屏幕的第一个显示:背景,然后是scrollview及其6个元素

1st display of the landing screen : background then the scrollview and its 6 elements

着陆屏幕的第二个显示:scrollview及其6个元素,然后是背景!

2nd display of the landing screen : scrollview and its 6 elements then the background

3 个答案:

答案 0 :(得分:1)

  

我读到元素的重叠对应于它们被添加到渲染树的顺序

从我所看到的,元素的重叠是由创建顺序的倒数(例如,最后一个在顶部)设置,而不是添加到渲染树。

创建Surface时,会在Entity注册: https://github.com/Famous/core/blob/master/Surface.js#L60

function Surface(options) {
   ...
    this.id = Entity.register(this);
   ...
}

当提交RenderNode上的更改时,将根据创建顺序应用它们(因为Object.keys以数字顺序返回数组中的索引): https://github.com/Famous/core/blob/master/RenderNode.js#L106

function _applyCommit(spec, context, cacheStorage) {
    var result = SpecParser.parse(spec, context);
    var keys = Object.keys(result);
    for (var i = 0; i < keys.length; i++) {
        var id = keys[i];
        var childNode = Entity.get(id);
    ....
}

您可以通过创建两个Surface并在第一个Context之前将您创建的第二个添加到define(function(require, exports, module) { var Engine = require("famous/core/Engine"); var Surface = require("famous/core/Surface"); var mainContext = Engine.createContext(); var surface1 = new Surface({ size: [200, 200], content: "Red", properties: { lineHeight: "200px", textAlign: "center", backgroundColor: "#f00" } }); var surface2 = new Surface({ size: [200, 200], content: "Green", properties: { lineHeight: "200px", textAlign: "center", backgroundColor: "#0f0" } }); // Doesn't matter what order you add these - surface2 will be on top mainContext.add(surface2); mainContext.add(surface1); }); 来对此进行测试。它仍然是最重要的:

Context

希望这给你一个开始寻找的好地方。如果您分享了将背景添加到{{1}}的位置,以便了解它现在在前面的原因,将会有所帮助。

答案 1 :(得分:1)

您似乎在RenderController中发现了一个错误。下面的简单示例展示了您描述的相同行为。我已经在https://github.com/Famous/views/issues/42提交了回购邮件。

注意:如果您在显示下一个视图之前不隐藏当前视图,则会得到相同的行为。有趣的是,如果你在隐藏/显示操作之间等待,你会看到不同的错误行为。

define(function(require, exports, module) {
  var Engine = require("famous/core/Engine");
  var Surface = require("famous/core/Surface");
  var View = require("famous/core/View");
  var RenderController = require("famous/views/RenderController");
  var Timer = require("famous/utilities/Timer");

  var mainContext = Engine.createContext();

  var renderController = new RenderController();

  mainContext.add(renderController);

  var view1 = new View();
  var view2 = new View();

  var surface1 = new Surface({
    size: [200, 200],
    content: "Red Background",
    properties: {
      lineHeight: "200px",
      textAlign: "center",
      backgroundColor: "#f00"
    }
  });

  var surface2 = new Surface({
    size: [200, 200],
    content: "Green Foreground",
    properties: {
      lineHeight: "200px",
      textAlign: "center",
      backgroundColor: "#0f0"
    }
  });

  var surface3 = new Surface({
    size: [200, 200],
    content: "Blue Background",
    properties: {
      lineHeight: "200px",
      textAlign: "center",
      backgroundColor: "#00f"
    }
  });

  var surface4 = new Surface({
    size: [200, 200],
    content: "Black Foreground",
    properties: {
      lineHeight: "200px",
      textAlign: "center",
      backgroundColor: "#000",
      color: "white"
    }
  });

  view1.add(surface1);
  view1.add(surface2);

  view2.add(surface3);
  view2.add(surface4);

  // If performing hide/show on same tick (or not hiding before show),
  //  you get green-fg, black-fg, red-bg (wrong)
  renderController.show(view1);
  Timer.setTimeout(function() {
    renderController.hide(view1); // <- commenting this out results in same behavior
    renderController.show(view2);
    Timer.setTimeout(function() {
      renderController.hide(view2); // <- commenting this out results in same behavior
      renderController.show(view1);
    }, 1000);
  }, 1000);

// If waiting between each hide/show
//  you get green-fg, blue-bg (wrong), green-fg
//  renderController.show(view1);
//  Timer.setTimeout(function() {
//    renderController.hide(view1);
//    Timer.setTimeout(function() {
//      renderController.show(view2);
//      Timer.setTimeout(function() {
//        renderController.hide(view2);
//        Timer.setTimeout(function() {
//          renderController.show(view1);
//        }, 1000)
//      }, 1000)
//    }, 1000)
//  }, 1000)


});

答案 2 :(得分:1)

一个视图不知道应该将Surfaces分层的顺序。当使用RenderController隐藏某些内容时,它会释放Surface正在管理的文档片段。当该视图返回场景图时,Surfaces将获取一个文档片段,以填充未使用元素池中的内容(如果存在),如果池为空,则会创建新元素。

由于浏览器实现分层的方式,如果新DOM节点存在于Z中的相同变换并且具有相同的CSS zIndex,则新创建的DOM节点存在于旧DOM节点之上。如果需要显式分层,则不应依赖创建顺序。尝试通过添加Modifiers在z空间中转换它们或添加显式CSS zIndexing来表示你的图层应该是什么来解决这个问题。