Рефакторинг

This commit is contained in:
Book Pauk
2020-12-23 21:17:39 +07:00
parent 48612ee118
commit 17c14722fd
2 changed files with 115 additions and 79 deletions

View File

@@ -228,28 +228,31 @@ class TextPage extends Vue {
//parsed //parsed
if (this.parsed) { if (this.parsed) {
this.parsed.p = this.p; this.testText = 'Это тестовый текст. Его ширина выдается системой неправильно некоторое время.';
this.parsed.w = this.w;// px, ширина текста
this.parsed.font = this.font;
this.parsed.fontSize = this.fontSize;
this.parsed.wordWrap = this.wordWrap;
this.parsed.cutEmptyParagraphs = this.cutEmptyParagraphs;
this.parsed.addEmptyParagraphs = this.addEmptyParagraphs;
let t = wideLetter;
if (!this.drawHelper.measureText(t, {}))
throw new Error('Ошибка measureText');
while (this.drawHelper.measureText(t, {}) < this.w) t += wideLetter;
this.parsed.maxWordLength = t.length - 1;
this.parsed.measureText = this.drawHelper.measureText.bind(this.drawHelper);
this.parsed.lineHeight = this.lineHeight;
this.parsed.showImages = this.showImages;
this.parsed.showInlineImagesInCenter = this.showInlineImagesInCenter;
this.parsed.imageHeightLines = this.imageHeightLines;
this.parsed.imageFitWidth = this.imageFitWidth;
this.parsed.compactTextPerc = this.compactTextPerc;
this.parsed.testText = 'Это тестовый текст. Его ширина выдается системой неверно некоторое время.'; let wideLine = wideLetter;
this.parsed.testWidth = this.drawHelper.measureText(this.parsed.testText, {}); if (!this.drawHelper.measureText(wideLine, {}))
throw new Error('Ошибка measureText');
while (this.drawHelper.measureText(wideLine, {}) < this.w) wideLine += wideLetter;
this.parsed.setSettings({
p: this.p,
w: this.w,
font: this.font,
fontSize: this.fontSize,
wordWrap: this.wordWrap,
cutEmptyParagraphs: this.cutEmptyParagraphs,
addEmptyParagraphs: this.addEmptyParagraphs,
maxWordLength: wideLine.length - 1,
lineHeight: this.lineHeight,
showImages: this.showImages,
showInlineImagesInCenter: this.showInlineImagesInCenter,
imageHeightLines: this.imageHeightLines,
imageFitWidth: this.imageFitWidth,
compactTextPerc: this.compactTextPerc,
testWidth: this.drawHelper.measureText(this.testText, {}),
measureText: this.drawHelper.measureText.bind(this.drawHelper),
});
} }
//scrolling page //scrolling page
@@ -333,19 +336,25 @@ class TextPage extends Vue {
if (!omitLoadFonts) if (!omitLoadFonts)
await this.loadFonts(); await this.loadFonts();
if (omitLoadFonts) {
this.draw(); this.draw();
} else {
// ширина шрифта некоторое время выдается неверно, поэтому // ширина шрифта некоторое время выдается неверно,
if (!omitLoadFonts) { // не получилось событийно отловить этот момент, поэтому костыль
const parsed = this.parsed; const parsed = this.parsed;
let i = 0; let i = 0;
const t = this.parsed.testText; const t = this.testText;
while (i++ < 50 && this.parsed === parsed && this.drawHelper.measureText(t, {}) === this.parsed.testWidth) const tw = this.drawHelper.measureText(t, {});
//5 секунд проверяем изменения шрифта
while (i++ < 50 && this.parsed === parsed && this.drawHelper.measureText(t, {}) === tw) {
if (i == 10) //через 1 сек
this.draw();
await utils.sleep(100); await utils.sleep(100);
}
if (this.parsed === parsed) { if (this.parsed === parsed) {
this.parsed.testWidth = this.drawHelper.measureText(t, {}); this.parsed.setSettings({testWidth: this.drawHelper.measureText(t, {})});
this.draw(); this.draw();
} }
} }

View File

@@ -4,21 +4,42 @@ import * as utils from '../../../share/utils';
const maxImageLineCount = 100; const maxImageLineCount = 100;
// defaults
const defaultSettings = {
p: 30, //px, отступ параграфа
w: 500, //px, ширина страницы
font: '', //css описание шрифта
fontSize: 20, //px, размер шрифта
wordWrap: false, //перенос по слогам
cutEmptyParagraphs: false, //убирать пустые параграфы
addEmptyParagraphs: 0, //добавлять n пустых параграфов перед непустым
maxWordLength: 500, //px, максимальная длина слова без пробелов
lineHeight: 26, //px, высота строки
showImages: true, //показыввать изображения
showInlineImagesInCenter: true, //выносить изображения в центр, работает на этапе первичного парсинга (parse)
imageHeightLines: 100, //кол-во строк, максимальная высота изображения
imageFitWidth: true, //ширина изображения не более ширины страницы
compactTextPerc: 0, //проценты, степень компактности текста
testWidth: 0, //ширина тестовой строки, пересчитывается извне при изменении шрифта браузером
//заглушка, измеритель ширины текста
measureText: (text, style) => {// eslint-disable-line no-unused-vars
return text.length*20;
},
};
export default class BookParser { export default class BookParser {
constructor(settings) { constructor(settings = {}) {
if (settings) { this.sets = {};
this.showInlineImagesInCenter = settings.showInlineImagesInCenter;
this.setSettings(defaultSettings);
this.setSettings(settings);
} }
// defaults setSettings(settings = {}) {
this.p = 30;// px, отступ параграфа this.sets = Object.assign({}, this.sets, settings);
this.w = 300;// px, ширина страницы this.measureText = this.sets.measureText;
this.wordWrap = false;// перенос по слогам
//заглушка
this.measureText = (text, style) => {// eslint-disable-line no-unused-vars
return text.length*20;
};
} }
async parse(data, callback) { async parse(data, callback) {
@@ -210,14 +231,14 @@ export default class BookParser {
if (href[0] == '#') {//local if (href[0] == '#') {//local
imageNum++; imageNum++;
if (inPara && !this.showInlineImagesInCenter && !center) if (inPara && !this.sets.showInlineImagesInCenter && !center)
growParagraph(`<image-inline href="${href}" num="${imageNum}"></image-inline>`, 0); growParagraph(`<image-inline href="${href}" num="${imageNum}"></image-inline>`, 0);
else else
newParagraph(`<image href="${href}" num="${imageNum}">${' '.repeat(maxImageLineCount)}</image>`, maxImageLineCount); newParagraph(`<image href="${href}" num="${imageNum}">${' '.repeat(maxImageLineCount)}</image>`, maxImageLineCount);
this.images.push({paraIndex, num: imageNum, id, local, alt}); this.images.push({paraIndex, num: imageNum, id, local, alt});
if (inPara && this.showInlineImagesInCenter) if (inPara && this.sets.showInlineImagesInCenter)
newParagraph(' ', 1); newParagraph(' ', 1);
} else {//external } else {//external
imageNum++; imageNum++;
@@ -632,7 +653,7 @@ export default class BookParser {
}); });
//длинные слова (или белиберду без пробелов) тоже разобьем //длинные слова (или белиберду без пробелов) тоже разобьем
const maxWordLength = this.maxWordLength; const maxWordLength = this.sets.maxWordLength;
const parts = result; const parts = result;
result = []; result = [];
for (const part of parts) { for (const part of parts) {
@@ -712,37 +733,43 @@ export default class BookParser {
parsePara(paraIndex) { parsePara(paraIndex) {
const para = this.para[paraIndex]; const para = this.para[paraIndex];
const s = this.sets;
//перераспарсиваем только при изменении одного из параметров
if (!this.force && if (!this.force &&
para.parsed && para.parsed &&
para.parsed.testWidth === this.testWidth && para.parsed.p === s.p &&
para.parsed.w === this.w && para.parsed.w === s.w &&
para.parsed.p === this.p && para.parsed.font === s.font &&
para.parsed.wordWrap === this.wordWrap && para.parsed.fontSize === s.fontSize &&
para.parsed.maxWordLength === this.maxWordLength && para.parsed.wordWrap === s.wordWrap &&
para.parsed.font === this.font && para.parsed.cutEmptyParagraphs === s.cutEmptyParagraphs &&
para.parsed.cutEmptyParagraphs === this.cutEmptyParagraphs && para.parsed.addEmptyParagraphs === s.addEmptyParagraphs &&
para.parsed.addEmptyParagraphs === this.addEmptyParagraphs && para.parsed.maxWordLength === s.maxWordLength &&
para.parsed.showImages === this.showImages && para.parsed.lineHeight === s.lineHeight &&
para.parsed.imageHeightLines === this.imageHeightLines && para.parsed.showImages === s.showImages &&
para.parsed.imageFitWidth === this.imageFitWidth && para.parsed.imageHeightLines === s.imageHeightLines &&
para.parsed.compactTextPerc === this.compactTextPerc para.parsed.imageFitWidth === s.imageFitWidth &&
para.parsed.compactTextPerc === s.compactTextPerc &&
para.parsed.testWidth === s.testWidth
) )
return para.parsed; return para.parsed;
const parsed = { const parsed = {
testWidth: this.testWidth, p: s.p,
w: this.w, w: s.w,
p: this.p, font: s.font,
wordWrap: this.wordWrap, fontSize: s.fontSize,
maxWordLength: this.maxWordLength, wordWrap: s.wordWrap,
font: this.font, cutEmptyParagraphs: s.cutEmptyParagraphs,
cutEmptyParagraphs: this.cutEmptyParagraphs, addEmptyParagraphs: s.addEmptyParagraphs,
addEmptyParagraphs: this.addEmptyParagraphs, maxWordLength: s.maxWordLength,
showImages: this.showImages, lineHeight: s.lineHeight,
imageHeightLines: this.imageHeightLines, showImages: s.showImages,
imageFitWidth: this.imageFitWidth, imageHeightLines: s.imageHeightLines,
compactTextPerc: this.compactTextPerc, imageFitWidth: s.imageFitWidth,
compactTextPerc: s.compactTextPerc,
testWidth: s.testWidth,
visible: true, //вычисляется позже visible: true, //вычисляется позже
}; };
@@ -774,7 +801,7 @@ export default class BookParser {
let ofs = 0;//смещение от начала параграфа para.offset let ofs = 0;//смещение от начала параграфа para.offset
let imgW = 0; let imgW = 0;
let imageInPara = false; let imageInPara = false;
const compactWidth = this.measureText('W', {})*this.compactTextPerc/100; const compactWidth = this.measureText('W', {})*parsed.compactTextPerc/100;
// тут начинается самый замес, перенос по слогам и стилизация, а также изображения // тут начинается самый замес, перенос по слогам и стилизация, а также изображения
for (const part of parts) { for (const part of parts) {
style = part.style; style = part.style;
@@ -787,14 +814,14 @@ export default class BookParser {
if (!bin) if (!bin)
bin = {h: 1, w: 1}; bin = {h: 1, w: 1};
let lineCount = this.imageHeightLines; let lineCount = parsed.imageHeightLines;
let c = Math.ceil(bin.h/this.lineHeight); let c = Math.ceil(bin.h/parsed.lineHeight);
const maxH = lineCount*this.lineHeight; const maxH = lineCount*parsed.lineHeight;
let maxH2 = maxH; let maxH2 = maxH;
if (this.imageFitWidth && bin.w > this.w) { if (parsed.imageFitWidth && bin.w > this.w) {
maxH2 = bin.h*this.w/bin.w; maxH2 = bin.h*this.w/bin.w;
c = Math.ceil(maxH2/this.lineHeight); c = Math.ceil(maxH2/parsed.lineHeight);
} }
lineCount = (c < lineCount ? c : lineCount); lineCount = (c < lineCount ? c : lineCount);
@@ -834,10 +861,10 @@ export default class BookParser {
continue; continue;
} }
if (part.image.id && part.image.inline && this.showImages) { if (part.image.id && part.image.inline && parsed.showImages) {
const bin = this.binary[part.image.id]; const bin = this.binary[part.image.id];
if (bin) { if (bin) {
let imgH = (bin.h > this.fontSize ? this.fontSize : bin.h); let imgH = (bin.h > parsed.fontSize ? parsed.fontSize : bin.h);
imgW += bin.w*imgH/bin.h; imgW += bin.w*imgH/bin.h;
line.parts.push({style, text: '', line.parts.push({style, text: '',
image: {local: part.image.local, inline: true, id: part.image.id, num: part.image.num}}); image: {local: part.image.local, inline: true, id: part.image.id, num: part.image.num}});
@@ -952,11 +979,11 @@ export default class BookParser {
//parsed.visible //parsed.visible
if (imageInPara) { if (imageInPara) {
parsed.visible = this.showImages; parsed.visible = parsed.showImages;
} else { } else {
parsed.visible = !( parsed.visible = !(
(para.addIndex > this.addEmptyParagraphs) || (para.addIndex > parsed.addEmptyParagraphs) ||
(para.addIndex == 0 && this.cutEmptyParagraphs && paragraphText.trim() == '') (para.addIndex == 0 && parsed.cutEmptyParagraphs && paragraphText.trim() == '')
); );
} }