1
0
Fork 0
mirror of https://github.com/futurepress/epub.js.git synced 2025-10-03 14:59:18 +02:00

Added relocated event

This commit is contained in:
Fred Chasen 2017-07-10 17:25:26 -04:00
parent aa9c2535d9
commit 3f4d7bbbf2
18 changed files with 250 additions and 58 deletions

View file

@ -60,7 +60,7 @@
rendition.on("keyup", keyListener); rendition.on("keyup", keyListener);
document.addEventListener("keyup", keyListener, false); document.addEventListener("keyup", keyListener, false);
rendition.on("locationChanged", function(location){ rendition.on("relocated", function(location){
// console.log(location); // console.log(location);
}); });

View file

@ -70,7 +70,7 @@
console.log("selected", range); console.log("selected", range);
}); });
rendition.on("locationChanged", function(location){ rendition.on("relocated", function(location){
console.log(location); console.log(location);
}); });

View file

@ -99,7 +99,7 @@
rendition.on("keyup", keyListener); rendition.on("keyup", keyListener);
document.addEventListener("keyup", keyListener, false); document.addEventListener("keyup", keyListener, false);
rendition.on("locationChanged", function(location){ rendition.on("relocated", function(location){
// console.log(location); // console.log(location);
}); });

View file

@ -49,7 +49,7 @@
rendition.display(); rendition.display();
rendition.on("keyup", keyListener); rendition.on("keyup", keyListener);
rendition.on("locationChanged", function(location){ rendition.on("relocated", function(location){
console.log(location); console.log(location);
}); });

View file

@ -70,9 +70,6 @@
rendition.on("keyup", keyListener); rendition.on("keyup", keyListener);
document.addEventListener("keyup", keyListener, false); document.addEventListener("keyup", keyListener, false);
rendition.on("locationChanged", function(location){
console.log(location);
});
book.ready.then(function(){ book.ready.then(function(){
// Load in stored locations from json or local storage // Load in stored locations from json or local storage
@ -109,7 +106,7 @@
// Get the current CFI // Get the current CFI
var currentLocation = rendition.currentLocation(); var currentLocation = rendition.currentLocation();
// Get the Percentage (or location) from that CFI // Get the Percentage (or location) from that CFI
var currentPage = book.locations.percentageFromCfi(currentLocation.start); var currentPage = book.locations.percentageFromCfi(currentLocation.start.cfi);
slider.value = currentPage; slider.value = currentPage;
currentPage.value = currentPage; currentPage.value = currentPage;
}); });
@ -122,13 +119,14 @@
}, false); }, false);
// Listen for location changed event, get percentage from CFI // Listen for location changed event, get percentage from CFI
rendition.on('locationChanged', function(location){ rendition.on('relocated', function(location){
var percent = book.locations.percentageFromCfi(location.start); var percent = book.locations.percentageFromCfi(location.start.cfi);
var percentage = Math.floor(percent * 100); var percentage = Math.floor(percent * 100);
if(!mouseDown) { if(!mouseDown) {
slider.value = percentage; slider.value = percentage;
} }
currentPage.value = percentage; currentPage.value = percentage;
console.log(location);
}); });
// Save out the generated locations to JSON // Save out the generated locations to JSON

View file

@ -160,7 +160,7 @@
}); });
rendition.on("locationChanged", function(location){ rendition.on("relocated", function(location){
var current = book.navigation.get(location.href); var current = book.navigation.get(location.href);
if (current) { if (current) {

View file

@ -61,7 +61,7 @@
rendition.on("keyup", keyListener); rendition.on("keyup", keyListener);
document.addEventListener("keyup", keyListener, false); document.addEventListener("keyup", keyListener, false);
rendition.on("locationChanged", function(location){ rendition.on("relocated", function(location){
// console.log(location); // console.log(location);
}); });

View file

@ -38,7 +38,7 @@
e.preventDefault(); e.preventDefault();
}, false); }, false);
rendition.on("locationChanged", function(location){ rendition.on("relocated", function(location){
console.log(location); console.log(location);
}); });

View file

@ -5,6 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>EPUB.js Scrolled Full Example</title> <title>EPUB.js Scrolled Full Example</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.1/jszip.min.js"></script>
<script src="../dist/epub.js"></script> <script src="../dist/epub.js"></script>
@ -161,7 +162,7 @@
}); });
var hash = window.location.hash.slice(2); var hash = window.location.hash.slice(2);
console.log(hash); console.log(hash);
rendition.display(hash || 1); rendition.display(hash || undefined);
var next = document.getElementById("next"); var next = document.getElementById("next");
@ -215,7 +216,7 @@
window.location.hash = "#/"+section.href window.location.hash = "#/"+section.href
}); });
rendition.on("locationChanged", function(location){ rendition.on("relocated", function(location){
console.log(location); console.log(location);
}); });

