1

初心者の質問です。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 は 1 回目のように背景の上に描画する必要がありますか?

これは期待されていますか?私は何か間違っていますか?私は何かが足りないのですか?

- - - - 編集 - - -

私のコード(おおよそ):

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 を見ると、フリップが表示されます。

ランディング画面の最初の表示: 背景、次にスクロールビューとその 6 つの要素

ランディング画面の最初の表示: 背景、次にスクロールビューとその 6 つの要素

ランディング画面の 2 番目の表示: scrollview とその 6 つの要素、そして背景です。

ランディング画面の 2 番目の表示: scrollview とその 6 つの要素、次に背景

4

3 に答える 3

1

View は、Surface をレイヤー化する順序を認識していません。RenderController で何かを非表示にすると、Surface が管理しているドキュメント フラグメントが解放されます。そのビューがシーン グラフに戻されると、サーフェスはドキュメント フラグメントを取得して未使用の要素のプールからそのコンテンツを埋めます (存在する場合)。プールが空の場合は、新しい要素を作成します。

ブラウザーがレイヤー化を実装する方法により、新しく作成された DOM ノードは、Z の同じ変換に存在し、同じ CSS zIndex を持つ場合、古い DOM ノードの上に存在します。明示的なレイヤリングが必要な場合は、作成順序に依存しないでください。Modifiers を追加して z 空間で変換するか、明示的な CSS zIndexing を追加して、レイヤーがどうあるべきかを示すことで、これを回避してみてください。

于 2014-05-11T20:27:27.410 に答える
1

要素のオーバーラップは、レンダリング ツリーに追加された順序に対応していると読みました

私が見たところ、要素のオーバーラップは、レンダー ツリーへの追加ではなく、作成順序の逆 (たとえば、最後の 1 つを一番上にする) によって設定されます。

Surface が作成されると、httpsEntity : //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);
    ....
}

2 つの を作成し、2 番目に作成したものを最初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前面にある理由を理解すると役立ちます.

于 2014-05-10T21:41:17.967 に答える
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)


});
于 2014-05-11T15:49:36.327 に答える