فهرست منبع

Добавил выравнивание текста по ширине

Book Pauk 6 سال پیش
والد
کامیت
966e01cf88
2فایلهای تغییر یافته به همراه52 افزوده شده و 17 حذف شده
  1. 35 9
      client/components/Reader/TextPage/TextPage.vue
  2. 17 8
      client/components/Reader/share/BookParser.js

+ 35 - 9
client/components/Reader/TextPage/TextPage.vue

@@ -45,7 +45,7 @@ class TextPage extends Vue {
         this.context.textAlign = 'left';
     }
 
-    updateCanvasSize() {
+    calcDrawProps() {
         this.canvas.width = this.$refs.main.clientWidth;
         this.canvas.height = this.$refs.main.clientHeight;
         this.lineHeight = this.fontSize + this.lineInterval;
@@ -63,15 +63,16 @@ class TextPage extends Vue {
         this.linesDown = null;
         this.pageLineCount = 0;
 
-        //canvas props
+        //draw props
         this.textColor = 'black';
         this.backgroundColor = '#478355';
         this.fontStyle = '';// 'bold','italic'
         this.fontSize = 20;// px
         this.fontName = 'arial';
         this.lineInterval = 5;// px
+        this.textAlignJustify = true;
 
-        this.updateCanvasSize();
+        this.calcDrawProps();
         this.drawPage();// пока не загрузили, очистим канвас
 
         if (this.lastBook) {
@@ -92,13 +93,15 @@ class TextPage extends Vue {
                     this.fb2.bookTitle
                 ]).join(' '));
 
-                this.updateCanvasSize();
+                this.calcDrawProps();
                 const parsed = this.book.parsed;
                 parsed.p = 30;// px, отступ параграфа
                 parsed.w = this.canvas.width;// px, ширина страницы
+                parsed.font = this.font;
                 parsed.measureText = (text, style) => {// eslint-disable-line no-unused-vars
                     return this.context.measureText(text).width;
-                };                
+                };
+                this.measureText = parsed.measureText;
 
                 this.parsed = parsed;
                 this.drawPage();
@@ -106,6 +109,10 @@ class TextPage extends Vue {
         }
     }
 
+    get font() {
+        return `${this.fontStyle} ${this.fontSize}px ${this.fontName}`;
+    }
+
     drawPage() {
         if (!this.lastBook)
             return;
@@ -114,15 +121,15 @@ class TextPage extends Vue {
         const canvas = this.canvas;
         const context = this.context;
 
-        context.font = `${this.fontStyle} ${this.fontSize}px ${this.fontName}`;
-
         context.fillStyle = this.backgroundColor;
         context.fillRect(0, 0, canvas.width, canvas.height);
 
         if (!this.book)
             return;
 
+        context.font = this.font;
         context.fillStyle = this.textColor;
+        const spaceWidth = this.context.measureText(' ').width;
 
         const lines = this.parsed.getLines(this.bookPos, this.pageLineCount + 1);
 
@@ -135,7 +142,8 @@ class TextPage extends Vue {
             {
                 begin: Number,
                 end: Number,
-                para: Boolean,
+                paraBegin: Boolean,
+                paraEnd: Boolean,
                 parts: array of {
                     style: 'bold'|'italic',
                     text: String,
@@ -148,7 +156,25 @@ class TextPage extends Vue {
             }
 
             y += this.lineHeight;
-            context.fillText(text, 0, y);
+            let filled = false;
+            if (this.textAlignJustify && !line.paraEnd) {
+                const words = text.split(' ');
+                if (words.length > 1) {
+                    let space = canvas.width - line.width + spaceWidth*(words.length - 1);
+                    space = space/(words.length - 1);
+
+                    let x = 0;
+                    for (const word of words) {
+                        context.fillText(word, x, y);
+                        x += this.measureText(word) + space;
+                    }
+                    filled = true;
+                }
+            }
+
+            if (!filled)
+                context.fillText(text, 0, y);
+            
         }
 
         this.linesUp = this.parsed.getLines(this.bookPos, -(this.pageLineCount + 1));

+ 17 - 8
client/components/Reader/share/BookParser.js

@@ -236,15 +236,16 @@ export default class BookParser {
         if (para.parsed && 
             para.parsed.w === this.w &&
             para.parsed.p === this.p &&
-            para.parsed.textAlignJustify === this.textAlignJustify &&
-            para.parsed.wordWrap === this.wordWrap)
+            para.parsed.wordWrap === this.wordWrap &&
+            para.parsed.font === this.font
+            )
             return para.parsed;
 
         const parsed = {
             w: this.w,
             p: this.p,
-            textAlignJustify: this.textAlignJustify,
-            wordWrap: this.wordWrap
+            wordWrap: this.wordWrap,
+            font: this.font,
         };
 
         const lines = [];
@@ -252,7 +253,8 @@ export default class BookParser {
         {
             begin: Number,
             end: Number,
-            para: Boolean,
+            paraBegin: Boolean,
+            paraEnd: Boolean,
             parts: array of {
                 style: 'bold'|'italic',
                 text: String,
@@ -265,29 +267,36 @@ export default class BookParser {
         let line = {begin: para.offset, parts: []};
         let prevPart = '';
         let part = '';
+        let prevW = 0;
         let k = 0;
         // тут начинается самый замес, перенос и стилизация
         for (let i = 0; i < words.length; i++) {
             const word = words[i];
             part += word;
 
-            if (this.measureText(part) > parsed.w) {
+            let w = this.measureText(part);
+            if (w > parsed.w) {
                 line.parts.push({style: '', text: prevPart});
                 line.end = line.begin + prevPart.length;//нет -1 !!!
-                line.para = (k == 0);
+                line.width = prevW;
+                line.paraBegin = (k == 0);
+                line.paraEnd = false;
                 lines.push(line);
 
                 line = {begin: line.end + 1, parts: []};
                 part = word;
                 k++;
             }
+            prevW = w;
             prevPart = part;
             part += ' ';
         }
 
         line.parts.push({style: '', text: prevPart});
         line.end = line.begin + prevPart.length - 1;
-        line.para = (k == 0);
+        line.width = prevW;
+        line.paraBegin = (k == 0);
+        line.paraEnd = true;
         lines.push(line);
 
         parsed.lines = lines;