FIX: Better handling of position when near the top or bottom

This commit is contained in:
Robin Ward 2016-05-27 12:35:16 -04:00
parent a3907e1fbb
commit 0b8a3ff5da
No known key found for this signature in database
GPG Key ID: 0E091E2B4ED1B83D
5 changed files with 42 additions and 20 deletions

View File

@ -88,11 +88,6 @@ export default MountWidget.extend({
const offset = offsetCalculator(); const offset = offsetCalculator();
const topCheck = Math.ceil(windowTop + offset); const topCheck = Math.ceil(windowTop + offset);
if (windowTop < offset) {
currentPost = 0;
const $post = $($posts[0]);
percent = windowTop > 0 ? (topCheck - $post.offset().top) / $post.height() : 0;
}
// uncomment to debug the eyeline // uncomment to debug the eyeline
// $('.debug-eyeline').css({ height: '1px', width: '100%', backgroundColor: 'blue', position: 'absolute', top: `${topCheck}px` }); // $('.debug-eyeline').css({ height: '1px', width: '100%', backgroundColor: 'blue', position: 'absolute', top: `${topCheck}px` });
@ -106,15 +101,15 @@ export default MountWidget.extend({
const viewTop = $post.offset().top; const viewTop = $post.offset().top;
const postHeight = $post.height(); const postHeight = $post.height();
const viewBottom = viewTop + postHeight; const viewBottom = Math.ceil(viewTop + postHeight);
if (viewTop > viewportBottom) { break; } if (viewTop > viewportBottom) { break; }
if (viewBottom > windowTop && viewTop <= windowBottom) { if (viewBottom >= windowTop && viewTop <= windowBottom) {
onscreen.push(bottomView); onscreen.push(bottomView);
} }
if (currentPost === null && (viewTop <= topCheck) && (viewBottom > topCheck)) { if (currentPost === null && (viewTop <= topCheck) && (viewBottom >= topCheck)) {
percent = (topCheck - viewTop) / postHeight; percent = (topCheck - viewTop) / postHeight;
currentPost = bottomView; currentPost = bottomView;
} }
@ -163,9 +158,13 @@ export default MountWidget.extend({
this.sendAction('currentPostChanged', { post }); this.sendAction('currentPostChanged', { post });
} }
if (percent !== null && this._currentPercent !== percent) { if (percent !== null) {
this._currentPercent = percent; if (percent > 1.0) { percent = 1.0; }
this.sendAction('currentPostScrolled', { percent });
if (this._currentPercent !== percent) {
this._currentPercent = percent;
this.sendAction('currentPostScrolled', { percent });
}
} }
} else { } else {

View File

@ -211,7 +211,7 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, {
currentPostScrolled(event) { currentPostScrolled(event) {
this.appEvents.trigger('topic:current-post-scrolled', { this.appEvents.trigger('topic:current-post-scrolled', {
postNumber: this._progressIndex, postIndex: this._progressIndex,
percent: event.percent percent: event.percent
}); });
}, },

View File

@ -1,8 +1,26 @@
export default function offsetCalculator() { export default function offsetCalculator() {
const $header = $('header'); const $header = $('header');
const $title = $('#topic-title'); const $title = $('#topic-title');
const windowHeight = $(window).height() - $title.height(); const rawWinHeight = $(window).height();
const windowHeight = rawWinHeight - $title.height();
const expectedOffset = $title.height() - $header.find('.contents').height() + (windowHeight / 5); const expectedOffset = $title.height() - $header.find('.contents').height() + (windowHeight / 5);
const ideal = $header.outerHeight(true) + ((expectedOffset < 0) ? 0 : expectedOffset);
return $header.outerHeight(true) + ((expectedOffset < 0) ? 0 : expectedOffset); const $container = $('.posts-wrapper');
const topPos = $container.offset().top;
const scrollTop = $(window).scrollTop();
const docHeight = $(document).height();
const scrollPercent = (scrollTop / (docHeight-rawWinHeight));
const inter = topPos - scrollTop + ($container.height() * scrollPercent);
if (inter > ideal) {
const bottom = $('#topic-bottom').offset().top;
if (bottom > (scrollTop + rawWinHeight)) {
return ideal;
}
}
return inter;
} }

View File

@ -8,10 +8,15 @@ export default Ember.Mixin.create({
init() { init() {
this._super(); this._super();
this.queueDockCheck = () => { this.queueDockCheck = () => {
Ember.run.debounce(this, this.dockCheck, helper, 5); Ember.run.debounce(this, this.safeDockCheck, 5);
}; };
}, },
safeDockCheck() {
if (this.isDestroyed || this.isDestroying) { return; }
this.dockCheck(helper);
},
didInsertElement() { didInsertElement() {
this._super(); this._super();

View File

@ -96,7 +96,7 @@ createWidget('timeline-scrollarea', {
const topic = attrs.topic; const topic = attrs.topic;
const postStream = topic.get('postStream'); const postStream = topic.get('postStream');
const total = postStream.get('filteredPostsCount'); const total = postStream.get('filteredPostsCount');
let current = Math.floor(total * percentage); let current = Math.floor(total * percentage) + 1;
if (current < 1) { current = 1; } if (current < 1) { current = 1; }
if (current > total) { current = total; } if (current > total) { current = total; }
@ -168,15 +168,15 @@ createWidget('timeline-scrollarea', {
}, },
topicCurrentPostScrolled(event) { topicCurrentPostScrolled(event) {
const { postNumber, percent } = event; const { postIndex, percent } = event;
// If the post number didn't change keep our scroll position // If the post number didn't change keep our scroll position
this.state.percentage = this._percentFor(this.attrs.topic, parseFloat(postNumber) + percent); this.state.percentage = this._percentFor(this.attrs.topic, parseFloat(postIndex) + percent);
}, },
_percentFor(topic, postNumber) { _percentFor(topic, postIndex) {
const total = topic.get('postStream.filteredPostsCount'); const total = topic.get('postStream.filteredPostsCount');
let result = (postNumber === 1) ? 0.0 : parseFloat(postNumber) / total; let result = parseFloat(postIndex - 1.0) / total;
if (result < 0) { return 0.0; } if (result < 0) { return 0.0; }
if (result > 1.0) { return 1.0; } if (result > 1.0) { return 1.0; }