0

In my context I have a scroll view, and I'm trying to position the child elements within the view using origin/align properties in a state modifier. However for some reason, when I scroll to the bottom, the last surface isn't displayed correctly.

I can see this is because I'm using origin/align but I'm not sure on the correct way to position child elements within a scroll view? If someone could point me in the right direction that would be great.

Thanks

Code: main.js

// Create the main context
var mainContext = Engine.createContext();

// Create scroll view 
var scrollView = new Scrollview();
var surfaces = [];
scrollView.sequenceFrom(surfaces);

// Create logo
var logoNode = new RenderNode();

var logo = new ImageSurface({
    size: [150, 112],
    content: 'img/logo.png',
    classes: ['logo']
});

// Center logo within context, center and set opacity
var modifier = new StateModifier({
    align: [0.5, 0.05],
    origin: [0.5, 0.05],
});

logoNode.add(modifier).add(logo);
logo.pipe(scrollView);
surfaces.push(logoNode);

var tribesLength = Object.keys(tribes).length;

for (var t = 0; t < tribesLength; t++) {
    var tribe = new TribesView({tribes: tribes, tribe: t});

    tribe.pipe(scrollView);
    surfaces.push(tribe);
}

mainContext.add(scrollView);

TribesView.js

function TribesView() {
    View.apply(this, arguments);

    _displayTribe.call(this);
}

TribesView.prototype = Object.create(View.prototype);
TribesView.prototype.constructor = TribesView;

TribesView.DEFAULT_OPTIONS = {
    tribes: {},
    tribe: 0,
};

function _displayTribe() {
    var tribes = this.options.tribes;
    var tribe = this.options.tribe;

    var node = new RenderNode();

    var surface = new Surface({
        size: [, 100],
        content: tribes[tribe]['name'],
        properties: {
            background: tribes[tribe]['bg'],
            color: 'blue'
        }
    });

    var modifier = new StateModifier({
        origin: [0, 0.1],
        align: [0, 0.1]
    });

    node.add(modifier).add(surface);
    surface.pipe(this._eventOutput);
    this.add(node);
}

module.exports = TribesView;

1 Answers1

0

The problem comes as you suspected, from the use of..

var modifier = new StateModifier({
    origin: [0, 0.1],
    align: [0, 0.1]
});

in the _displayTribe function. You have to remember that TribeView although labeled a view is nothing representative of something visual on screen. That means when you add this modifier to a surface inside a view, view thinks it is one place, which will be laid out in scrollview, and the modifier will put it in another place (in your case too low on screen).

It is difficult to give you a clear example, because I do not have the data or images or anything to make this look halfway good. If you want to use modifiers within your TribeViews, take a look at chain modifier. I have found it helpful for creating a sort of container surface without using a containerSurface.

Here is what I did to _displayTribe to give the content text an offset relative to the view..

function _displayTribe() {
    var tribes = this.options.tribes;
    var tribe = this.options.tribe;

    var surface = new Surface({
        size: [undefined, 100],
        properties: {
            color: 'blue',
            border:'1px solid black'
        }
    });

    this.add(surface)

    var text = new Surface({
        size:[undefined,true],
        content: "Helloo",
    })

    chain = new ModifierChain()

    var containerModifier = new StateModifier({
        size: [undefined, 100],
    });

    var modifier = new StateModifier({
        origin: [0, 0.1],
        align: [0, 0.1]
    });


    chain.addModifier(modifier)
    chain.addModifier(containerModifier)

    this.add(chain).add(text);

    surface.pipe(this._eventOutput);
}

I removed anything 'asset' related since it was not available to me. The first surface I added to the view completely unmodified. This allows us to see where scrollview is placing our view. For the text surface, I am using true sizing, and creating a ModifierChain to simulate the container as I previously mentioned. You do this by defining two modifiers, one for the size of the container, and the other for positioning in the container, then chain them together.

Lots of information, Hope this helps!

johntraver
  • 3,612
  • 18
  • 17
  • Hi John, thanks for your reply. I have just tried what you suggested but I can't seem to get it working... I'm getting to the end of my tether with this! I have tried everything in my limited knowledge of famo.us to position these surfaces (not just the text) literally 20 pixels down yet every single time the last surface is positioned off the screen. Is there anything else we can try? – Peter Allen Jun 24 '14 at 19:03
  • Oh sorry, see you say not just the text.. Why don't you add a 20px placeholder surface at the top? – johntraver Jun 24 '14 at 19:45
  • I figured this out, although your solution is much simpler than mine, I'm not sure why I didn't think of that! I appreciate the help. – Peter Allen Jun 25 '14 at 20:03