1
0
mirror of https://github.com/pdf2htmlEX/pdf2htmlEX.git synced 2024-12-21 20:50:07 +00:00

maintain currenet page number

This commit is contained in:
Lu Wang 2013-11-11 17:36:35 +08:00
parent f09ede489c
commit 5cb26697a8
2 changed files with 77 additions and 81 deletions

8
TODO
View File

@ -5,20 +5,12 @@ more information on demo page:
- link to other demos - link to other demos
- browser requirements - browser requirements
page idx vs no
tracking current page
pdf:miui pdf:miui
tmp dir: use pid tmp dir: use pid
remove page from dom -- UI option
view hash view hash
- store a separate map/dict for 'original' page number - store a separate map/dict for 'original' page number
- OR adjust all destinations - OR adjust all destinations
issue: separate CSS?
key handler on $container instead of window?
fix get_next/prev_page
next/prev for each Page ?
- dots issue - dots issue
- AdobeXML*.pdf - AdobeXML*.pdf
- font issue - font issue

View File

@ -138,9 +138,9 @@ function Page(page) {
this.loaded = false; this.loaded = false;
this.shown = false; this.shown = false;
this.p = page; // page frame element this.page = page; // page frame element
this.n = get_page_number(page); this.num = get_page_number(page);
// page size // page size
// Need to make rescale work when page_content_box is not loaded, yet // Need to make rescale work when page_content_box is not loaded, yet
@ -201,43 +201,27 @@ Page.prototype = {
// stretch the page frame to hold the place // stretch the page frame to hold the place
{ {
var ps = this.p.style; var ps = this.page.style;
ps.height = (this.original_height * this.cur_scale) + 'px'; ps.height = (this.original_height * this.cur_scale) + 'px';
ps.width = (this.original_width * this.cur_scale) + 'px'; ps.width = (this.original_width * this.cur_scale) + 'px';
} }
}, },
/* return if any part of this page is shown in the container */
is_visible : function() {
var p = this.p;
var pos = this.position();
return !((pos[1] > p.clientHeight) || (pos[1] + p.parentNode.clientHeight < 0));
},
/* return if this page or any neighbor of it is visible */
is_nearly_visible : function() {
var p = this.p;
var pos = this.position();
/*
* I should use the height of the previous page or the next page here
* but since they are not easily available, just use '*2', which should be a good estimate in most cases
*/
return !((pos[1] > p.clientHeight * 2) || (pos[1] + p.parentNode.clientHeight * 2 < 0));
},
/* /*
* return the coordinate of the top-left corner of container * return the coordinate of the top-left corner of container
* in our coordinate system * in our coordinate system
* may or may not work if there are nodes between p.parentNode and p.offsetParent * assuming that p.parentNode == p.offsetParent
*/ */
position : function () { view_position : function () {
var p = this.p; var p = this.page;
var c = p.parentNode; var c = p.parentNode;
return [ c.scrollLeft - p.offsetLeft - p.clientLeft return [c.scrollLeft - p.offsetLeft - p.clientLeft
, c.scrollTop - p.offsetTop - p.clientTop ]; ,c.scrollTop - p.offsetTop - p.clientTop];
}, },
height : function () { height : function () {
return this.p.clientHeight; return this.page.clientHeight;
}, },
width : function () { width : function () {
return this.p.clientWidth; return this.page.clientWidth;
} }
}; };
@ -259,6 +243,7 @@ function Viewer(config) {
Viewer.prototype = { Viewer.prototype = {
scale : 1, scale : 1,
cur_page_idx : 0,
init_before_loading_content : function() { 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 */
@ -325,7 +310,7 @@ Viewer.prototype = {
&& cur_node.classList.contains(CSS_CLASS_NAMES.page_frame)) { && cur_node.classList.contains(CSS_CLASS_NAMES.page_frame)) {
var p = new Page(cur_node); var p = new Page(cur_node);
new_pages.push(p); new_pages.push(p);
new_page_map[p.n] = new_pages.length - 1; new_page_map[p.num] = new_pages.length - 1;
} }
} }
this.pages = new_pages; this.pages = new_pages;
@ -354,12 +339,12 @@ Viewer.prototype = {
var new_loading_indicator = this.loading_indicator.cloneNode(); var new_loading_indicator = this.loading_indicator.cloneNode();
new_loading_indicator.classList.add('active'); new_loading_indicator.classList.add('active');
var cur_page_ele = cur_page.p; var cur_page_ele = cur_page.page;
cur_page_ele.appendChild(new_loading_indicator); cur_page_ele.appendChild(new_loading_indicator);
var url = cur_page_ele.getAttribute('data-page-url'); var url = cur_page_ele.getAttribute('data-page-url');
if (url) { if (url) {
this.pages_loading[idx] = true; // Set semaphore this.pages_loading[idx] = true; // set semaphore
/* closure variables */ /* closure variables */
var _ = this; var _ = this;
@ -390,7 +375,7 @@ Viewer.prototype = {
// replace the old page with loaded data // replace the old page with loaded data
// the loading indicator on this page should also be destroyed // the loading indicator on this page should also be destroyed
var p = _.pages[_idx]; var p = _.pages[_idx];
_.container.replaceChild(new_page, p.p); _.container.replaceChild(new_page, p.page);
p = new Page(new_page); p = new Page(new_page);
_.pages[_idx] = p; _.pages[_idx] = p;
@ -438,23 +423,62 @@ Viewer.prototype = {
/* /*
* show visible pages and hide invisible pages * show visible pages and hide invisible pages
* update current page number
*/ */
render : function () { render : function () {
/* hide (positional) invisible pages */ var container = this.container;
/*
* show the pages that are 'nearly' visible -- it's right above or below the container
*
* all the y values are in the all-page element's coordinate system
*/
var container_min_y = container.scrollTop;
var container_height = container.clientHeight;
var container_max_y = container_min_y + container_height;
var visible_min_y = container_min_y - container_height;
var visible_max_y = container_max_y + container_height;
var cur_page_fully_visible = false;
var cur_page_idx = this.cur_page_idx;
var max_visible_page_idx = cur_page_idx;
var max_visible_ratio = 0.0;
var pl = this.pages; var pl = this.pages;
var pm = this.page_map;
for(var i = 0, l = pl.length; i < l; ++i) { for(var i = 0, l = pl.length; i < l; ++i) {
var p = pl[i]; var cur_page = pl[i];
if(p.is_nearly_visible()){ var cur_page_ele = cur_page.page;
if (p.loaded) { var page_min_y = cur_page_ele.offsetTop + cur_page_ele.clientTop;
p.show(); var page_height = cur_page_ele.clientHeight;
var page_max_y = page_min_y + page_height;
if((page_min_y <= visible_max_y) && (page_max_y >= visible_min_y))
{
// cur_page is 'nearly' visible, show it or load it
if (cur_page.loaded) {
cur_page.show();
} else { } else {
this.load_page(i); 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 { } else {
p.hide(); cur_page.hide();
} }
} }
/*
* update current page number to the maximum visible page
* do not update it when current page is still fully visible
*/
if(!cur_page_fully_visible)
this.cur_page_idx = max_visible_page_idx;
}, },
/** /**
@ -532,7 +556,7 @@ Viewer.prototype = {
break; break;
case 33: // Page UP: case 33: // Page UP:
if (with_alt) { // alt-pageup -> scroll one page up if (with_alt) { // alt-pageup -> scroll one page up
_.scroll_to(_.get_prev_page()); _.scroll_to(_.cur_page_idx - 1);
} else { // pageup -> scroll one screen up } else { // pageup -> scroll one screen up
_.container.scrollTop -= _.container.clientHeight; _.container.scrollTop -= _.container.clientHeight;
} }
@ -540,7 +564,7 @@ Viewer.prototype = {
break; break;
case 34: // Page DOWN case 34: // Page DOWN
if (with_alt) { // alt-pagedown -> scroll one page down if (with_alt) { // alt-pagedown -> scroll one page down
_.scroll_to(_.get_next_page()); _.scroll_to(_.cur_page_idx + 1);
} else { // pagedown -> scroll one screen down } else { // pagedown -> scroll one screen down
_.container.scrollTop += _.container.clientHeight; _.container.scrollTop += _.container.clientHeight;
} }
@ -566,10 +590,6 @@ Viewer.prototype = {
}, false); }, false);
}, },
// TODO
get_next_page : function() { return null; },
get_prev_page : function() { return null; },
/** /**
* @param{number} ratio * @param{number} ratio
* @param{boolean} is_relative * @param{boolean} is_relative
@ -582,7 +602,7 @@ Viewer.prototype = {
rescale : function (ratio, is_relative, offsetX, offsetY) { rescale : function (ratio, is_relative, offsetX, offsetY) {
var old_scale = this.scale; var old_scale = this.scale;
var new_scale = 1.0; var new_scale = 1.0;
// Set new scale // set new scale
if (ratio == 0) { if (ratio == 0) {
new_scale = 1; new_scale = 1;
is_relative = false; is_relative = false;
@ -600,7 +620,7 @@ Viewer.prototype = {
offsetY = 0; offsetY = 0;
// Save offset of the active page // Save offset of the active page
var active_page = this.get_active_page(); var active_page = this.pages[this.cur_page_idx];
if(!active_page) return; if(!active_page) return;
var active_page_ele = active_page.p; var active_page_ele = active_page.p;
@ -629,29 +649,15 @@ Viewer.prototype = {
}, },
fit_width : function () { fit_width : function () {
var active_page = this.get_active_page(); var page_idx = this.cur_page_idx;
if(!active_page) return; this.rescale(this.container.clientWidth / this.pages[page_idx].width(), false);
this.scroll_to(page_idx, [0,0]);
this.rescale(this.container.clientWidth / active_page.width(), false);
this.scroll_to(this.page_map[active_page.n], [0,0]);
}, },
fit_height : function () { fit_height : function () {
var active_page = this.get_active_page(); var page_idx = this.cur_page_idx;
if(!active_page) return; this.rescale(this.container.clientHeight / this.pages[page_idx].height(), false);
this.scroll_to(page_idx, [0,0]);
this.rescale(this.container.clientHeight / active_page.height(), false);
this.scroll_to(this.page_map[active_page.n], [0,0]);
},
// TODO: preserve active_page idx after rescaling
get_active_page : function () {
var pl = this.pages;
for(var i = 0, l = pl.length; i < l; ++i) {
if (pl[i].is_visible())
return pl[i];
}
return null;
}, },
/** /**
* @param{Node} ele * @param{Node} ele
@ -686,7 +692,7 @@ Viewer.prototype = {
var cur_page = this.get_containing_page(target); var cur_page = this.get_containing_page(target);
if(cur_page) if(cur_page)
{ {
cur_pos = cur_page.position(); cur_pos = cur_page.view_position();
//get the coordinates in default user system //get the coordinates in default user system
cur_pos = transform(cur_page.ictm, [cur_pos[0], cur_page.height()-cur_pos[1]]); cur_pos = transform(cur_page.ictm, [cur_pos[0], cur_page.height()-cur_pos[1]]);
} }
@ -779,21 +785,19 @@ Viewer.prototype = {
* @param{Array.<number>=} pos [x,y] in UNSCALED COORDINATION, where (0,0) is the top-left corner * @param{Array.<number>=} pos [x,y] in UNSCALED COORDINATION, where (0,0) is the top-left corner
*/ */
scroll_to : function(page_idx, pos) { scroll_to : function(page_idx, pos) {
var target_page = this.pages[page_idx]; var pl = this.pages;
if(target_page === undefined) return; if((page_idx < 0) || (page_idx >= pl.length)) return;
var target_page = pl[page_idx];
var cur_target_pos = target_page.view_position();
if(pos === undefined) if(pos === undefined)
pos = [0,0]; pos = [0,0];
var cur_target_pos = target_page.position();
var container = this.container; var container = this.container;
var scale = this.scale; var scale = this.scale;
container.scrollLeft += pos[0] * scale - cur_target_pos[0]; container.scrollLeft += pos[0] * scale - cur_target_pos[0];
container.scrollTop += pos[1] * scale - cur_target_pos[1]; container.scrollTop += pos[1] * scale - cur_target_pos[1];
}, }
__last_member__ : 'no comma' /*,*/
}; };
pdf2htmlEX['Viewer'] = Viewer; pdf2htmlEX['Viewer'] = Viewer;