1
0
Fork 0
mirror of https://github.com/futurepress/epub.js.git synced 2025-10-04 15:09:16 +02:00

Update vertical writing support in continuous

This commit is contained in:
Fred Chasen 2017-11-17 17:35:09 -08:00
parent 628be87534
commit 781fd1e3bf
7 changed files with 172 additions and 64 deletions

View file

@ -18,8 +18,12 @@
<div id="prev" class="arrow"></div> <div id="prev" class="arrow"></div>
<div id="next" class="arrow"></div> <div id="next" class="arrow"></div>
<script> <script>
var params = URLSearchParams && new URLSearchParams(document.location.search.substring(1));
var url = params && params.get("url") && decodeURIComponent(params.get("url"));
var currentSectionIndex = (params && params.get("loc")) ? params.get("loc") : undefined;
// Load the opf // Load the opf
window.book = ePub("https://s3.amazonaws.com/moby-dick/moby-dick.epub"); window.book = ePub(url || "https://s3.amazonaws.com/moby-dick/moby-dick.epub");
var rendition = book.renderTo("viewer", { var rendition = book.renderTo("viewer", {
manager: "continuous", manager: "continuous",
flow: "paginated", flow: "paginated",
@ -27,7 +31,7 @@
height: 600 height: 600
}); });
var displayed = rendition.display(); var displayed = rendition.display(currentSectionIndex);
displayed.then(function(renderer){ displayed.then(function(renderer){
@ -39,39 +43,72 @@
// console.log(toc); // console.log(toc);
}); });
var next = document.getElementById("next"); book.ready.then(() => {
next.addEventListener("click", function(){
rendition.next();
}, false);
var prev = document.getElementById("prev"); var next = document.getElementById("next");
prev.addEventListener("click", function(){
rendition.prev();
}, false);
var keyListener = function(e){ next.addEventListener("click", function(e){
book.package.metadata.direction === "rtl" ? rendition.prev() : rendition.next();
e.preventDefault();
}, false);
// Left Key var prev = document.getElementById("prev");
if ((e.keyCode || e.which) == 37) { prev.addEventListener("click", function(e){
rendition.prev(); book.package.metadata.direction === "rtl" ? rendition.next() : rendition.prev();
} e.preventDefault();
}, false);
// Right Key var keyListener = function(e){
if ((e.keyCode || e.which) == 39) {
rendition.next();
}
}; // Left Key
if ((e.keyCode || e.which) == 37) {
book.package.metadata.direction === "rtl" ? rendition.next() : rendition.prev();
}
rendition.on("keyup", keyListener); // Right Key
document.addEventListener("keyup", keyListener, false); if ((e.keyCode || e.which) == 39) {
book.package.metadata.direction === "rtl" ? rendition.prev() : rendition.next();
}
};
rendition.on("keyup", keyListener);
document.addEventListener("keyup", keyListener, false);
});
rendition.on("selected", function(range) { rendition.on("selected", function(range) {
console.log("selected", range); console.log("selected", range);
}); });
rendition.on("layout", function(layout) {
let viewer = document.getElementById("viewer");
if (layout.spread) {
viewer.classList.remove('single');
} else {
viewer.classList.add('single');
}
});
rendition.on("relocated", function(location){ rendition.on("relocated", function(location){
console.log(location); console.log(location);
var next = book.package.metadata.direction === "rtl" ? document.getElementById("prev") : document.getElementById("next");
var prev = book.package.metadata.direction === "rtl" ? document.getElementById("next") : document.getElementById("prev");
if (location.atEnd) {
next.style.visibility = "hidden";
} else {
next.style.visibility = "visible";
}
if (location.atStart) {
prev.style.visibility = "hidden";
} else {
prev.style.visibility = "visible";
}
}); });
book.loaded.navigation.then(function(toc){ book.loaded.navigation.then(function(toc){

View file

@ -88,6 +88,10 @@ body {
content: ""; content: "";
} }
#viewer.spreads.single:after {
display: none;
}
#prev { #prev {
left: 40px; left: 40px;
} }

