Famo.us ScrollView可以像聊天界面一样滚动

3
我有一个 ScrollView,其中包含一系列表面元素。我希望在新元素出现时就能将其滚动到最新的位置。
这是一个演示,我希望它像任何聊天应用程序一样滚动...旧的表面超出了场景,而新的表面始终位于底部。问题与此处相同:Famo.us如何使ScrollView从底部填充(或从右到左)? http://jsfiddle.net/LA49a/
Famous.loaded(function () {
    var Engine = Famous.Core.Engine;
    var Surface = Famous.Core.Surface;
    var Scrollview = Famous.Views.Scrollview;
    var Timer = Famous.Utilities.Timer;

    var mainContext = Engine.createContext();

    var scrollview = new Scrollview();
    var surfaces = [];
    var i = 0;

    scrollview.sequenceFrom(surfaces);

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

        temp.pipe(scrollview);
        surfaces.push(temp);
        i++;
        // scrollview.goToNextPage();
    }, 400);

    mainContext.add(scrollview);
});
4个回答

1

1
我假设您输入了一个非常大的、圆形的数字,以便让滚动视图移动到末尾,这样就可以显示您的“最新”元素。
如果您有相同宽度的表面(假设滚动视图的X方向),您可能会通过检查实际需要移动的像素数量来使结果更加平滑,以将最后一个项目定位在滚动视图的右边缘。您有原始数组,您在其中运行了sequenceFrom()。将该数组中的项目数乘以表面宽度,并减去滚动视图的宽度的像素(如果设置为“未定义”,则需要查看窗口的宽度)以调整将最新元素放置在滚动视图的右侧而不是左侧。
如果您的表面大小不同,您可以通过在将它们添加到备份数组时跟踪每个表面的x偏移量来更改内容,只需向表面添加一个属性即可。然后,您可以询问表面其偏移量并减去滚动视图宽度的正确数量。
希望这能帮助您更接近目标。

嗨!谢谢回复!是的,我正在使用 scrollView.setPosition(20000)。问题是当将表面放置到序列中时,如何计算偏移量,因为它尚未呈现。并且据我所知,在获取表面的偏移量之后,我需要执行类似于这样的操作:scrollView.setPosition(surface.offset - scrollview.height),对吗? :) - Iurii Tkachenko
1
从你的问题中,我担心可能没有好的答案。但也许更多的信息会有所帮助。当您创建每个表面时,您为“size”数组选项设置了什么? - Dan Zaner

0

问题解决了,通过将ScrollView旋转180度,并将其中所有表面也旋转180度http://jsfiddle.net/tamtamchik/LA49a/3/

Famous.loaded(function () {
    var Engine = Famous.Core.Engine;
    var Surface = Famous.Core.Surface;
    var Scrollview = Famous.Views.Scrollview;
    var Timer = Famous.Utilities.Timer;
    var Transform = Famous.Core.Transform;
    var StateModifier = Famous.Modifiers.StateModifier;
    var ContainerSurface = Famous.Surfaces.ContainerSurface;

    var mainContext = Engine.createContext();

    var scrollview = new Scrollview();
    var surfaces = [];
    var i = 0;
    var surfaceHeight = 50;

    scrollview.sequenceFrom(surfaces);

    Timer.setInterval(function () {
        var container = new ContainerSurface({
            size: [undefined, surfaceHeight]
        });

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

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

        var surfacePush = new StateModifier({
            transform: Transform.translate(window.innerWidth, surfaceHeight)
        });

        container.add(surfacePush).add(surfaceRotate).add(temp);
        container.pipe(scrollview);
        temp.pipe(scrollview);
        surfaces.unshift(container);
        i++;
    }, 400);

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

    var push = new StateModifier({
        transform: Transform.translate(window.innerWidth, window.innerHeight)
    });

    mainContext.add(push).add(rotate).add(scrollview);
});

0

嗯,这很巧妙!如果在这些节点中有大量文本内容,那么这将是一些额外的矩阵,可能会变得非常缓慢...

通过使用一个巨大的数字,这只是为了强制famo.us滚动到视图的末尾,我猜测?

如果渲染已经发生,你也可以:

pos = getPosition(nodeNum)  // for last elements scrollposition
setPosition(pos)

但是,如果插入发生在与您的移动控制相同的代码块中,则尚未呈现。

这里提供了一个复杂的解决方法,使用事件触发大小计算,以在部署/呈现后进行: 如何在famo.us中获取表面的大小?

还有另一个技巧,可以让著名的@johntraver重新计算大小 如何使famo.us重新计算大小?

您是否也看过Engine.nextTick()或JQuery.deferred? 似乎在插入内容后立即会出现“未呈现”的瞬间,但在更新后,您可以获得正确的大小。


1
setPosition的效果不太稳定。如果你一次在屏幕上显示的内容太多,它可能会被截断,只能滚动部分距离。我曾经使用一个带有滑块类型滚动视图的应用程序,在慢速运行时只需要几分钟就会出现问题,无法完全滚动到底部。 - aintnorest

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接