From 94b0c9def11870b9ab47617ac8b78823986faea4 Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Fri, 25 Jan 2019 03:06:53 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=BF=D0=BE=D0=B4=D0=B3=D1=80=D1=83=D0=B7=D0=BA?= =?UTF-8?q?=D0=B8=20=D1=88=D1=80=D0=B8=D1=84=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/components/App.vue | 5 + .../components/Reader/TextPage/TextPage.vue | 103 +++++++++++------- client/components/Reader/share/BookParser.js | 3 +- client/components/fonts/rubik.woff2 | Bin 0 -> 10656 bytes 4 files changed, 69 insertions(+), 42 deletions(-) create mode 100644 client/components/fonts/rubik.woff2 diff --git a/client/components/App.vue b/client/components/App.vue index fee0e8db..80802598 100644 --- a/client/components/App.vue +++ b/client/components/App.vue @@ -286,4 +286,9 @@ body, html, #app { src: url('fonts/archivo.woff2') format('woff2'); } +@font-face { + font-family: 'Rubik'; + src: url('fonts/rubik.woff2') format('woff2'); +} + diff --git a/client/components/Reader/TextPage/TextPage.vue b/client/components/Reader/TextPage/TextPage.vue index 78e9e298..44308acb 100644 --- a/client/components/Reader/TextPage/TextPage.vue +++ b/client/components/Reader/TextPage/TextPage.vue @@ -1,9 +1,9 @@ @@ -41,7 +42,7 @@ export default @Component({ }, }) class TextPage extends Vue { - activeCanvas = false; + toggleLayout = false; showStatusBar = false; page1 = null; page2 = null; @@ -115,8 +116,6 @@ class TextPage extends Vue { this.$refs.layoutEvents.style.width = this.realWidth + 'px'; this.$refs.layoutEvents.style.height = this.realHeight + 'px'; - this.activeCanvas = false; - this.w = this.realWidth - 2*this.indent; this.h = this.realHeight - (this.showStatusBar ? this.statusBarHeight : 0); this.lineHeight = this.fontSize + this.lineInterval; @@ -131,7 +130,7 @@ class TextPage extends Vue { } //сообщение "Загрузка шрифтов..." - const flText = 'Загрузка шрифтов...'; + const flText = 'Загрузка шрифта...'; this.$refs.fontsLoading.innerHTML = flText; const fontsLoadingStyle = this.$refs.fontsLoading.style; fontsLoadingStyle.position = 'absolute'; @@ -172,18 +171,54 @@ class TextPage extends Vue { return this.context.measureText(text).width; } - async loadFonts() { + async checkLoadedFonts() { let loaded = await Promise.all(this.fontList.map(font => document.fonts.check(font))); if (loaded.some(r => !r)) { loaded = await Promise.all(this.fontList.map(font => document.fonts.load(font))); - await document.fonts.ready; if (loaded.some(r => !r.length)) throw new Error('some font not loaded'); } } + async loadFonts() { + this.fontsLoading = true; + + if (!this.fontsLoaded) + this.fontsLoaded = {}; + //загрузка дин.шрифта + const loaded = this.fontsLoaded[this.fontCssUrl]; + if (this.fontCssUrl && !loaded) { + loadCSS(this.fontCssUrl); + this.fontsLoaded[this.fontCssUrl] = 1; + } + + const waitingTime = 10*1000; + const delay = 100; + let i = 0; + //ждем шрифты + while (i < waitingTime/delay) { + i++; + try { + await this.checkLoadedFonts(); + i = waitingTime; + } catch (e) { + await sleep(delay); + } + } + if (i !== waitingTime) { + this.$notify.error({ + title: 'Ошибка загрузки', + message: 'Некоторые шрифты не удалось загрузить' + }); + } + + this.fontsLoading = false; + } + showBook() { this.$refs.main.focus(); + + this.toggleLayout = false; this.book = null; this.meta = null; this.fb2 = null; @@ -196,7 +231,7 @@ class TextPage extends Vue { this.textColor = '#000000'; this.backgroundColor = '#478355'; this.fontStyle = '';// 'bold','italic' - this.fontSize = 33;// px + this.fontSize = 35;// px this.fontName = 'Archivo'; this.fontCssUrl = ''; this.lineInterval = 7;// px, межстрочный интервал @@ -243,34 +278,20 @@ class TextPage extends Vue { this.parsed = parsed; this.calcDrawProps(); - //загрузка дин.шрифта - if (this.fontCssUrl) - loadCSS(this.fontCssUrl); + await this.loadFonts(); - const waitingTime = 10*1000; - const delay = 100; - let i = 0; - this.fontsLoading = true; - //ждем шрифты - while (i < waitingTime/delay) { - i++; - try { - await this.loadFonts(); - i = waitingTime; - } catch (e) { - await sleep(delay); - } - } - this.fontsLoading = false; - if (i !== waitingTime) { - this.$notify.error({ - title: 'Ошибка загрузки', - message: 'Некоторые шрифты не удалось загрузить' - }); - } - - this.draw(); + this.draw(true); this.refreshTime(); + + // шрифты хрен знает когда подгружаются, поэтому + let i = 0; + this.parsed.force = true; + while (i < 10) { + this.draw(true); + await sleep(1000); + i++; + } + this.parsed.force = false; })(); } } @@ -294,10 +315,10 @@ class TextPage extends Vue { return; } - this.activeCanvas = !this.activeCanvas; + this.toggleLayout = !this.toggleLayout; - if (immediate) { - if (this.activeCanvas) + if (immediate || (this.parsed && this.parsed.force)) { + if (this.toggleLayout) this.page1 = this.drawPage(this.bookPos); else this.page2 = this.drawPage(this.bookPos); @@ -308,7 +329,7 @@ class TextPage extends Vue { this.pagePrepared = false; this.debouncedPrepareNextPage(); } else { - if (this.activeCanvas) + if (this.toggleLayout) this.page1 = this.drawPage(this.bookPos); else this.page2 = this.drawPage(this.bookPos); @@ -477,7 +498,7 @@ class TextPage extends Vue { if (i >= 0 && this.linesDown.length > i) { this.bookPosPrepared = this.linesDown[i].begin; - if (this.activeCanvas) + if (this.toggleLayout) this.page2 = this.drawPage(this.bookPosPrepared, true);//наоборот else this.page1 = this.drawPage(this.bookPosPrepared, true); diff --git a/client/components/Reader/share/BookParser.js b/client/components/Reader/share/BookParser.js index a9faa271..4f35a2db 100644 --- a/client/components/Reader/share/BookParser.js +++ b/client/components/Reader/share/BookParser.js @@ -346,7 +346,8 @@ export default class BookParser { parsePara(paraIndex) { const para = this.para[paraIndex]; - if (para.parsed && + if (!this.force && + para.parsed && para.parsed.w === this.w && para.parsed.p === this.p && para.parsed.wordWrap === this.wordWrap && diff --git a/client/components/fonts/rubik.woff2 b/client/components/fonts/rubik.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..0ab2f0cdd39d7d83bff3cdcc1f30001a87c51a5a GIT binary patch literal 10656 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