maintain first visible page
This commit is contained in:
parent
920b693a06
commit
c949183bca
|
@ -244,11 +244,20 @@ function Viewer(config) {
|
|||
|
||||
Viewer.prototype = {
|
||||
scale : 1,
|
||||
// index of the active page (most visible one)
|
||||
/*
|
||||
* index of the active page (the one with largest visible area)
|
||||
* which estimates the page currently being viewed
|
||||
*/
|
||||
cur_page_idx : 0,
|
||||
|
||||
/*
|
||||
* index of the first visible page
|
||||
* used when determining current view
|
||||
*/
|
||||
first_page_idx : 0,
|
||||
|
||||
init_before_loading_content : function() {
|
||||
/*hide all pages before loading, will reveal only visible ones later */
|
||||
/* hide all pages before loading, will reveal only visible ones later */
|
||||
this.pre_hide_pages();
|
||||
},
|
||||
|
||||
|
@ -275,6 +284,8 @@ Viewer.prototype = {
|
|||
}
|
||||
|
||||
this.find_pages();
|
||||
// do nothing if there's nothing
|
||||
if(this.pages.length == 0) return;
|
||||
|
||||
// disable dragging of background images
|
||||
disable_dragstart(document.getElementsByClassName(CSS_CLASS_NAMES.background_image));
|
||||
|
@ -293,6 +304,7 @@ Viewer.prototype = {
|
|||
// register schedule rendering
|
||||
// renew old schedules since scroll() may be called frequently
|
||||
this.container.addEventListener('scroll', function() {
|
||||
self.update_page_idx();
|
||||
self.schedule_render(true);
|
||||
}, false);
|
||||
|
||||
|
@ -434,7 +446,6 @@ Viewer.prototype = {
|
|||
|
||||
/*
|
||||
* show visible pages and hide invisible pages
|
||||
* update current page number
|
||||
*/
|
||||
render : function () {
|
||||
var container = this.container;
|
||||
|
@ -469,27 +480,80 @@ Viewer.prototype = {
|
|||
} else {
|
||||
this.load_page(i);
|
||||
}
|
||||
|
||||
if (!cur_page_fully_visible) {
|
||||
// check the visible fraction of the page
|
||||
var page_visible_ratio = (Math.min(container_max_y, page_max_y) - Math.max(container_min_y, page_min_y)) / page_height;
|
||||
if ((i === cur_page_idx) && (Math.abs(page_visible_ratio - 1.0) <= EPS)) {
|
||||
cur_page_fully_visible = true;
|
||||
} else if (page_visible_ratio > max_visible_ratio) {
|
||||
max_visible_ratio = page_visible_ratio;
|
||||
max_visible_page_idx = i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cur_page.hide();
|
||||
}
|
||||
}
|
||||
},
|
||||
/*
|
||||
* update cur_page_idx and first_page_idx
|
||||
* normally called upon scrolling
|
||||
*/
|
||||
update_page_idx: function () {
|
||||
var pages = this.pages;
|
||||
var pages_len = pages.length;
|
||||
// there is no chance that cur_page_idx or first_page_idx is modified
|
||||
if (pages_len < 2) return;
|
||||
|
||||
var container = this.container;
|
||||
var container_min_y = container.scrollTop;
|
||||
var container_max_y = container_min_y + container.clientHeight;
|
||||
|
||||
// binary search for the first page
|
||||
// whose bottom border is below the top border of the container
|
||||
var first_idx = -1;
|
||||
var last_idx = pages_len;
|
||||
var rest_len = last_idx - first_idx;
|
||||
// TODO: use current first_page_idx as a hint?
|
||||
while(rest_len > 1) {
|
||||
var idx = first_idx + Math.floor(rest_len / 2);
|
||||
var cur_page_ele = pages[idx].page;
|
||||
if (cur_page_ele.offsetTop + cur_page_ele.clientTop + cur_page_ele.clientHeight >= container_min_y) {
|
||||
last_idx = idx;
|
||||
} else {
|
||||
first_idx = idx;
|
||||
}
|
||||
rest_len = last_idx - first_idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* update current page number to the maximum visible page
|
||||
* do not update it when current page is still fully visible
|
||||
* with malformed settings it is possible that no page is visible, e.g.
|
||||
* - the container is to thin, which lies in the margin between two pages
|
||||
* - all pages are completely above or below the container
|
||||
* but we just assume that they won't happen.
|
||||
*/
|
||||
if (!cur_page_fully_visible)
|
||||
this.cur_page_idx = max_visible_page_idx;
|
||||
this.first_page_idx = last_idx;
|
||||
|
||||
// find the page with largest visible area
|
||||
var cur_page_idx = this.cur_page_idx;
|
||||
var max_visible_page_idx = cur_page_idx;
|
||||
var max_visible_ratio = 0.0;
|
||||
|
||||
for(var i = last_idx; i < pages_len; ++i) {
|
||||
var cur_page_ele = pages[i].page;
|
||||
var page_min_y = cur_page_ele.offsetTop + cur_page_ele.clientTop;
|
||||
var page_height = cur_page_ele.clientHeight;
|
||||
var page_max_y = page_min_y + page_height;
|
||||
if (page_min_y > container_max_y) break;
|
||||
|
||||
// check the visible fraction of the page
|
||||
var page_visible_ratio = ( Math.min(container_max_y, page_max_y)
|
||||
- Math.max(container_min_y, page_min_y)
|
||||
) / page_height;
|
||||
|
||||
// stay with the current page if it is still fully visible
|
||||
if ((i === cur_page_idx) && (Math.abs(page_visible_ratio - 1.0) <= EPS)) {
|
||||
max_visible_page_idx = cur_page_idx;
|
||||
break;
|
||||
}
|
||||
|
||||
if (page_visible_ratio > max_visible_ratio) {
|
||||
max_visible_ratio = page_visible_ratio;
|
||||
max_visible_page_idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
this.cur_page_idx = max_visible_page_idx;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue