lazy load with deferrered scroll_to

This commit is contained in:
Michele Redolfi 2013-06-12 17:53:14 +02:00
parent dd41565c3c
commit d5ade42d5a
3 changed files with 102 additions and 37 deletions

View File

@ -1,5 +1,6 @@
Developing v0.9
* Lazy loading of entire pages
* Licensed changed
- Additional terms for usage in online services
- Remove GPLv2

View File

@ -49,7 +49,7 @@ pdf2htmlEX.defaultViewer = new pdf2htmlEX.Viewer({
<body>
"""
# The sidbar
# The sidebar
# By default this is hidden, pdf2htmlEX.js will add the 'opened' class if it is not empty
# You can add a class 'opened' here if you want it always opened or you don't use pdf2htmlEX.js
# e.g.

136
share/pdf2htmlEX.js.in Normal file → Executable file
View File

@ -18,6 +18,9 @@ var pdf2htmlEX = (function(){
link : '@CSS_LINK_CN@',
__dummy__ : 'no comma'
};
var PAGES_TO_PRELOAD = 3;
var pages_loading = {};
var pdf2htmlEX = new Object();
@ -40,24 +43,36 @@ var pdf2htmlEX = (function(){
var Page = function(page, container) {
if(page == undefined) return;
this.loaded = false;
this.p = $(page);
this.container = container;
this.n = parseInt(this.p.attr('data-page-no'), 16);
this.b = $('.'+CSS_CLASS_NAMES['page_content_box'], this.p);
this.d = this.p.parents('.'+CSS_CLASS_NAMES['page_decoration']);
/*
* scale ratios
*
* default_r : the first one
* set_r : last set
* cur_r : currently using
*/
this.default_r = this.set_r = this.cur_r = this.p.height() / this.b.height();
this.h = this.p.height(); // Need to make rescale work when page_content_box is not loaded, yet
this.w = this.p.width();
this.data = JSON.parse($($('.'+CSS_CLASS_NAMES['page_data'], this.p)[0]).attr('data-data'));
// if page is loaded
if (this.b[0]) {
/*
* scale ratios
*
* default_r : the first one
* set_r : last set
* cur_r : currently using
*/
this.default_r = this.set_r = this.cur_r = this.p.height() / this.b.height();
this.ctm = this.data.ctm;
this.ictm = invert(this.ctm);
this.container = container;
this.data = JSON.parse($($('.'+CSS_CLASS_NAMES['page_data'], this.p)[0]).attr('data-data'));
this.ctm = this.data.ctm;
this.ictm = invert(this.ctm);
this.loaded = true;
}
};
$.extend(Page.prototype, {
/* hide & show are for contents, the page frame is still there */
@ -67,6 +82,7 @@ var pdf2htmlEX = (function(){
show : function(){
if(Math.abs(this.set_r - this.cur_r) > EPS) {
this.cur_r = this.set_r;
//TODO make it cross-browser compliant
this.b.css('transform', 'scale('+this.cur_r.toFixed(3)+')');
}
this.b.addClass('opened');
@ -116,7 +132,6 @@ var pdf2htmlEX = (function(){
this.container_id = config['container_id'];
this.sidebar_id = config['sidebar_id'];
this.outline_id = config['outline_id'];
this.page_urls = config['page_urls'];
this.init_before_loading_content();
var _ = this;
@ -141,26 +156,22 @@ var pdf2htmlEX = (function(){
if(this.outline.children().length > 0) {
this.sidebar.addClass('opened');
}
this.find_pages();
// register schedule rendering
var _ = this;
this.container.scroll(function(){ _.schedule_render(); });
//this.zoom_fixer();
this.zoom_fixer();
// handle links
this.container.add(this.outline).on('click', '.'+CSS_CLASS_NAMES['link'], this, this.link_handler);
// disable background image draging
$('img', this.container).on('dragstart', function(e){return false;});
this.render();
// load split pages
// has no effect if --split-pages is 0
this.load_page(0);
// Trigger documentLoaded event
$(this.container).trigger("documentLoaded");
},
find_pages : function() {
var new_pages = new Array();
@ -172,19 +183,54 @@ var pdf2htmlEX = (function(){
}
this.pages = new_pages;
},
load_page : function(idx) {
if(idx < this.page_urls.length){
var _ = this;
load_page : function(idx, pages_to_preload, successCallback) {
if (this.pages[idx+1].loaded)
return; // Page is loaded
if (pages_loading[idx])
return; // Page is already loading
var page_no_hex = (idx+1).toString(16);
var $pf = $(this.container).find('#' + CSS_CLASS_NAMES['page_frame'] + page_no_hex);
if($pf.length == 0)
return; // Page does not exist
var _ = this;
var url = $pf.data('page-url');
if (url && url.length > 0) {
pages_loading[idx] = true; // Set semaphore
$.ajax({
url: this.page_urls[idx],
url: url,
dataType: 'text'
}).done(function(data){
$('#'+_.container_id).append(data);
_.find_pages();
_.schedule_render();
_.load_page(idx+1);
});
_.pages[idx+1].p.parent().replaceWith(data); // pages index starts from 1
var $new_pf = $(_.container).find('#' + CSS_CLASS_NAMES['page_frame'] + page_no_hex);
_.pages[idx+1] = new Page($new_pf, _.container);
_.pages[idx+1].rescale(_.scale);
_.schedule_render();
// Event fired when page is loaded. Please notice that it's not necessarily rendered (see event pageShown).
_.container.trigger("pageLoaded", idx+1);
// disable background image dragging
$new_pf.find('.'+CSS_CLASS_NAMES['background_image']).on('dragstart', function(e){return false;});
// Reset loading token
pages_loading[idx] = undefined;
if (successCallback) successCallback();
});
}
// Concurrent prefetch of the next pages
if (pages_to_preload === undefined)
pages_to_preload = PAGES_TO_PRELOAD;
if (--pages_to_preload > 0)
_.load_page(idx+1, pages_to_preload);
},
pre_hide_pages : function() {
/* pages might have not been loaded yet, so add a CSS rule */
@ -211,7 +257,11 @@ var pdf2htmlEX = (function(){
for(var i in pl) {
var p = pl[i];
if(p.is_nearly_visible()){
p.show();
if (p.loaded) {
p.show();
this.container.trigger("pageShown", i);
} else
this.load_page(p.n - 1); // load_page index starts from 0
} else {
p.hide();
}
@ -284,7 +334,6 @@ var pdf2htmlEX = (function(){
},
link_handler : function (e) {
console.log('here');
var _ = e.data;
var t = $(e.currentTarget);
@ -345,11 +394,26 @@ var pdf2htmlEX = (function(){
}
if(ok) {
pos = transform(target_page.ctm, pos);
if(upside_down) {
pos[1] = target_page.height() - pos[1];
if (target_page.loaded) {
pos = transform(target_page.ctm, pos);
if(upside_down) {
pos[1] = target_page.height() - pos[1];
}
_.scroll_to(detail[0], pos);
} else {
// Scroll to the exact position once loaded.
_.load_page(target_page.n - 1, 1, function() { // load_page index starts from 0
target_page = _.pages[target_page.n];
pos = transform(target_page.ctm, pos);
if(upside_down) {
pos[1] = target_page.height() - pos[1];
}
_.scroll_to(detail[0], pos);
});
// In the meantime page gets loaded, scroll approximately position for maximum responsiveness.
_.scroll_to(detail[0], [0,0]);
}
_.scroll_to(detail[0], pos);
e.preventDefault();
}
},