View file

@ -89,7 +89,7 @@
}); });
rendition.on("locationChanged", function(location){ rendition.on("relocated", function(location){
console.log(location); console.log(location);
}); });

View file

@ -86,7 +86,7 @@
}); });
rendition.on("locationChanged", function(location){ rendition.on("relocated", function(location){
console.log(location); console.log(location);
}); });

View file

@ -180,14 +180,28 @@ class Layout {
* @return {number} spreads * @return {number} spreads
* @return {number} pages * @return {number} pages
*/ */
count(totalWidth) { count(totalLength, pageLength) {
// var totalWidth = contents.scrollWidth(); // var totalWidth = contents.scrollWidth();
var spreads = Math.ceil( totalWidth / this.delta); let spreads, pages;
if (this.name === "pre-paginated") {
spreads = 1;
pages = 1;
} else if (this._flow === "paginated") {
pageLength = pageLength || this.delta;
spreads = Math.ceil( totalLength / pageLength);
pages = spreads * this.divisor;
} else { // scrolled
pageLength = pageLength || this.height;
spreads = Math.ceil( totalLength / pageLength);
pages = spreads;
}
return { return {
spreads : spreads, spreads,
pages : spreads * this.divisor pages
}; };
} }
} }

View file

@ -407,7 +407,7 @@ class DefaultViewManager {
} }
return this.location; return this.location;
} }
/*
scrolledLocation(){ scrolledLocation(){
var visible = this.visible(); var visible = this.visible();
@ -456,14 +456,91 @@ class DefaultViewManager {
} }
} }
*/
scrolledLocation() {
let visible = this.visible();
var container = this.container.getBoundingClientRect();
var pageHeight = (container.height < window.innerHeight) ? container.height : window.innerHeight;
var offset = 0;
if(!this.settings.height) {
offset = window.scrollY;
}
let sections = visible.map((view) => {
let {index, href} = view.section;
let position = view.position();
let startPos = position.top - container.top + offset;
let endPos = startPos + pageHeight;
if (endPos > position.bottom - container.top + offset) {
endPos = position.bottom - container.top + offset;
}
let totalPages = this.layout.count(view._height, pageHeight).pages;
let currPage = Math.round(startPos / pageHeight);
let pages = [];
let numPages = (endPos - startPos) / pageHeight;
for (var i = 1; i <= numPages; i++) {
let pg = currPage + i;
pages.push(pg);
}
let mapping = this.mapping.page(view.contents, view.section.cfiBase, startPos, endPos);
return {
index,
href,
pages,
totalPages,
mapping
}
});
return sections;
}
paginatedLocation(){ paginatedLocation(){
var visible = this.visible(); let visible = this.visible();
var startA, startB, endA, endB;
var pageLeft, pageRight;
var container = this.container.getBoundingClientRect(); var container = this.container.getBoundingClientRect();
var last;
let sections = visible.map((view) => {
let {index, href} = view.section;
let offset = view.offset().left;
let position = view.position().left;
let width = view.width();
let startPos = this.container.scrollLeft + offset;
let endPos = startPos + this.layout.spreadWidth + this.layout.gap;
if (endPos > this.container.scrollLeft + offset + width) {
endPos = this.container.scrollLeft + offset + width;
}
let totalPages = this.layout.count(width).pages;
let currPage = Math.ceil((startPos - offset) / this.layout.spreadWidth);
let pages = [];
let numPages = (endPos - startPos) / (this.layout.columnWidth + (this.layout.gap / 2));
for (var i = 1; i <= numPages; i++) {
let pg = currPage + i;
pages.push(pg);
}
let start = container.left - position;
let end = start + this.layout.spreadWidth + this.layout.gap;
let mapping = this.mapping.page(view.contents, view.section.cfiBase, start, end);
return {
index,
href,
pages,
totalPages,
mapping
}
});
return sections;
/*
if(visible.length === 1) { if(visible.length === 1) {
startA = container.left - visible[0].position().left; startA = container.left - visible[0].position().left;
endA = startA + this.layout.spreadWidth + this.layout.gap; endA = startA + this.layout.spreadWidth + this.layout.gap;
@ -498,6 +575,7 @@ class DefaultViewManager {
end: pageRight.end end: pageRight.end
}; };
} }
*/
} }
isVisible(view, offsetPrev, offsetNext, _container){ isVisible(view, offsetPrev, offsetNext, _container){

View file

@ -42,6 +42,7 @@ class Stage {
container.style.wordSpacing = "0"; container.style.wordSpacing = "0";
container.style.lineHeight = "0"; container.style.lineHeight = "0";
container.style.verticalAlign = "top"; container.style.verticalAlign = "top";
container.style.position = "relative";
if(axis === "horizontal") { if(axis === "horizontal") {
container.style.whiteSpace = "nowrap"; container.style.whiteSpace = "nowrap";

View file

@ -24,8 +24,8 @@ class IframeView {
this.displayed = false; this.displayed = false;
this.rendered = false; this.rendered = false;
this.width = this.settings.width; // this.width = this.settings.width;
this.height = this.settings.height; // this.height = this.settings.height;
this.fixedWidth = 0; this.fixedWidth = 0;
this.fixedHeight = 0; this.fixedHeight = 0;
@ -536,6 +536,21 @@ class IframeView {
this.emit("hidden", this); this.emit("hidden", this);
} }
offset() {
return {
top: this.element.offsetTop,
left: this.element.offsetLeft
}
}
width() {
return this._width;
}
height() {
return this._height;
}
position() { position() {
return this.element.getBoundingClientRect(); return this.element.getBoundingClientRect();
} }

View file

@ -169,8 +169,8 @@ class Mapping {
elPos = node.getBoundingClientRect(); elPos = node.getBoundingClientRect();
} }
left = this.horizontal ? elPos.left : elPos.top; left = Math.round(this.horizontal ? elPos.left : elPos.top);
right = this.horizontal ? elPos.right : elPos.bottom; right = Math.round(this.horizontal ? elPos.right : elPos.bottom);
if(left > end && $prev) { if(left > end && $prev) {
return $prev; return $prev;

View file

@ -490,23 +490,31 @@ class Rendition {
var location = this.manager.currentLocation(); var location = this.manager.currentLocation();
if (location && location.then && typeof location.then === "function") { if (location && location.then && typeof location.then === "function") {
location.then(function(result) { location.then(function(result) {
this.location = result; let located = this.located(result);
this.location = located;
this.emit("locationChanged", {
index: this.location.start.index,
href: this.location.start.href,
start: this.location.start.cfi,
end: this.location.end.cfi,
percentage: this.location.start.percentage
});
this.percentage = this.book.locations.percentageFromCfi(result.start); this.emit("relocated", this.location);
if (this.percentage != null) {
this.location.percentage = this.percentage;
}
this.emit("locationChanged", this.location);
}.bind(this)); }.bind(this));
} else if (location) { } else if (location) {
this.location = location; let located = this.located(location);
this.percentage = this.book.locations.percentageFromCfi(location.start); this.location = located;
if (this.percentage != null) {
this.location.percentage = this.percentage;
}
this.emit("locationChanged", this.location); this.emit("locationChanged", {
index: this.location.start.index,
href: this.location.start.href,
start: this.location.start.cfi,
end: this.location.end.cfi,
percentage: this.location.start.percentage
});
this.emit("relocated", this.location);
} }
}.bind(this)); }.bind(this));
@ -520,19 +528,73 @@ class Rendition {
var location = this.manager.currentLocation(); var location = this.manager.currentLocation();
if (location && location.then && typeof location.then === "function") { if (location && location.then && typeof location.then === "function") {
location.then(function(result) { location.then(function(result) {
var percentage = this.book.locations.percentageFromCfi(result.start); let located = this.located(result);
if (percentage != null) { return located;
result.percentage = percentage;
}
return result;
}.bind(this)); }.bind(this));
} else if (location) { } else if (location) {
var percentage = this.book.locations.percentageFromCfi(location.start); let located = this.located(location);
if (percentage != null) { return located;
location.percentage = percentage;
} }
return location;
} }
located(location){
let start = location[0];
let end = location[location.length-1]
let located = {
start: {
index: start.index,
href: start.href,
cfi: start.mapping.start,
displayed: {
page: start.pages[0],
total: start.totalPages
}
},
end: {
index: end.index,
href: end.href,
cfi: end.mapping.end,
displayed: {
page: end.pages[end.pages.length-1],
totalPages: end.totalPages
}
}
};
let locationStart = this.book.locations.locationFromCfi(start.mapping.start);
let locationEnd = this.book.locations.locationFromCfi(end.mapping.end);
if (locationStart != null) {
located.start.location = locationStart;
located.start.percentage = this.book.locations.percentageFromLocation(locationStart);
}
if (locationEnd != null) {
located.end.location = locationEnd;
located.end.percentage = this.book.locations.percentageFromLocation(locationEnd);
}
let pageStart = this.book.pageList.pageFromCfi(start.mapping.start);
let pageEnd = this.book.pageList.pageFromCfi(end.mapping.end);
if (pageStart != -1) {
located.start.page = pageStart;
}
if (pageEnd != -1) {
located.end.page = pageEnd;
}
if (end.index === this.book.spine.last().index &&
located.end.displayed.page === located.end.displayed.totalPages) {
located.atEnd = true;
}
if (start.index === this.book.spine.first().index &&
located.start.displayed.page === 1) {
located.atStart = true;
}
return located;
} }
/** /**
@ -644,7 +706,7 @@ class Rendition {
contents.addStylesheetRules({ contents.addStylesheetRules({
"img" : { "img" : {
"max-width": (this._layout.columnWidth ? this._layout.columnWidth + "px" : "100%") + "!important", "max-width": (this._layout.columnWidth ? this._layout.columnWidth + "px" : "100%") + "!important",
"max-height": (this._layout.height ? this._layout.height + "px" : "50%") + "!important", "max-height": (this._layout.height ? (this._layout.height * 0.6) + "px" : "60%") + "!important",
"object-fit": "contain", "object-fit": "contain",
"page-break-inside": "avoid" "page-break-inside": "avoid"
} }

View file

@ -76,7 +76,6 @@ class Spine {
} }
return; return;
}.bind(this); }.bind(this);
item.next = function() { item.next = function() {
let nextIndex = item.index; let nextIndex = item.index;
while (nextIndex < this.spineItems.length-1) { while (nextIndex < this.spineItems.length-1) {
@ -133,9 +132,9 @@ class Spine {
index = cfi.spinePos; index = cfi.spinePos;
} else if(typeof target === "number" || isNaN(target) === false){ } else if(typeof target === "number" || isNaN(target) === false){
index = target; index = target;
} else if(target && target.indexOf("#") === 0) { } else if(typeof target === "string" && target.indexOf("#") === 0) {
index = this.spineById[target.substring(1)]; index = this.spineById[target.substring(1)];
} else if(target) { } else if(typeof target === "string") {
// Remove fragments // Remove fragments
target = target.split("#")[0]; target = target.split("#")[0];
index = this.spineByHref[target]; index = this.spineByHref[target];
@ -207,6 +206,30 @@ class Spine {
return this.spineItems.forEach.apply(this.spineItems, arguments); return this.spineItems.forEach.apply(this.spineItems, arguments);
} }
first() {
let index = 0;
while (index < this.spineItems.length-1) {
let next = this.get(index);
if (next && next.linear) {
return next;
}
index += 1;
}
}
last() {
let index = this.spineItems.length-1;
while (index > 0) {
let prev = this.get(index);
if (prev && prev.linear) {
return prev;
}
index -= 1;
}
}
destroy() { destroy() {
this.each((section) => section.destroy()); this.each((section) => section.destroy());