AverageJoe
AverageJoe

Reputation: 15

Resizing multiple surfaces in a Scrollview

Another famo.us beginner question...

My question relates to this question and johntraver's excellent answer (provided below). I've been playing around with this for a bit, and I can't figure out how to access the other surfaces in the Scrollview when one is clicked.

For example, I'd like to re-size both 'Surface 2' AND 'Surface 3' when 'Surface 2' is clicked.

I've looked at the guides, examples, etc., and my confusion is with the RenderNode. I'm not entirely clear on the purpose it serves.

Thanks in advance for the help.

var Engine              = require("famous/core/Engine");
var Surface             = require("famous/core/Surface");
var RenderNode          = require("famous/core/RenderNode");
var Modifier            = require("famous/core/Modifier");

var Scrollview          = require("famous/views/Scrollview");
var Transitionable      = require("famous/transitions/Transitionable");
var SnapTransition      = require("famous/transitions/SnapTransition");

Transitionable.registerMethod('snap', SnapTransition);

var snap = { method: 'snap', period: 600, dampingRatio: 0.6 }

var mainContext = Engine.createContext();

var scrollview = new Scrollview();

var surfaces = [];

scrollview.sequenceFrom(surfaces);

for (var i = 0; i < 20; i++) {

    var surface = new Surface({
    content: "Surface: " + (i + 1),
    size: [undefined, undefined],
    properties: {
        backgroundColor: "hsl(" + (i * 360 / 40) + ", 100%, 50%)",
        lineHeight: "200px",
        textAlign: "center"
    }
    });

    surface.open = false;

    surface.state = new Modifier();

    surface.trans = new Transitionable(200);

    surface.state.sizeFrom(function(){
    return [undefined, this.trans.get()];
    }.bind(surface));

    surface.node = new RenderNode();

    surface.node.add(surface.state).add(surface);

    surface.pipe(scrollview);

    surface.on('click',function(e){
    if (this.open) {
        this.trans.halt();
        this.trans.set(200,snap);
    } else {
        this.trans.halt();
        this.trans.set(400,snap);
    }
    this.open = !this.open;

    }.bind(surface));

    surfaces.push(surface.node);
}

mainContext.add(scrollview);

Upvotes: 0

Views: 133

Answers (1)

talves
talves

Reputation: 14353

Think of the RenderNode as the view of the items being added to the scrollview. In the example, @johntraver is storing references to his node and surface modifiers onto the surface. This may be confusing you a bit. Although it is fine, we will need to use node (item) as our reference point. Also, the render node item purpose is to allow us to have a node branch where we have multiple items.

I changed the example to make it a little more accessible to be able to get to the surfaces stored in the items (views). I am now calling the surfaces collection views to help us understand what we are passing to the scrollview for rendering. Instead a RenderNode (node) is holding the reference to our surface as properties, so we can later access the surfaces.

Here is a running example on jsBin.

Building our view

Note: I moved the functions out of the loop, for easier reading.

  for (var i = 0; i < 20; i++) {

    var node = new RenderNode();

    node.surface = new Surface({
      content: "Surface: " + (i + 1),
      size: [undefined, undefined],
      properties: {
        backgroundColor: "hsl(" + (i * 360 / 40) + ", 100%, 50%)",
        lineHeight: "200px",
        textAlign: "center"
      }
    });

    node.surface.open = false;

    node.surface.state = new Modifier();

    node.surface.trans = new Transitionable(200);

    node.surface.state.sizeFrom(_surfaceSize.bind(node.surface));

    // Add the modifier and the surface to our view    
    node.add(node.surface.state).add(node.surface);

    node.surface.pipe(scrollview);

    node.surface.on('click', _resize.bind(node.surface, i, views));

    views.push(node);
  }

Function to access our multiple views and resize

  function _resize(index, views, event){
    console.log(index, views, event);
    next = index+1 < views.length ? views[index+1].surface : views[0].surface;
    if (this.open) {
      this.trans.halt();
      this.trans.set(200, snap);
      next.trans.halt();
      next.trans.set(200, snap);
    } else {
      this.trans.halt();
      this.trans.set(400, snap);
      next.trans.halt();
      next.trans.set(400, snap);
    }
    this.open = !this.open;
    next.open = this.open;

  }

The full code

  var Engine              = require("famous/core/Engine");
  var Surface             = require("famous/core/Surface");
  var RenderNode          = require("famous/core/RenderNode");
  var Modifier            = require("famous/core/Modifier");

  var Scrollview          = require("famous/views/Scrollview");
  var Transitionable      = require("famous/transitions/Transitionable");
  var SnapTransition      = require("famous/transitions/SnapTransition");

  Transitionable.registerMethod('snap', SnapTransition);

  var snap = { method: 'snap', period: 600, dampingRatio: 0.6 };

  var mainContext = Engine.createContext();

  var scrollview = new Scrollview();

  var views = [];

  scrollview.sequenceFrom(views);

  function _resize(index, views, event){
    console.log(index, views, event);
    next = index+1 < views.length ? views[index+1].surface : views[0].surface;
    if (this.open) {
      this.trans.halt();
      this.trans.set(200, snap);
      next.trans.halt();
      next.trans.set(200, snap);
    } else {
      this.trans.halt();
      this.trans.set(400, snap);
      next.trans.halt();
      next.trans.set(400, snap);
    }
    this.open = !this.open;
    next.open = this.open;

  }

  function _surfaceSize(){
    return [undefined, this.trans.get()];
  }

  for (var i = 0; i < 20; i++) {

    var node = new RenderNode();

    node.surface = new Surface({
      content: "Surface: " + (i + 1),
      size: [undefined, undefined],
      properties: {
        backgroundColor: "hsl(" + (i * 360 / 40) + ", 100%, 50%)",
        lineHeight: "200px",
        textAlign: "center"
      }
    });

    node.surface.open = false;

    node.surface.state = new Modifier();

    node.surface.trans = new Transitionable(200);

    node.surface.state.sizeFrom(_surfaceSize.bind(node.surface));

    node.add(node.surface.state).add(node.surface);

    node.surface.pipe(scrollview);

    node.surface.on('click', _resize.bind(node.surface, i, views));

    views.push(node);
  }

  mainContext.add(scrollview);

Upvotes: 1

Related Questions