2014-04-21 48 views
1

我想在famo.us中構建粘滯滾動視圖,並且我陷入兩處。在famo.us中構建粘滯滾動視圖

1)身體在標題頂部滾動。當我添加一個Transform.translate(0,0,1)到標題中之前,它將它添加到_mainScrollview它什麼都不做。

2)_mainScrollview卡住時,我如何保持_bodyScrollview的速度?

/*** 
* A view that scrolls, sticks the header at stickAt, 
* and then allows the body to scroll. 
*/ 
function Sticky(options) { 
    View.apply(this, arguments); 

    options = options || {}; 

    this.options = Object.create(Sticky.DEFAULT_OPTIONS); 
    for (var i in Sticky.DEFAULT_OPTIONS) { 
     if (options[i] !== undefined) this.options[i] = options[i]; 
    } 

    // setup the scrollviews 

    this._bodyScrollview = new Scrollview({}); 
    this._bodyScrollview.sequenceFrom([this.options.body]); 

    this._mainScrollview = new Scrollview({}); 
    this._mainScrollview.sequenceFrom([this.options.header, this._bodyScrollview]); 
    this._eventInput.pipe(this._mainScrollview); 

    // track the velocities 

    this._mainScrollview.sync.on('update', function (data) { 
     this._mainVelocity = data.velocity; 
    }.bind(this)); 

    this._bodyScrollview.sync.on('update', function (data) { 
     this._bodyVelocity = data.velocity; 
    }.bind(this)); 

    this.add(this._mainScrollview); 
} 

Sticky.prototype.render = function() { 
    // If the main scrollview is scrolled up (velocity < 0) 
    // past the stickAt point, stick it and unstick the body scrollview. 
    if (this._mainVelocity < 0) { 
     if (this._mainScrollview.getPosition() >= this.options.stickAt) { 
      this._eventInput.unpipe(this._mainScrollview); 
      this._eventInput.pipe(this._bodyScrollview); 

      Tools.forcePosition(this._mainScrollview, this.options.stickAt, true); 

      this._mainVelocity = 0; 
     } 
    } 

    // If the main scrollview is scrolled down (velocity > 0) 
    // past 0, stick it and unstick the main scrollview. 
    if (this._bodyVelocity > 0) { 
     console.log(this._bodyScrollview.getPosition()); 
     if (this._bodyScrollview.getPosition() <= 0) { 
      this._eventInput.unpipe(this._bodyScrollview); 
      this._eventInput.pipe(this._mainScrollview); 

      Tools.forcePosition(this._bodyScrollview, 0, true); 

      this._bodyVelocity = 0; 
     } 
    } 

    return View.prototype.render.call(this); 
}; 

/** 
* Force a scrollview to a position 
*/ 
Tools.forcePosition = function (scrollview, position, noSpring) { 
    if (noSpring) { 
     scrollview._springState = 0; 
     scrollview._physicsEngine.detachAll(); 
    } 

    scrollview.setVelocity(0); 
    scrollview.setPosition(position);  
}; 
+1

來源位於http://github.com/famous/famous,文檔位於https://famo.u s/docs – jonperl

回答

0

1)我懷疑你的標題大小是錯誤的,並與主滾動內容重疊。使用檢查器檢查並根據需要修改大小。 (請參閱Famo.us Common pitfalls: Why am I not getting this click?

2)訂閱滾動條的edgeHit事件並手動設置速度(就像您在停止滾動條時所做的那樣)。

BTW,而不是有這個

ScrollView 
    HeaderSurface 
    ScrollView 
     Content 

我會佈置這樣的:

HeaderSurface 
ScrollView 
    HeaderSurface 
    Content1 
    Content2 
    Content3 

因此單個HeaderSurface在RenderTree引用了兩次。所以我會克隆HeaderSurface,如果你滾動過某個點,你會顯示第一個(粘滯的)HeaderSurface。這與第二個(滾動查看的)HeaderSurface重疊。

+0

1)在safari中工作。我猜測它與Chrome中的交叉曲面錯誤有關https://famo.us/guides/dev/pitfalls.html – jonperl

+0

對於未來的觀衆,在兩棵樹中添加RenderNode似乎不起作用。 – jonperl

0

1)原來這是Chrome的一個問題,它適用於Safari瀏覽器。解決方法是在主體之後創建標題。

2)繞過速度被證明是困難和複雜的 - 當我將頭部粘住時,身體會反彈,因爲它位於相同的滾動視圖內。

我重建視圖使用一個滾動視圖與表示標題的填充節點。然後我根據滾動視圖的位置手動轉換標題。

HeaderSurface 
BodyScrollview 
    HeaderFiller 
    BodySurface 

下面是代碼:

/*** 
* A view that scrolls sticks the header at stickHeaderAt 
* and allows the body to scroll underneath the header. 
*/ 
function Sticky(options) { 
    View.apply(this, arguments); 

    options = options || {}; 

    this.options = Object.create(Sticky.DEFAULT_OPTIONS); 
    for (var i in Sticky.DEFAULT_OPTIONS) { 
     if (options[i] !== undefined) this.options[i] = options[i]; 
    } 

    // Setup the body scrollview. 

    // Add a filler node to represent the header. 
    // In render we will manually transform the header depending on where the scrollview is. 
    var headerFiller = new RenderNode(new Modifier({ 
     size: this.options.header.getSize() 
    })); 
    headerFiller.add(new Surface); 

    this._bodyScrollview = new Scrollview({}); 
    this._bodyScrollview.sequenceFrom([headerFiller, this.options.body]); 

    this.add(this._bodyScrollview); 

    this._eventInput.pipe(this._bodyScrollview); 

    // Create a wrapping container surface for the header after 
    // the body as a workaround of a bug where chrome does not 
    // respect our transform on the header. 

    var headerContainer = new ContainerSurface({ 
     size: this.options.header.getSize(), 
     transform: Transform.translate(0, 0, 1) 
    }); 
    headerContainer.add(this.options.header); 

    // Setup the header node. 

    // Transform the header on top of the body (broken in chrome). 
    this._headerModifier = new StateModifier({ 
     transform: Transform.translate(0, 0, 1) 
    }); 
    var headerNode = new RenderNode(this._headerModifier); 
    headerNode.add(headerContainer); 

    this.add(headerNode); 
} 

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

Sticky.DEFAULT_OPTIONS = { 
    header: null, 
    body: null, 
    stickHeaderAt: 0 
}; 

Sticky.prototype.render = function() { 
    // If the body scrollview is on the first page handle sticking/unsticking the header. 
    // Otherwise the body is scrolled up enought that the header is already stuck, so ignore it. 
    if (this._bodyScrollview._node.getNext()) { 
     var scrollviewPosition = this._bodyScrollview.getPosition(); 

     // Stop the header when the scrollview hits stickHeaderAt. 
     if (scrollviewPosition > this.options.stickHeaderAt) { 
      this._headerModifier.setTransform(Transform.translate(0, -1 * this.options.stickHeaderAt, 1)); 
     } 
     // When the scrollview is below the stickHeaderAt point 
     // move the header with the scrollview. 
     else { 
      this._headerModifier.setTransform(Transform.translate(0, -1 * scrollviewPosition, 1)); 
     } 
    } 

    return View.prototype.render.call(this); 
}; 

/** 
* Reset the header and body to the top. 
*/ 
Sticky.prototype.reset = function() { 
    this._headerModifier.setTransform(Transform.translate(0, 0, 1)); 

    this._bodyScrollview.goToPreviousPage(); 
    Tools.forcePosition(this._bodyScrollview, 0, true); 
};