Why cant we reuse State Modifiers?

心已入冬 提交于 2019-12-08 10:39:47

问题


I am just trying to understand famo.us and wondering why we cant reuse StateModifier instance when the values are the same.

var rotateModifierOne = new StateModifier({
  transform: Transform.rotateZ(Math.PI/4)
});

var rotateModifierTwo = new StateModifier({
  transform: Transform.rotateZ(Math.PI/4)
});

As seen here: http://famo.us/university/famous-101/positioning/4/

Why cant we just do

var mainContext = Engine.createContext();

var translateModifier = new StateModifier({
  transform: Transform.translate(200, 0, 0)
});

var rotateModifier = new StateModifier({
  transform: Transform.rotateZ(Math.PI/4)
});

var redSurface = new Surface({
  size: [100, 100],
  classes: ['red-bg']
});

var greySurface = new Surface({
  size: [100, 100],
  classes: ['grey-bg']
});

mainContext
  .add(translateModifier)
  .add(rotateModifier)
  .add(redSurface);

mainContext
  .add(rotateModifier)
  .add(translateModifier)
  .add(greySurface);

Why do we need separate instances when the values are the same? I am expecting the answer to help me understand how State Modifiers are consumed.


回答1:


StateModifier's are consumed the same as the Modifier object they extend. They are required to have a one to one relationship with their child node. StateModifiers change the state of their child renderable visual changes as stated in the comments.

The reason you need a separate modifier for each node is by design. There is a one to one relationship from a modifier to another node in the tree. This is due to the placement of each modifier (node) to have a parent child relationship.

The functional reason, for not applying a modifier to more than one Renderable at a time, may be for performance reasons and to keep code maintainable. There is a design pattern and best practice that is shown in the examples below to accomplish the answer to the question above. For our purposes, a StateModifier is not really anything more than a Modifier that maintains properties of it's children, so we will not explain the difference here.

A couple facts:

  • There are two types of nodes in the tree, Modifiers and Renderables
  • Each node represents a level of a branch in the tree

In your example you wanted to do the same effect on surface one and surface two:

Take this example first: Two nodes

mainContext.add(translateModifierOne).add(rotateModifierOne).add(redSurface);
mainContext.add(translateModifierTwo).add(rotateModifierTwo).add(greySurface);

It is similar to your example and has two modifier nodes doing the same exact thing by placing the surfaces in the same exact location as each other but rotating different directions with the rotate modifiers.

Now let's look at this example: One node

var myView = new RenderNode();

myView.add(rotateModifierOne).add(redSurface);
myView.add(rotateModifierTwo).add(greySurface);

mainContext.add(translateModifierTwo).add(myView);

It uses one modifier applied to a render node that places the two surfaces in the same exact place. The parent render node (myView) has two nodes attached at the same level and effects both of their placement. It does show how the one to one relationship of modifiers to nodes can be applied to more than one surface by using a render node.

Yet Another example: One node chaining another One

var myView = new RenderNode();

var initialTime = Date.now();
var myState = new Modifier({
    transform: function(){
        return Transform.rotateZ(0.002 * (Date.now() - initialTime));
    }
});
myView.add(redSurface);
myView.add(greySurface);

mainContext.add(translateModifierTwo).add(myState).add(myView);

In this example, we see two modifiers chained together to transition a render node that has two surfaces added. In this case we are applying the same effect to both surfaces using their parent render node. It is hard to see, but they are stacked on top of each other in the same exact location. It kind of translates to how you would set up applying a modifier to two different surfaces. Not really useful, but did get rid of the duplicate modifiers.

Simple fix example: Give each surface it's own modifier

myView.add(rotateModifierOne).add(redSurface);
myView.add(rotateModifierTwo).add(greySurface);

We apply a parent modifier to each of the surfaces to give them their uniqueness in the tree to make their rotation offset by our original modifiers.




回答2:


Seems like that should work and this drove me crazy when I started. I can't say I know what their reasoning behind making it not work is but as I'm sure you saw later in that same lesson they intend you add a modifier to the context or really anything your attaching to and making that a new variable that holds that offset/transform to let you do relative placement.

I can say their method is cleaner and easier to read than seeing the same modifier over and over again. Especially if your using this a lot to give relative based placement. Check this out http://famo.us/guides/render-tree . I also used to git really annoyed with Modifier vs StateModifier, took me awhile to find http://famo.us/guides/layout

    var Engine = require('famous/core/Engine');
    var Surface = require('famous/core/Surface');
    var Transform = require('famous/core/Transform');
    var StateModifier = require('famous/modifiers/StateModifier');

    var mainContext = Engine.createContext();

    mainContext.downMod = new StateModifier({
      transform: Transform.translate(0, 100, 0)
    });

    var leftSurface = new Surface({
      size: [120, 100],
      content: 'left surface',
      properties: {
        color: 'white',
        backgroundColor: '#FA5C4F'
      }
    });

    var rightSurface = new Surface({
      size: [120, 100],
      content: 'right surface',
      properties: {
        color: 'white',
        backgroundColor: '#404040'
      }
    });

    rightSurface.rightMod = new StateModifier({
      transform: Transform.translate(150, 0, 0)
    });

    var node = mainContext.add(mainContext.downMod);

    //Now anything attached to node is actually attached to mainContext with that singular modifier attached

    node.add(leftSurface);
    node.add(rightSurface.rightMod).add(rightSurface);


来源:https://stackoverflow.com/questions/25197689/why-cant-we-reuse-state-modifiers

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