View file

@ -21,7 +21,7 @@
<script> <script>
var params = URLSearchParams && new URLSearchParams(document.location.search.substring(1)); var params = URLSearchParams && new URLSearchParams(document.location.search.substring(1));
var url = params && params.get("url") && decodeURIComponent(params.get("url")); var url = params && params.get("url") && decodeURIComponent(params.get("url"));
var currentSectionIndex = (params && params.get("loc")) ? params.get("loc") : 6; var currentSectionIndex = (params && params.get("loc")) ? params.get("loc") : undefined;
// Load the opf // Load the opf
var book = ePub(url || "https://s3.amazonaws.com/moby-dick/moby-dick.epub"); var book = ePub(url || "https://s3.amazonaws.com/moby-dick/moby-dick.epub");

View file

@ -954,10 +954,13 @@ class Contents {
* @param {number} gap * @param {number} gap
*/ */
columns(width, height, columnWidth, gap){ columns(width, height, columnWidth, gap){
var COLUMN_AXIS = prefixed("column-axis"); let COLUMN_AXIS = prefixed("column-axis");
var COLUMN_GAP = prefixed("column-gap"); let COLUMN_GAP = prefixed("column-gap");
var COLUMN_WIDTH = prefixed("column-width"); let COLUMN_WIDTH = prefixed("column-width");
var COLUMN_FILL = prefixed("column-fill"); let COLUMN_FILL = prefixed("column-fill");
let writingMode = this.writingMode();
let axis = (writingMode.indexOf("vertical") === 0) ? "vertical" : "horizontal";
this.layoutStyle("paginated"); this.layoutStyle("paginated");
@ -976,7 +979,11 @@ class Contents {
this.css("overflow-y", "hidden"); this.css("overflow-y", "hidden");
this.css("margin", "0", true); this.css("margin", "0", true);
this.css("padding", "20px " + (gap / 2) + "px", true); if (axis === "vertical") {
this.css("padding", (gap / 2) + "px 20px", true);
} else {
this.css("padding", "20px " + (gap / 2) + "px", true);
}
this.css("box-sizing", "border-box"); this.css("box-sizing", "border-box");
this.css("max-width", "inherit"); this.css("max-width", "inherit");

View file

@ -274,8 +274,6 @@ class ContinuousViewManager extends DefaultViewManager {
} }
check(_offsetLeft, _offsetTop){ check(_offsetLeft, _offsetTop){
var last, first, next, prev;
var checking = new defer(); var checking = new defer();
var newViews = []; var newViews = [];
@ -292,27 +290,45 @@ class ContinuousViewManager extends DefaultViewManager {
var bounds = this._bounds; // bounds saved this until resize var bounds = this._bounds; // bounds saved this until resize
let dir = this.settings.direction === "rtl" ? -1 : 1; //RTL reverses scrollTop let rtl = this.settings.direction === "rtl";
let dir = horizontal && rtl ? -1 : 1; //RTL reverses scrollTop
var offset = horizontal ? this.scrollLeft : this.scrollTop * dir; var offset = horizontal ? this.scrollLeft : this.scrollTop * dir;
var visibleLength = horizontal ? bounds.width : bounds.height; var visibleLength = horizontal ? bounds.width : bounds.height;
var contentLength = horizontal ? this.container.scrollWidth : this.container.scrollHeight; var contentLength = horizontal ? this.container.scrollWidth : this.container.scrollHeight;
if (offset + visibleLength + delta >= contentLength) { let prepend = () => {
last = this.views.last(); let first = this.views.first();
next = last && last.section.next(); let prev = first && first.section.prev();
if(prev) {
newViews.push(this.prepend(prev));
}
}
let append = () => {
let last = this.views.last();
let next = last && last.section.next();
if(next) { if(next) {
newViews.push(this.append(next)); newViews.push(this.append(next));
} }
}
if (offset + visibleLength + delta >= contentLength) {
if (horizontal && rtl) {
prepend();
} else {
append();
}
} }
if (offset - delta < 0 ) { if (offset - delta < 0 ) {
first = this.views.first(); if (horizontal && rtl) {
append();
prev = first && first.section.prev(); } else {
if(prev) { prepend();
newViews.push(this.prepend(prev));
} }
} }
@ -322,6 +338,11 @@ class ContinuousViewManager extends DefaultViewManager {
if(newViews.length){ if(newViews.length){
return Promise.all(promises) return Promise.all(promises)
.then(() => {
if (this.layout.name === "pre-paginated" && this.layout.props.spread) {
return this.check();
}
})
.then(() => { .then(() => {
// Check to see if anything new is on screen after rendering // Check to see if anything new is on screen after rendering
return this.update(delta); return this.update(delta);
@ -511,32 +532,64 @@ class ContinuousViewManager extends DefaultViewManager {
next(){ next(){
if(this.settings.axis === "horizontal") { let dir = this.settings.direction;
let delta = this.layout.props.name === "pre-paginated" &&
this.layout.props.spread ? this.layout.props.delta * 2 : this.layout.props.delta;
this.scrollLeft = this.container.scrollLeft; if(!this.views.length) return;
if(this.container.scrollLeft + if(this.isPaginated && this.settings.axis === "horizontal") {
this.container.offsetWidth +
this.layout.delta < this.container.scrollWidth) { this.scrollBy(delta, 0, true);
this.scrollBy(this.layout.delta, 0, true);
} else {
this.scrollTo(this.container.scrollWidth - this.layout.delta, 0, true);
}
} else { } else {
this.scrollBy(0, this.layout.height, true); this.scrollBy(0, this.layout.height, true);
} }
// if(this.settings.axis === "horizontal") {
//
// this.scrollLeft = this.container.scrollLeft;
//
// if(this.container.scrollLeft +
// this.container.offsetWidth +
// this.layout.delta < this.container.scrollWidth) {
// console.log("a", this.layout.delta);
// this.scrollBy(this.layout.delta, 0, true);
// } else {
// console.log("b", this.container.scrollWidth - this.layout.delta);
//
// this.scrollTo(this.container.scrollWidth - this.layout.delta, 0, true);
// }
//
// } else {
// console.log("c", this.layout.height);
//
// this.scrollBy(0, this.layout.height, true);
// }
this.q.enqueue(function() { this.q.enqueue(function() {
this.check(); this.check();
}.bind(this)); }.bind(this));
} }
prev(){ prev(){
if(this.settings.axis === "horizontal") {
this.scrollBy(-this.layout.delta, 0, true); let dir = this.settings.direction;
let delta = this.layout.props.name === "pre-paginated" &&
this.layout.props.spread ? this.layout.props.delta * 2 : this.layout.props.delta;
if(!this.views.length) return;
if(this.isPaginated && this.settings.axis === "horizontal") {
this.scrollBy(-delta, 0, true);
} else { } else {
this.scrollBy(0, -this.layout.height, true); this.scrollBy(0, -this.layout.height, true);
} }
this.q.enqueue(function() { this.q.enqueue(function() {
@ -544,24 +597,30 @@ class ContinuousViewManager extends DefaultViewManager {
}.bind(this)); }.bind(this));
} }
updateAxis(axis, preventUpdate){
updateAxis(axis){
if (!this.isPaginated) {
axis = "vertical";
}
this.settings.axis = axis; this.settings.axis = axis;
this.stage && this.stage.axis(axis); this.stage && this.stage.axis(axis);
this.viewSettings.axis = axis; this.viewSettings.axis = axis;
if (!this.isPaginated) {
axis = "vertical";
}
if (axis === "vertical") {
this.layout.spread("none");
}
if (axis === "vertical") { if (axis === "vertical") {
this.settings.infinite = true; this.settings.infinite = true;
} else { } else {
this.settings.infinite = false; this.settings.infinite = false;
} }
if (!preventUpdate) {
this.updateLayout();
}
} }
} }

View file

@ -241,7 +241,7 @@ class DefaultViewManager {
if (this.settings.direction === "ltr") { if (this.settings.direction === "ltr") {
this.scrollTo(offset.left, offset.top, true); this.scrollTo(offset.left, offset.top, true);
} else { } else {
let width = view.width(); let width = visible.width();
this.scrollTo(offset.left + width, offset.top, true); this.scrollTo(offset.left + width, offset.top, true);
} }
@ -414,7 +414,7 @@ class DefaultViewManager {
left = this.container.scrollLeft; left = this.container.scrollLeft;
if(left > 0) { if(left > 0) {
this.scrollBy(-this.layout.delta, 0, true); this.scrollBy(this.layout.delta, 0, true);
} else { } else {
next = this.views.last().section.next(); next = this.views.last().section.next();
} }
@ -426,7 +426,7 @@ class DefaultViewManager {
let top = this.container.scrollTop + this.container.offsetHeight; let top = this.container.scrollTop + this.container.offsetHeight;
if(top < this.container.scrollHeight) { if(top < this.container.scrollHeight) {
this.scrollBy(0, this.layout.height + this.layout.gap / 2, true); this.scrollBy(0, this.layout.height, true);
} else { } else {
next = this.views.last().section.next(); next = this.views.last().section.next();
} }
@ -484,7 +484,7 @@ class DefaultViewManager {
left = this.container.scrollLeft + this.container.offsetWidth + this.layout.delta; left = this.container.scrollLeft + this.container.offsetWidth + this.layout.delta;
if(left <= this.container.scrollWidth) { if(left <= this.container.scrollWidth) {
this.scrollBy(this.layout.delta, 0, true); this.scrollBy(-this.layout.delta, 0, true);
} else { } else {
prev = this.views.first().section.prev(); prev = this.views.first().section.prev();
} }
@ -496,7 +496,7 @@ class DefaultViewManager {
let top = this.container.scrollTop; let top = this.container.scrollTop;
if(top > 0) { if(top > 0) {
this.scrollBy(0, -(this.layout.height + this.layout.gap / 2), true); this.scrollBy(0, -(this.layout.height), true);
} else { } else {
prev = this.views.first().section.prev(); prev = this.views.first().section.prev();
} }
@ -731,7 +731,7 @@ class DefaultViewManager {
} }
if(!this.fullsize) { if(!this.fullsize) {
if(x) this.container.scrollLeft += x; if(x) this.container.scrollLeft += x * dir;
if(y) this.container.scrollTop += y; if(y) this.container.scrollTop += y;
} else { } else {
window.scrollBy(x * dir, y * dir); window.scrollBy(x * dir, y * dir);

View file

@ -9,7 +9,7 @@ class IframeView {
constructor(section, options) { constructor(section, options) {
this.settings = extend({ this.settings = extend({
ignoreClass : "", ignoreClass : "",
axis: "vertical", axis: options.layout && options.layout.props.flow === "scrolled" ? "vertical" : "horizontal",
direction: undefined, direction: undefined,
width: 0, width: 0,
height: 0, height: 0,
@ -154,6 +154,7 @@ class IframeView {
// find and report the writingMode axis // find and report the writingMode axis
let writingMode = this.contents.writingMode(); let writingMode = this.contents.writingMode();
let axis = (writingMode.indexOf("vertical") === 0) ? "vertical" : "horizontal"; let axis = (writingMode.indexOf("vertical") === 0) ? "vertical" : "horizontal";
this.setAxis(axis); this.setAxis(axis);
this.emit(EVENTS.VIEWS.AXIS, axis); this.emit(EVENTS.VIEWS.AXIS, axis);