TextPage.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <template>
  2. <div ref="main" class="main">
  3. <!--pre>{{ meta }}</pre-->
  4. <p v-for="item in items" :key="item.id">
  5. <pre>{{ item.text }}</pre>
  6. </p>
  7. </div>
  8. </template>
  9. <script>
  10. //-----------------------------------------------------------------------------
  11. import Vue from 'vue';
  12. import Component from 'vue-class-component';
  13. import _ from 'lodash';
  14. import bookManager from '../share/bookManager';
  15. export default @Component({
  16. watch: {
  17. bookPos: function(newValue) {
  18. this.debouncedEmitPosChange(newValue);
  19. this.drawPage();
  20. },
  21. },
  22. })
  23. class TextPage extends Vue {
  24. lastBook = null;
  25. bookPos = 0;
  26. //убрать
  27. meta = null;
  28. items = null;
  29. created() {
  30. this.commit = this.$store.commit;
  31. this.dispatch = this.$store.dispatch;
  32. this.config = this.$store.state.config;
  33. this.reader = this.$store.state.reader;
  34. this.debouncedEmitPosChange = _.debounce((newValue) => {
  35. this.$emit('book-pos-changed', {bookPos: newValue});
  36. }, 100);
  37. }
  38. showBook() {
  39. this.$refs.main.focus();
  40. this.book = null;
  41. this.meta = null;
  42. this.fb2 = null;
  43. this.parsed = null;
  44. this.linesUp = null;
  45. this.linesDown = null;
  46. this.pageLineCount = 0;
  47. this.drawPage();//пока не загрузили, очистим канвас
  48. if (this.lastBook) {
  49. (async() => {
  50. const isParsed = await bookManager.hasBookParsed(this.lastBook);
  51. if (!isParsed) {
  52. return;
  53. }
  54. this.book = await bookManager.getBook(this.lastBook);
  55. this.meta = bookManager.metaOnly(this.book);
  56. this.fb2 = this.meta.fb2;
  57. this.$root.$emit('set-app-title', _.compact([
  58. this.fb2.lastName,
  59. this.fb2.middleName,
  60. this.fb2.firstName,
  61. '-',
  62. this.fb2.bookTitle
  63. ]).join(' '));
  64. this.pageLineCount = 30;
  65. const parsed = this.book.parsed;
  66. parsed.p = 30;//px, отступ параграфа
  67. parsed.w = 300;//px, ширина страницы
  68. parsed.measureText = (text, style) => {
  69. if (style == 'bold')
  70. return text.length*12;
  71. else
  72. return text.length*3;
  73. };
  74. this.parsed = parsed;
  75. this.drawPage();
  76. })();
  77. }
  78. }
  79. drawPage() {
  80. if (!this.lastBook)
  81. return;
  82. //пустой канвас
  83. this.items = [];
  84. if (!this.book)
  85. return;
  86. const lines = this.parsed.getLines(this.bookPos, this.pageLineCount + 1);
  87. let newItems = [];
  88. let len = lines.length;
  89. len = (len > this.pageLineCount ? len = this.pageLineCount : len);
  90. for (let i = 0; i < len; i++) {
  91. const line = lines[i];
  92. /* line:
  93. {
  94. begin: Number,
  95. end: Number,
  96. parts: array of {
  97. style: 'bold'|'italic',
  98. text: String,
  99. }
  100. }*/
  101. const item = {text: '', id: line.begin};
  102. for (const part of line.parts) {
  103. item.text += part.text;
  104. }
  105. newItems.push(item);
  106. }
  107. this.items = newItems;
  108. this.linesUp = this.parsed.getLines(this.bookPos, -(this.pageLineCount + 1));
  109. this.linesDown = lines;
  110. }
  111. pageDown() {
  112. let i = this.pageLineCount;
  113. i--;
  114. if (this.linesDown && this.linesDown.length > i) {
  115. this.bookPos = this.linesDown[i].begin;
  116. }
  117. }
  118. pageUp() {
  119. let i = this.pageLineCount;
  120. i--;
  121. i = (i > this.linesUp.length - 1 ? this.linesUp.length - 1 : i);
  122. if (this.linesUp && this.linesUp.length > i) {
  123. this.bookPos = this.linesUp[i].begin;
  124. }
  125. }
  126. keyHook(event) {
  127. if (event.type == 'keydown') {
  128. switch (event.key) {
  129. case 'PageDown':
  130. this.pageDown();
  131. break;
  132. case 'PageUp':
  133. this.pageUp();
  134. break;
  135. }
  136. }
  137. }
  138. }
  139. //-----------------------------------------------------------------------------
  140. </script>
  141. <style scoped>
  142. .main {
  143. flex: 1;
  144. display: flex;
  145. flex-direction: column;
  146. }
  147. pre {
  148. margin: 0;
  149. padding: 0;
  150. }
  151. p {
  152. margin: 0;
  153. padding: 0;
  154. }
  155. </style>