diff --git a/client/components/Reader/Reader.vue b/client/components/Reader/Reader.vue
index 46b2fa75..092a4518 100644
--- a/client/components/Reader/Reader.vue
+++ b/client/components/Reader/Reader.vue
@@ -53,6 +53,7 @@
@book-pos-changed="bookPosChanged"
@tool-bar-toggle="toolBarToggle"
@full-screen-toogle="fullScreenToggle"
+ @scrolling-toggle="scrollingToggle"
>
@@ -249,6 +250,8 @@ class Reader extends Vue {
this.setPositionActive = false;
this.historyActive = false;
this.settingsActive = false;
+ if (this.scrollingActive)
+ this.scrollingToggle();
}
loaderToggle() {
@@ -273,6 +276,18 @@ class Reader extends Vue {
}
}
+ scrollingToggle() {
+ this.scrollingActive = !this.scrollingActive;
+ if (this.activePage == 'TextPage') {
+ const page = this.$refs.page;
+ if (this.scrollingActive) {
+ page.startTextScrolling();
+ } else {
+ page.stopTextScrolling();
+ }
+ }
+ }
+
historyToggle() {
this.historyActive = !this.historyActive;
if (this.historyActive) {
@@ -303,7 +318,10 @@ class Reader extends Vue {
break;
case 'setPosition':
this.setPositionToggle();
- break;
+ break;
+ case 'scrolling':
+ this.scrollingToggle()
+ break;
case 'history':
this.historyToggle();
break;
@@ -536,6 +554,9 @@ class Reader extends Vue {
case 'KeyP':
this.setPositionToggle();
break;
+ case 'KeyZ':
+ this.scrollingToggle();
+ break;
case 'KeyH':
this.historyToggle();
break;
diff --git a/client/components/Reader/TextPage/TextPage.vue b/client/components/Reader/TextPage/TextPage.vue
index 09a56d7e..704dadb8 100644
--- a/client/components/Reader/TextPage/TextPage.vue
+++ b/client/components/Reader/TextPage/TextPage.vue
@@ -5,7 +5,9 @@
@@ -345,6 +347,7 @@ class TextPage extends Vue {
this.page1 = null;
this.page2 = null;
this.statusBar = null;
+ await this.stopTextScrolling();
this.calcPropsAndLoadFonts();
@@ -360,10 +363,11 @@ class TextPage extends Vue {
` background-color: ${this.backgroundColor}">
`;
}
- onResize() {
+ async onResize() {
this.page1 = null;
this.page2 = null;
this.statusBar = null;
+ await this.stopTextScrolling();
this.calcDrawProps();
this.setBackground();
@@ -382,7 +386,84 @@ class TextPage extends Vue {
return `${style.italic ? 'italic' : this.fontStyle} ${style.bold ? 'bold' : this.fontWeight} ${this.fontSize}px ${this.fontName}`;
}
+ onScrollingTransitionEnd() {
+ if (this.resolveTransitionFinish)
+ this.resolveTransitionFinish();
+ }
+
+ async startTextScrolling() {
+ if (this.doingScrolling || !this.book || !this.parsed.textLength || !this.linesDown || this.pageLineCount < 1 ||
+ this.linesDown.length <= this.pageLineCount) {
+ this.$emit('scrolling-toggle');
+ return;
+ }
+
+ this.stopScrolling = false;
+ this.doingScrolling = true;
+
+ const transitionFinish = (timeout) => {
+ return new Promise(async(resolve) => {
+ this.resolveTransitionFinish = resolve;
+ let steps = timeout/100;
+ while (steps > 0 && !this.stopScrolling) {
+ steps--;
+ await sleep(100);
+ }
+ resolve();
+ });
+ };
+
+ if (!this.toggleLayout)
+ this.page1 = this.page2;
+ this.toggleLayout = true;
+ await sleep(50);
+
+ const page = this.$refs.scrollingPage;
+ let i = 0;
+ while (!this.stopScrolling) {
+ page.style.transition = 'all 2s linear 0s';
+ page.style.transform = `translateY(-${this.lineHeight}px)`;
+
+ if (i > 0) {
+ this.doDown();
+ if (this.linesDown.length <= this.pageLineCount + 1) {
+ this.$emit('scrolling-toggle');
+ this.stopScrolling = true;
+ }
+ }
+ await transitionFinish(2500);
+ page.style.transition = '';
+ page.style.transform = 'none';
+ page.offsetHeight;
+ i++;
+ }
+ page.style.transition = '';
+ page.style.transform = 'none';
+ this.resolveTransitionFinish = null;
+ this.doingScrolling = false;
+ }
+
+ async stopTextScrolling() {
+ this.stopScrolling = true;
+
+ const page = this.$refs.scrollingPage;
+ page.style.transition = '';
+ page.style.transform = 'none';
+ page.offsetHeight;
+
+ while (this.doingScrolling) await sleep(10);
+ }
+
draw() {
+ if (this.doingScrolling) {
+ const lines = this.getLines(this.bookPos);
+ this.linesDown = lines.linesDown;
+ this.linesUp = lines.linesUp;
+ this.page1 = this.drawPage(lines.linesDown);
+ this.debouncedDrawStatusBar();
+ return;
+ }
+
if (this.w < minLayoutWidth) {
this.page1 = null;
this.page2 = null;
@@ -465,7 +546,7 @@ class TextPage extends Vue {
y += this.statusBarHeight*(this.statusBarTop ? 1 : 0);
let len = lines.length;
- len = (len > this.pageLineCount ? len = this.pageLineCount : len);
+ len = (len > this.pageLineCount + 1 ? this.pageLineCount + 1 : len);
for (let i = 0; i < len; i++) {
const line = lines[i];
/* line:
@@ -620,36 +701,22 @@ class TextPage extends Vue {
if (!this.book || !this.parsed.textLength || !this.linesDown || this.pageLineCount < 1)
return;
- if (!this.preparing) {
- this.preparing = true;
+ let i = this.pageLineCount;
+ if (this.keepLastToFirst)
+ i--;
+ if (i >= 0 && this.linesDown.length > i) {
+ this.bookPosPrepared = this.linesDown[i].begin;
+
+ const lines = this.getLines(this.bookPosPrepared);
+ this.linesDownNext = lines.linesDown;
+ this.linesUpNext = lines.linesUp;
- (async() => {
- await sleep(100);
- if (this.cancelPrepare) {
- this.preparing = false;
- return;
- }
+ if (this.toggleLayout)
+ this.page2 = this.drawPage(lines.linesDown);//наоборот
+ else
+ this.page1 = this.drawPage(lines.linesDown);
- let i = this.pageLineCount;
- if (this.keepLastToFirst)
- i--;
- if (i >= 0 && this.linesDown.length > i) {
- this.bookPosPrepared = this.linesDown[i].begin;
-
- const lines = this.getLines(this.bookPosPrepared);
- this.linesDownNext = lines.linesDown;
- this.linesUpNext = lines.linesUp;
-
- if (this.toggleLayout)
- this.page2 = this.drawPage(lines.linesDown);//наоборот
- else
- this.page1 = this.drawPage(lines.linesDown);
-
- this.pagePrepared = true;
- }
-
- this.preparing = false;
- })();
+ this.pagePrepared = true;
}
}