Ver código fonte

Попытка сделать автоскроллинг текста

Book Pauk 6 anos atrás
pai
commit
945d69ab8f

+ 22 - 1
client/components/Reader/Reader.vue

@@ -53,6 +53,7 @@
                     @book-pos-changed="bookPosChanged"
                     @tool-bar-toggle="toolBarToggle"
                     @full-screen-toogle="fullScreenToggle"
+                    @scrolling-toggle="scrollingToggle"
                 ></component>
             </keep-alive>
 
@@ -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;

+ 98 - 31
client/components/Reader/TextPage/TextPage.vue

@@ -5,7 +5,9 @@
             <!-- img -->
         </div>
         <div v-show="toggleLayout" class="layout">
-            <div v-html="page1"></div>
+            <div ref="scrollingPage" class="layout" @transitionend="onScrollingTransitionEnd">
+                <div v-html="page1"></div>
+            </div>
         </div>
         <div v-show="!toggleLayout" class="layout">
             <div v-html="page2"></div>
@@ -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}"></div>`;
     }
 
-    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;
-
-            (async() => {
-                await sleep(100);
-                if (this.cancelPrepare) {
-                    this.preparing = false;
-                    return;
-                }
+        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;
 
-                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;
-                }
+            if (this.toggleLayout)
+                this.page2 = this.drawPage(lines.linesDown);//наоборот
+            else
+                this.page1 = this.drawPage(lines.linesDown);
 
-                this.preparing = false;
-            })();
+            this.pagePrepared = true;
         }
     }