From 049c77a004822e0cb2fb9d204b94bbe2f2baf9b1 Mon Sep 17 00:00:00 2001 From: Matthieu CAILLEAUX Date: Wed, 27 Apr 2022 23:36:15 +0200 Subject: [PATCH] feat: add mobile css --- src/abstract-builder.ts | 2 + src/elements/abstract-container-element.ts | 35 ++ src/elements/abstract-element.ts | 19 +- src/elements/blank.ts | 11 +- src/elements/box.ts | 12 +- src/elements/column.ts | 41 +- src/elements/context.ts | 5 + src/elements/image.ts | 18 +- src/elements/labelled-text.ts | 14 +- src/elements/labelled-value.ts | 19 +- src/elements/labelled-values.ts | 24 +- src/elements/multiline-text.ts | 8 +- src/elements/row.ts | 32 +- src/elements/separator.ts | 11 +- src/elements/text.ts | 8 +- src/elements/texts.ts | 17 +- src/html-builder.ts | 51 +- src/main.ts | 625 +++++++++++++-------- src/pdf-builder.ts | 6 +- 19 files changed, 639 insertions(+), 319 deletions(-) create mode 100644 src/elements/abstract-container-element.ts create mode 100644 src/elements/context.ts diff --git a/src/abstract-builder.ts b/src/abstract-builder.ts index 66283e5..900f47b 100644 --- a/src/abstract-builder.ts +++ b/src/abstract-builder.ts @@ -6,4 +6,6 @@ export abstract class AbstractBuilder { public abstract getLabelledRowHeight(): number; public abstract save(name: string); + + public abstract getImageScale(): number; } diff --git a/src/elements/abstract-container-element.ts b/src/elements/abstract-container-element.ts new file mode 100644 index 0000000..3aea4f4 --- /dev/null +++ b/src/elements/abstract-container-element.ts @@ -0,0 +1,35 @@ +import { AbstractElement } from './abstract-element'; +import { IContext } from './context'; + +export abstract class AbstractContainerElement extends AbstractElement { + public pdfElements: AbstractElement[] = []; + public htmlElements: AbstractElement[] = []; + public contextElements: AbstractElement[] = []; + + constructor( + x: number, + y: number, + maxWidth: number | undefined, + elements: AbstractElement[] = [], + context: Partial = AbstractElement.DEFAULT_CONTEXT + ) { + super(x, y, maxWidth, context); + this.htmlElements = this.context.isHtml + ? elements.filter((el) => el.context.isHtml) + : []; + this.pdfElements = this.context.isPdf + ? elements.filter((el) => el.context.isPdf) + : []; + this.contextElements = this.context.isHtml + ? this.htmlElements + : this.pdfElements; + } + + public getElements(): AbstractElement[] { + const elements: AbstractElement[] = []; + for (const element of this.contextElements) { + elements.push(...element.getElements()); + } + return elements; + } +} diff --git a/src/elements/abstract-element.ts b/src/elements/abstract-element.ts index aeb80d5..4ab7ae2 100644 --- a/src/elements/abstract-element.ts +++ b/src/elements/abstract-element.ts @@ -1,15 +1,32 @@ import jsPDF from 'jspdf'; import { MARGINS } from '../constants'; +import { IContext } from './context'; export abstract class AbstractElement { + public static readonly DEFAULT_CONTEXT: IContext = { + isHtml: true, + isPdf: true, + name: 'element', + }; + public x: number; public y: number; public maxWidth?: number; + public context: IContext = AbstractElement.DEFAULT_CONTEXT; - constructor(x: number, y: number, maxWidth?: number | undefined) { + constructor( + x: number, + y: number, + maxWidth?: number | undefined, + context: Partial = AbstractElement.DEFAULT_CONTEXT + ) { this.x = x >= MARGINS.left ? x : MARGINS.left; this.y = y >= MARGINS.top ? y : MARGINS.top; this.maxWidth = maxWidth; + this.context = { + ...this.context, + ...context, + }; } public getHeightFromPx(doc: jsPDF, size: number) { diff --git a/src/elements/blank.ts b/src/elements/blank.ts index f8da391..ccf4370 100644 --- a/src/elements/blank.ts +++ b/src/elements/blank.ts @@ -1,10 +1,17 @@ import { AbstractElement } from './abstract-element'; import jsPDF from 'jspdf'; import { Box } from './box'; +import { IContext } from './context'; export class Blank extends Box { - constructor(x: number, y: number, w: number, h: number) { - super(x, y, w, h); + constructor( + x: number, + y: number, + w: number, + h: number, + context: Partial = AbstractElement.DEFAULT_CONTEXT + ) { + super(x, y, w, h, context); } public static heightBlank(h: number) { diff --git a/src/elements/box.ts b/src/elements/box.ts index cd059f8..253ad1b 100644 --- a/src/elements/box.ts +++ b/src/elements/box.ts @@ -1,12 +1,19 @@ import { AbstractElement } from './abstract-element'; import jsPDF from 'jspdf'; +import { IContext } from './context'; export class Box extends AbstractElement { public w: number; public h: number; - constructor(x: number, y: number, w: number, h: number) { - super(x, y, w); + constructor( + x: number, + y: number, + w: number, + h: number, + context: Partial = AbstractElement.DEFAULT_CONTEXT + ) { + super(x, y, w, context); this.w = w; this.h = h; } @@ -30,6 +37,7 @@ export class Box extends AbstractElement { const css = `box-${this.w ?? 0}-${this.h ?? 0}`; div.classList.add(`box`); div.classList.add(css); + div.classList.add(this.context.name); if (!cssRules.includes(css)) { cssRules.push(css); let rule = 'width: 100%;'; diff --git a/src/elements/column.ts b/src/elements/column.ts index 4af3854..58876ca 100644 --- a/src/elements/column.ts +++ b/src/elements/column.ts @@ -1,16 +1,20 @@ import { AbstractElement } from './abstract-element'; import jsPDF from 'jspdf'; +import { IContext } from './context'; +import { AbstractContainerElement } from './abstract-container-element'; -export class Column extends AbstractElement { - public elements: AbstractElement[] = []; - - constructor(x: number, y: number, elements: AbstractElement[]) { - super(x, y); - this.elements = elements; +export class Column extends AbstractContainerElement { + constructor( + x: number, + y: number, + elements: AbstractElement[], + context: Partial = AbstractElement.DEFAULT_CONTEXT + ) { + super(x, y, undefined, elements, context); } public prepareRender(doc: jsPDF, _maxWidth?: number): jsPDF { - const elements = this.elements ?? []; + const elements = this.pdfElements ?? []; let currentY = this.y; for (let i = 0; i < elements.length; i++) { @@ -37,7 +41,8 @@ export class Column extends AbstractElement { ): Document { const div = doc.createElement('div'); div.classList.add(`column`); - const elements = this.elements ?? []; + div.classList.add(this.context.name); + const elements = this.htmlElements ?? []; for (let i = 0; i < elements.length; i++) { const element = elements[i]; element.renderHtml(doc, div, cssRules, sheet); @@ -47,8 +52,8 @@ export class Column extends AbstractElement { } public getHeight(doc): number { - return this.elements.length > 0 - ? this.elements + return this.pdfElements.length > 0 + ? this.pdfElements .map((e) => e.getHeight(doc)) .reduce((p, c, i) => { if (i === 0) { @@ -60,20 +65,8 @@ export class Column extends AbstractElement { } public getCheckNewPageHeight(doc?: jsPDF): number { - return this.elements.length > 0 - ? this.elements[0].getCheckNewPageHeight(doc) + return this.pdfElements.length > 0 + ? this.pdfElements[0].getCheckNewPageHeight(doc) : 0; } - - public getElements(): AbstractElement[] { - const elements: AbstractElement[] = []; - for (const element of this.elements) { - elements.push(...element.getElements()); - } - return elements; - } - - public isEmpty(): boolean { - return this.elements.length === 0; - } } diff --git a/src/elements/context.ts b/src/elements/context.ts new file mode 100644 index 0000000..e5e84a0 --- /dev/null +++ b/src/elements/context.ts @@ -0,0 +1,5 @@ +export interface IContext { + name: string; + isHtml: boolean; + isPdf: boolean; +} diff --git a/src/elements/image.ts b/src/elements/image.ts index 86680f6..acb549f 100644 --- a/src/elements/image.ts +++ b/src/elements/image.ts @@ -1,12 +1,20 @@ import { Box } from './box'; import jsPDF from 'jspdf'; import { AbstractElement } from './abstract-element'; +import { IContext } from './context'; export class Image extends Box { public imageData: string; - constructor(x: number, y: number, w: number, h: number, imageData: string) { - super(x, y, w, h); + constructor( + x: number, + y: number, + w: number, + h: number, + imageData: string, + context: Partial = AbstractElement.DEFAULT_CONTEXT + ) { + super(x, y, w, h, context); this.imageData = imageData; } @@ -29,18 +37,16 @@ export class Image extends Box { ): Document { const img = doc.createElement('img'); img.src = this.imageData; - const css = `img-${this.w ?? 0}-${this.h ?? 0}`; + const css = `img-${this.w ?? 0}`; img.classList.add(`img`); img.classList.add(css); + img.classList.add(this.context.name); if (!cssRules.includes(css)) { cssRules.push(css); let rule = ''; if (this.w > 0) { rule += `width: ${this.w}px;`; } - if (this.h > 0) { - rule += `height: ${this.h}px;`; - } if (rule.length > 0) { sheet.innerHTML += ` .${css} { ${rule} }`; } diff --git a/src/elements/labelled-text.ts b/src/elements/labelled-text.ts index 92ceb5b..168fa50 100644 --- a/src/elements/labelled-text.ts +++ b/src/elements/labelled-text.ts @@ -8,6 +8,7 @@ import { TEXT_SIZE, } from '../constants'; import { AbstractElement } from './abstract-element'; +import { IContext } from './context'; export class LabelledText extends Text { public label: string; @@ -19,9 +20,10 @@ export class LabelledText extends Text { label: string, text: string, textOptions?: TextOptionsLight, - labelOptions?: TextOptionsLight + labelOptions?: TextOptionsLight, + context: Partial = AbstractElement.DEFAULT_CONTEXT ) { - super(x, y, text, textOptions); + super(x, y, text, textOptions, context); this.label = label; this.labelOptions = labelOptions; const textMaxWidth = this.textOptions?.maxWidth ?? 0; @@ -54,6 +56,8 @@ export class LabelledText extends Text { ): Document { const div = doc.createElement('div'); div.classList.add(`column`); + div.classList.add(`labelled-text`); + div.classList.add(this.context.name); const label = doc.createElement('p'); const text = doc.createElement('p'); const labelCss = `label-${LABEL_SIZE}`; @@ -62,11 +66,13 @@ export class LabelledText extends Text { text.classList.add(textCss); if (!cssRules.includes(labelCss)) { cssRules.push(labelCss); - sheet.innerHTML += ` .${labelCss} { font-size: ${HTML_LABEL_SIZE}rem }`; + sheet.innerHTML += ` .${labelCss} { font-size: ${HTML_LABEL_SIZE}rem; margin: 0; }`; } if (!cssRules.includes(textCss)) { cssRules.push(textCss); - sheet.innerHTML += ` .${textCss} { font-size: ${HTML_TEXT_SIZE}rem }`; + sheet.innerHTML += ` .${textCss} { font-size: ${HTML_TEXT_SIZE}rem; margin-top: 0.5rem; margin-bottom: 0.5rem; }`; + sheet.innerHTML += ` .labelled-text { margin-top: 0.5rem; margin-bottom: 0.5rem; }`; + sheet.innerHTML += ` .labelled-text > .${textCss} { font-size: ${HTML_TEXT_SIZE}rem; margin: 0; }`; } label.innerHTML = i18nLocalize(this.label); text.innerHTML = i18nLocalize(this.text); diff --git a/src/elements/labelled-value.ts b/src/elements/labelled-value.ts index 67bcfe8..0cd2fe3 100644 --- a/src/elements/labelled-value.ts +++ b/src/elements/labelled-value.ts @@ -1,6 +1,8 @@ import { Row } from './row'; import { Text } from './text'; import { MultilineText } from './multiline-text'; +import { IContext } from './context'; +import { AbstractElement } from './abstract-element'; export class LabelledValue extends Row { public label: string; @@ -11,7 +13,8 @@ export class LabelledValue extends Row { value: number, widthPercents?: number[], multiline = false, - maxWidth?: number + maxWidth?: number, + context: Partial = AbstractElement.DEFAULT_CONTEXT ) { super( 0, @@ -24,9 +27,21 @@ export class LabelledValue extends Row { ], maxWidth, widthPercents, - [] + [], + context ); this.label = label; this.value = value; } + + public renderHtml( + doc: Document, + parent: HTMLElement, + cssRules: string[], + sheet: HTMLStyleElement + ): Document { + const resultDoc = super.renderHtml(doc, parent, cssRules, sheet); + parent.lastElementChild?.classList?.add('labelled-value'); + return resultDoc; + } } diff --git a/src/elements/labelled-values.ts b/src/elements/labelled-values.ts index f1b7f05..712a11e 100644 --- a/src/elements/labelled-values.ts +++ b/src/elements/labelled-values.ts @@ -3,6 +3,8 @@ import { Column } from './column'; import { LabelledValue } from './labelled-value'; import jsPDF from 'jspdf'; import { MARGINS } from '../constants'; +import { IContext } from './context'; +import { AbstractElement } from './abstract-element'; export class LabelledValues extends Row { public labelledValues: { label: string; value: number }[]; @@ -13,9 +15,10 @@ export class LabelledValues extends Row { y: number, labelledValues: { label: string; value: number }[], nbrOfCol?: number, - multiline = false + multiline = false, + context: Partial = AbstractElement.DEFAULT_CONTEXT ) { - super(x, y, []); + super(x, y, [], undefined, undefined, undefined, context); this.labelledValues = labelledValues; this.nbrOfCol = nbrOfCol ?? 3; if (this.nbrOfCol > 3) { @@ -35,7 +38,9 @@ export class LabelledValues extends Row { rest > 2 ? nbrPerCol + 1 : nbrPerCol, ]; for (let i = 0; i < this.nbrOfCol; i++) { - this.elements[i] = new Column(0, 0, []); + this.contextElements[i] = new Column(0, 0, [], { + name: `${this.context.name}-column`, + }); } for (let i = 0; i < labelledValues.length; i++) { if (i < nbrPerCols[0]) { @@ -45,7 +50,7 @@ export class LabelledValues extends Row { } else { currentIndex = 2; } - (this.elements[currentIndex]).elements.push( + (this.contextElements[currentIndex]).contextElements.push( new LabelledValue( labelledValues[i].label, labelledValues[i].value, @@ -55,7 +60,7 @@ export class LabelledValues extends Row { ); } } else { - this.elements.push( + this.contextElements.push( new Column( 0, 0, @@ -67,7 +72,10 @@ export class LabelledValues extends Row { widthPercent, multiline ) - ) + ), + { + name: `${this.context.name}-column`, + } ) ); } @@ -77,8 +85,8 @@ export class LabelledValues extends Row { public prepareRender(doc: jsPDF, maxWidth?: number): jsPDF { const pageWidth = doc.internal.pageSize.width; const rowWidth = pageWidth - this.x - MARGINS.right; - for (const column of this.elements) { - for (const labelledValue of (column).elements) { + for (const column of this.pdfElements) { + for (const labelledValue of (column).pdfElements) { labelledValue.maxWidth = rowWidth / this.nbrOfCol; } } diff --git a/src/elements/multiline-text.ts b/src/elements/multiline-text.ts index e273f35..9a212b2 100644 --- a/src/elements/multiline-text.ts +++ b/src/elements/multiline-text.ts @@ -2,6 +2,7 @@ import { AbstractElement } from './abstract-element'; import jsPDF, { TextOptionsLight } from 'jspdf'; import { HTML_TEXT_SIZE, i18nLocalize, TEXT_SIZE } from '../constants'; import { Text } from './text'; +import { IContext } from './context'; export class MultilineText extends Text { private nbrLine = 1; @@ -10,9 +11,10 @@ export class MultilineText extends Text { x: number, y: number, text: string, - textOptions?: TextOptionsLight + textOptions?: TextOptionsLight, + context: Partial = AbstractElement.DEFAULT_CONTEXT ) { - super(x, y, text, textOptions); + super(x, y, text, textOptions, context); } public prepareRender(doc: jsPDF, maxWidth?: number): jsPDF { @@ -42,9 +44,11 @@ export class MultilineText extends Text { const css = `text-${TEXT_SIZE}`; text.classList.add(`multiline-text`); text.classList.add(css); + text.classList.add(this.context.name); if (!cssRules.includes(css)) { cssRules.push(css); sheet.innerHTML += ` .${css} { font-size: ${HTML_TEXT_SIZE}rem }`; + sheet.innerHTML += ` .labelled-text > .${css} { font-size: ${HTML_TEXT_SIZE}rem; margin: 0; }`; } text.innerHTML = i18nLocalize(this.text); parent.append(text); diff --git a/src/elements/row.ts b/src/elements/row.ts index 7c4c836..656cba2 100644 --- a/src/elements/row.ts +++ b/src/elements/row.ts @@ -1,9 +1,10 @@ import { AbstractElement } from './abstract-element'; import jsPDF from 'jspdf'; import { MARGINS } from '../constants'; +import { IContext } from './context'; +import { AbstractContainerElement } from './abstract-container-element'; -export class Row extends AbstractElement { - public elements: AbstractElement[] = []; +export class Row extends AbstractContainerElement { public widthPercents?: number[]; public maxWidths?: number[]; @@ -13,16 +14,16 @@ export class Row extends AbstractElement { elements: AbstractElement[], maxWidth?: number | undefined, widthPercents?: number[], - maxWidths?: number[] + maxWidths?: number[], + context: Partial = AbstractElement.DEFAULT_CONTEXT ) { - super(x, y, maxWidth); - this.elements = elements ?? []; + super(x, y, maxWidth, elements, context); this.widthPercents = widthPercents ?? []; this.maxWidths = maxWidths ?? []; } public prepareRender(doc: jsPDF, maxWidth?: number): jsPDF { - const elements = this.elements ?? []; + const elements = this.pdfElements ?? []; let maxWidths = this.maxWidths ?? []; let widthPercents = this.widthPercents ?? []; @@ -68,7 +69,8 @@ export class Row extends AbstractElement { ): Document { const div = doc.createElement('div'); div.classList.add(`row`); - const elements = this.elements ?? []; + div.classList.add(this.context.name); + const elements = this.htmlElements ?? []; for (let i = 0; i < elements.length; i++) { const element = elements[i]; element.renderHtml(doc, div, cssRules, sheet); @@ -79,7 +81,7 @@ export class Row extends AbstractElement { public getHeight(doc?: jsPDF): number { let maxHeight = 0; - for (const element of this.elements) { + for (const element of this.pdfElements) { maxHeight = Math.max(maxHeight, element.getHeight(doc)); } return maxHeight; @@ -87,21 +89,9 @@ export class Row extends AbstractElement { public getCheckNewPageHeight(doc?: jsPDF): number { let maxHeight = 0; - for (const element of this.elements) { + for (const element of this.pdfElements) { maxHeight = Math.max(maxHeight, element.getCheckNewPageHeight(doc)); } return maxHeight; } - - public getElements(): AbstractElement[] { - const elements: AbstractElement[] = []; - for (const element of this.elements) { - elements.push(...element.getElements()); - } - return elements; - } - - public isEmpty(): boolean { - return this.elements.length === 0; - } } diff --git a/src/elements/separator.ts b/src/elements/separator.ts index b2f41dd..519fe82 100644 --- a/src/elements/separator.ts +++ b/src/elements/separator.ts @@ -1,10 +1,16 @@ import { AbstractElement } from './abstract-element'; import jsPDF from 'jspdf'; import { MARGINS } from '../constants'; +import { IContext } from './context'; export class Separator extends AbstractElement { - constructor(x: number, y: number, maxWidth?: number | undefined) { - super(x, y, maxWidth); + constructor( + x: number, + y: number, + maxWidth?: number | undefined, + context: Partial = AbstractElement.DEFAULT_CONTEXT + ) { + super(x, y, maxWidth, context); } public getHeight(_doc?: jsPDF): number { @@ -41,6 +47,7 @@ export class Separator extends AbstractElement { ): Document { const div = doc.createElement('div'); div.classList.add(`separator`); + div.classList.add(this.context.name); parent.append(div); return doc; } diff --git a/src/elements/text.ts b/src/elements/text.ts index 0e164ec..a3211ec 100644 --- a/src/elements/text.ts +++ b/src/elements/text.ts @@ -1,6 +1,7 @@ import { AbstractElement } from './abstract-element'; import jsPDF, { TextOptionsLight } from 'jspdf'; import { HTML_TEXT_SIZE, i18nLocalize, TEXT_SIZE } from '../constants'; +import { IContext } from './context'; export class Text extends AbstractElement { public text: string; @@ -10,9 +11,10 @@ export class Text extends AbstractElement { x: number, y: number, text: string, - textOptions?: TextOptionsLight + textOptions?: TextOptionsLight, + context: Partial = AbstractElement.DEFAULT_CONTEXT ) { - super(x, y, textOptions?.maxWidth); + super(x, y, textOptions?.maxWidth, context); this.text = text; this.textOptions = textOptions; } @@ -46,10 +48,12 @@ export class Text extends AbstractElement { const css = `text-${TEXT_SIZE}`; text.classList.add(`ellipsis`); text.classList.add(css); + text.classList.add(this.context.name); text.innerHTML = i18nLocalize(i18nLocalize(this.text)); if (!cssRules.includes(css)) { cssRules.push(css); sheet.innerHTML += ` .${css} { font-size: ${HTML_TEXT_SIZE}rem }`; + sheet.innerHTML += ` .labelled-text > .${css} { font-size: ${HTML_TEXT_SIZE}rem; margin: 0; }`; } parent.append(text); return doc; diff --git a/src/elements/texts.ts b/src/elements/texts.ts index 32c353b..6314be0 100644 --- a/src/elements/texts.ts +++ b/src/elements/texts.ts @@ -4,6 +4,8 @@ import jsPDF from 'jspdf'; import { MARGINS } from '../constants'; import { Text } from './text'; import { MultilineText } from './multiline-text'; +import { IContext } from './context'; +import { AbstractElement } from './abstract-element'; export class Texts extends Row { public texts: string[]; @@ -14,9 +16,10 @@ export class Texts extends Row { y: number, texts: string[], nbrOfCol?: number, - multiline = false + multiline = false, + context: Partial = AbstractElement.DEFAULT_CONTEXT ) { - super(x, y, []); + super(x, y, [], undefined, undefined, undefined, context); this.texts = texts; this.nbrOfCol = nbrOfCol ?? 4; if (this.nbrOfCol > 4) { @@ -34,7 +37,7 @@ export class Texts extends Row { rest > 3 ? nbrPerCol + 1 : nbrPerCol, ]; for (let i = 0; i < this.nbrOfCol; i++) { - this.elements[i] = new Column(0, 0, []); + this.contextElements[i] = new Column(0, 0, []); } for (let i = 0; i < texts.length; i++) { if (i < nbrPerCols[0]) { @@ -46,7 +49,7 @@ export class Texts extends Row { } else { currentIndex = 3; } - (this.elements[currentIndex]).elements.push( + (this.contextElements[currentIndex]).contextElements.push( new Row(0, 0, [ multiline ? new MultilineText(0, 0, texts[i]) @@ -55,7 +58,7 @@ export class Texts extends Row { ); } } else { - this.elements.push( + this.contextElements.push( new Column( 0, 0, @@ -76,8 +79,8 @@ export class Texts extends Row { public prepareRender(doc: jsPDF, maxWidth?: number): jsPDF { const pageWidth = doc.internal.pageSize.width; const rowWidth = pageWidth - this.x - MARGINS.right; - for (const column of this.elements) { - for (const labelledValue of (column).elements) { + for (const column of this.pdfElements) { + for (const labelledValue of (column).pdfElements) { labelledValue.maxWidth = rowWidth / this.nbrOfCol; } } diff --git a/src/html-builder.ts b/src/html-builder.ts index a4b4c4a..1bf8c14 100644 --- a/src/html-builder.ts +++ b/src/html-builder.ts @@ -1,7 +1,13 @@ import { AbstractElement } from './elements/abstract-element'; import { AbstractBuilder } from './abstract-builder'; import { saveAs } from 'file-saver'; -import { i18n } from './constants'; +import { + HTML_LABEL_SIZE, + HTML_TEXT_SIZE, + i18n, + LABEL_SIZE, + TEXT_SIZE, +} from './constants'; export class HtmlBuilder extends AbstractBuilder { public doc: Document; @@ -12,16 +18,26 @@ export class HtmlBuilder extends AbstractBuilder { this.doc = document.implementation.createHTMLDocument(); const style = document.createElement('style'); style.innerHTML = '.column { display: flex; flex-direction: column; }'; + style.innerHTML += ' .main-column { align-items: center; }'; + style.innerHTML += ' .row { display: flex; flex-direction: row }'; + style.innerHTML += ' .row:not(.labelled-value) { gap: 5em; }'; style.innerHTML += - ' .row { display: flex; flex-direction: row; gap: 10px; }'; + ' .row.labelled-value { gap: 10px; justify-content: space-between; }'; style.innerHTML += ' .separator { border: 1px solid; width: 100%; height: 0px }'; style.appendChild(document.createTextNode('')); this.doc.head.appendChild(style); this.styleSheet = style; - const meta = document.createElement('meta'); - meta.setAttribute('charset', 'UTF-8'); - this.doc.head.appendChild(meta); + const meta1 = document.createElement('meta'); + meta1.setAttribute('charset', 'UTF-8'); + this.doc.head.appendChild(meta1); + const meta2 = document.createElement('meta'); + meta2.setAttribute('name', 'viewport'); + meta2.setAttribute( + 'content', + 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=yes' + ); + this.doc.head.appendChild(meta2); } public getLabelledRowHeight(): number { @@ -43,8 +59,31 @@ export class HtmlBuilder extends AbstractBuilder { public build(elements: AbstractElement[]) { const cssList: string[] = []; - for (const element of elements) { + for (const element of elements.filter((el) => el.context.isHtml)) { element.renderHtml(this.doc, this.doc.body, cssList, this.styleSheet); } + // Mobile start + this.styleSheet.innerHTML += ' @media screen and (max-width: 959px) {'; + this.styleSheet.innerHTML += ` .text-${TEXT_SIZE} { font-size: ${ + 2 * HTML_TEXT_SIZE + }rem; }`; + this.styleSheet.innerHTML += ` .labelled-text > .text-${TEXT_SIZE} { font-size: ${ + 2 * HTML_TEXT_SIZE + }rem; margin: 0; }`; + this.styleSheet.innerHTML += ` .label-${LABEL_SIZE} { font-size: ${ + 2 * HTML_LABEL_SIZE + }rem; }`; + this.styleSheet.innerHTML += + ' .main-column { align-items: stretch; overflow-x: hidden; }'; + this.styleSheet.innerHTML += + ' .row:not(.labelled-value) { flex-wrap: wrap; gap: 0 5em; }'; + this.styleSheet.innerHTML += ' .skills { width: 100%; }'; + this.styleSheet.innerHTML += ' .skills-column { width: 100%; }'; + this.styleSheet.innerHTML += ' }'; + // Mobile end + } + + public getImageScale(): number { + return 4; } } diff --git a/src/main.ts b/src/main.ts index 12fe30c..31b0852 100644 --- a/src/main.ts +++ b/src/main.ts @@ -104,20 +104,31 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) { value: item.data.data.total.value, }; }) - .sort((a, b) => a.label.localeCompare(b.label)) + .sort((a, b) => a.label.localeCompare(b.label)), + undefined, + false, + { name: 'skills' } ); + const talentsByName: { [name: string]: { count: number; test: string } } = {}; + + actor.itemCategories.talent.forEach((item) => { + const name = item.name; + if (talentsByName[name] == null) { + talentsByName[name] = { count: 1, test: item.data.data.tests.value }; + } else { + talentsByName[name].count++; + } + }); + const talents = new LabelledValues( 0, 0, - actor.itemCategories.talent - .map((item) => { + Object.entries(talentsByName) + .map(([name, value]) => { return { - label: - item.data.data.tests.value.length > 0 - ? `${item.name} : ${item.data.data.tests.value}` - : item.name, - value: item.data.data.advances.value, + label: value.test.length > 0 ? `${name} : ${value.test}` : name, + value: value.count, }; }) .sort((a, b) => a.label.localeCompare(b.label)), @@ -376,250 +387,406 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) { const labelledRowHeight = docBuilder.getLabelledRowHeight(); - const imageWidth = 25; + const imageWidth = 25 * docBuilder.getImageScale(); const imageY = labelledRowHeight + MARGINS.top + 2; - const actorImageElement = + const actorImageElementPdf = actorImageData != null - ? new Image(0, imageY, imageWidth, imageWidth, actorImageData) - : new Box(0, imageY, imageWidth, imageWidth); + ? new Image(0, imageY, imageWidth, imageWidth, actorImageData, { + isHtml: false, + }) + : new Box(0, imageY, imageWidth, imageWidth, { + isHtml: false, + }); + const actorImageElementHtml = + actorImageData != null + ? new Image(0, imageY, imageWidth, imageWidth, actorImageData, { + isPdf: false, + }) + : new Box(0, imageY, imageWidth, imageWidth, { + isPdf: false, + }); docBuilder.build([ - actorImageElement, - new Column(0, 0, [ - new Row(0, 0, [ - new LabelledText(0, 0, 'Name', `${actor.name}`), - new LabelledText(0, 0, 'Species', `${actorDetails?.species?.value}`), - new LabelledText(0, 0, 'Gender', `${actorDetails?.gender?.value}`), - ]), - new Row(imageWidth + MARGINS.left + 1, 0, [ - new LabelledText(0, 0, 'Class', `${careerDetail?.class?.value}`), - new LabelledText( + actorImageElementPdf, + new Column( + 0, + 0, + [ + new Row(0, 0, [ + new LabelledText(0, 0, 'Name', `${actor.name}`), + new LabelledText(0, 0, 'Species', `${actorDetails?.species?.value}`), + new LabelledText(0, 0, 'Gender', `${actorDetails?.gender?.value}`), + ]), + new Row( + imageWidth + MARGINS.left + 1, 0, - 0, - 'Career Group', - `${careerDetail?.careergroup?.value}` + [ + new LabelledText(0, 0, 'Class', `${careerDetail?.class?.value}`), + new LabelledText( + 0, + 0, + 'Career Group', + `${careerDetail?.careergroup?.value}` + ), + new LabelledText(0, 0, 'Career', `${currentCareer?.name}`), + ], + undefined, + undefined, + undefined, + { isHtml: false } ), - new LabelledText(0, 0, 'Career', `${currentCareer?.name}`), - ]), - new Row(imageWidth + MARGINS.left + 1, 0, [ - new LabelledText(0, 0, 'Status', `${actorDetails?.status?.value}`), - new LabelledText(0, 0, 'Age', `${actorDetails?.age?.value}`), - new LabelledText(0, 0, 'Height', `${actorDetails?.height?.value}`), - new LabelledText(0, 0, 'Weight', `${actorDetails?.weight?.value}`), - new LabelledText( + new Row( + imageWidth + MARGINS.left + 1, 0, - 0, - 'Hair Colour', - `${actorDetails?.haircolour?.value}` + [ + new LabelledText(0, 0, 'Status', `${actorDetails?.status?.value}`), + new LabelledText(0, 0, 'Age', `${actorDetails?.age?.value}`), + new LabelledText(0, 0, 'Height', `${actorDetails?.height?.value}`), + new LabelledText(0, 0, 'Weight', `${actorDetails?.weight?.value}`), + new LabelledText( + 0, + 0, + 'Hair Colour', + `${actorDetails?.haircolour?.value}` + ), + ], + undefined, + undefined, + undefined, + { isHtml: false } ), - ]), - new Row(imageWidth + MARGINS.left + 1, 0, [ - new LabelledText( + new Row( + imageWidth + MARGINS.left + 1, 0, - 0, - 'Eye Colour', - `${actorDetails?.eyecolour?.value}` + [ + new LabelledText( + 0, + 0, + 'Eye Colour', + `${actorDetails?.eyecolour?.value}` + ), + new LabelledText( + 0, + 0, + 'Distinguishing Mark', + `${actorDetails?.distinguishingmark?.value}` + ), + new LabelledText( + 0, + 0, + 'Star Sign', + `${actorDetails?.starsign?.value}` + ), + ], + undefined, + undefined, + undefined, + { isHtml: false } ), - new LabelledText( + new Row( 0, 0, - 'Distinguishing Mark', - `${actorDetails?.distinguishingmark?.value}` + [ + actorImageElementHtml, + new Column(0, 0, [ + new Row(imageWidth + MARGINS.left + 1, 0, [ + new LabelledText( + 0, + 0, + 'Class', + `${careerDetail?.class?.value}` + ), + new LabelledText( + 0, + 0, + 'Career Group', + `${careerDetail?.careergroup?.value}` + ), + new LabelledText(0, 0, 'Career', `${currentCareer?.name}`), + ]), + new Row(imageWidth + MARGINS.left + 1, 0, [ + new LabelledText( + 0, + 0, + 'Status', + `${actorDetails?.status?.value}` + ), + new LabelledText(0, 0, 'Age', `${actorDetails?.age?.value}`), + new LabelledText( + 0, + 0, + 'Height', + `${actorDetails?.height?.value}` + ), + new LabelledText( + 0, + 0, + 'Weight', + `${actorDetails?.weight?.value}` + ), + new LabelledText( + 0, + 0, + 'Hair Colour', + `${actorDetails?.haircolour?.value}` + ), + ]), + new Row(imageWidth + MARGINS.left + 1, 0, [ + new LabelledText( + 0, + 0, + 'Eye Colour', + `${actorDetails?.eyecolour?.value}` + ), + new LabelledText( + 0, + 0, + 'Distinguishing Mark', + `${actorDetails?.distinguishingmark?.value}` + ), + new LabelledText( + 0, + 0, + 'Star Sign', + `${actorDetails?.starsign?.value}` + ), + ]), + ]), + ], + undefined, + undefined, + undefined, + { isPdf: false } ), - new LabelledText(0, 0, 'Star Sign', `${actorDetails?.starsign?.value}`), - ]), - Blank.heightBlank(2), - new Row(0, 0, [ - new LabelledText(0, 0, 'CHARAbbrev.WS', `${actorCharacs?.ws?.value}`), - new LabelledText(0, 0, 'CHARAbbrev.BS', `${actorCharacs?.bs?.value}`), - new LabelledText(0, 0, 'CHARAbbrev.S', `${actorCharacs?.s?.value}`), - new LabelledText(0, 0, 'CHARAbbrev.T', `${actorCharacs?.t?.value}`), - new LabelledText(0, 0, 'CHARAbbrev.I', `${actorCharacs?.i?.value}`), - new LabelledText(0, 0, 'CHARAbbrev.Ag', `${actorCharacs?.ag?.value}`), - new LabelledText(0, 0, 'CHARAbbrev.Dex', `${actorCharacs?.dex?.value}`), - new LabelledText(0, 0, 'CHARAbbrev.Int', `${actorCharacs?.int?.value}`), - new LabelledText(0, 0, 'CHARAbbrev.WP', `${actorCharacs?.wp?.value}`), - new LabelledText(0, 0, 'CHARAbbrev.Fel', `${actorCharacs?.fel?.value}`), - ]), - new Row(0, 0, [ - new LabelledText(0, 0, 'Move', `${actorDetails?.move?.value}`), - new LabelledText(0, 0, 'Walk', `${actorDetails?.move?.walk}`), - new LabelledText(0, 0, 'Run', `${actorDetails?.move?.run}`), - new LabelledText(0, 0, 'Fortune', `${actorStatus?.fortune?.value}`), - new LabelledText(0, 0, 'Fate', `${actorStatus?.fate?.value}`), - new LabelledText(0, 0, 'Resolve', `${actorStatus?.resolve?.value}`), - new LabelledText( - 0, - 0, - 'Resilience', - `${actorStatus?.resilience?.value}` - ), - new LabelledText( - 0, - 0, - 'Wounds', - `${actorStatus?.wounds?.value}/${actorStatus?.wounds?.max}` - ), - ]), - new Separator(0, 0), - new Text(0, 0, 'Skills'), - skills, - new Separator(0, 0), - new Text(0, 0, `${i18nLocalize('Talents')} : ${i18nLocalize('Tests')}`), - talents, - traits.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0), - traits.elements.length > 0 - ? new Text(0, 0, 'Traits') - : Blank.heightBlank(0), - traits, - weaponsMelee.elements.length > 0 - ? new Separator(0, 0) - : Blank.heightBlank(0), - weaponsMelee.elements.length > 0 - ? new Text( + Blank.heightBlank(2), + new Row(0, 0, [ + new LabelledText(0, 0, 'CHARAbbrev.WS', `${actorCharacs?.ws?.value}`), + new LabelledText(0, 0, 'CHARAbbrev.BS', `${actorCharacs?.bs?.value}`), + new LabelledText(0, 0, 'CHARAbbrev.S', `${actorCharacs?.s?.value}`), + new LabelledText(0, 0, 'CHARAbbrev.T', `${actorCharacs?.t?.value}`), + new LabelledText(0, 0, 'CHARAbbrev.I', `${actorCharacs?.i?.value}`), + new LabelledText(0, 0, 'CHARAbbrev.Ag', `${actorCharacs?.ag?.value}`), + new LabelledText( 0, 0, - `${i18nLocalize('SHEET.MeleeWeaponHeader')} : ${i18nLocalize( - 'Weapon Group' - )}, ${i18nLocalize('Reach')}, ${i18nLocalize( - 'Damage' - )}, ${i18nLocalize('Qualities')}, ${i18nLocalize('Flaws')}` - ) - : Blank.heightBlank(0), - weaponsMelee, - weaponsRanged.elements.length > 0 - ? new Separator(0, 0) - : Blank.heightBlank(0), - weaponsRanged.elements.length > 0 - ? new Text( + 'CHARAbbrev.Dex', + `${actorCharacs?.dex?.value}` + ), + new LabelledText( 0, 0, - `${i18nLocalize('SHEET.RangedWeaponHeader')} : ${i18nLocalize( - 'Weapon Group' - )}, ${i18nLocalize('Range')}, ${i18nLocalize( - 'Damage' - )}, ${i18nLocalize('Qualities')}, ${i18nLocalize('Flaws')}` - ) - : Blank.heightBlank(0), - weaponsRanged, - ammunitions.elements.length > 0 - ? new Separator(0, 0) - : Blank.heightBlank(0), - ammunitions.elements.length > 0 - ? new Text( + 'CHARAbbrev.Int', + `${actorCharacs?.int?.value}` + ), + new LabelledText(0, 0, 'CHARAbbrev.WP', `${actorCharacs?.wp?.value}`), + new LabelledText( 0, 0, - `${i18nLocalize('Ammunition')} : ${i18nLocalize( - 'Range' - )}, ${i18nLocalize('Damage')}, ${i18nLocalize( - 'Qualities' - )}, ${i18nLocalize('Flaws')}` - ) - : Blank.heightBlank(0), - ammunitions, - armours.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0), - armours.elements.length > 0 - ? new Text(0, 0, 'Armour') - : Blank.heightBlank(0), - armours, - petty.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0), - petty.elements.length > 0 - ? new Text( + 'CHARAbbrev.Fel', + `${actorCharacs?.fel?.value}` + ), + ]), + new Row(0, 0, [ + new LabelledText(0, 0, 'Move', `${actorDetails?.move?.value}`), + new LabelledText(0, 0, 'Walk', `${actorDetails?.move?.walk}`), + new LabelledText(0, 0, 'Run', `${actorDetails?.move?.run}`), + new LabelledText(0, 0, 'Fortune', `${actorStatus?.fortune?.value}`), + new LabelledText(0, 0, 'Fate', `${actorStatus?.fate?.value}`), + new LabelledText(0, 0, 'Resolve', `${actorStatus?.resolve?.value}`), + new LabelledText( 0, 0, - `${i18nLocalize('SHEET.PettySpell')} : ${i18nLocalize( - 'Casting Number' - )}, ${i18nLocalize('Range')}, ${i18nLocalize( - 'Target' - )}, ${i18nLocalize('Duration')}` - ) - : Blank.heightBlank(0), - petty, - spell.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0), - spell.elements.length > 0 - ? new Text( + 'Resilience', + `${actorStatus?.resilience?.value}` + ), + new LabelledText( 0, 0, - `${i18nLocalize('SHEET.LoreSpell')} : ${i18nLocalize( - 'Casting Number' - )}, ${i18nLocalize('Range')}, ${i18nLocalize( - 'Target' - )}, ${i18nLocalize('Duration')}, ${i18nLocalize( - 'WFRP4E.TrappingType.Ingredients' - )}` - ) - : Blank.heightBlank(0), - spell, - blessing.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0), - blessing.elements.length > 0 - ? new Text( - 0, - 0, - `${i18nLocalize('Blessing')} : ${i18nLocalize( - 'Range' - )}, ${i18nLocalize('Target')}, ${i18nLocalize('Duration')}` - ) - : Blank.heightBlank(0), - blessing, - miracle.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0), - miracle.elements.length > 0 - ? new Text( - 0, - 0, - `${i18nLocalize('Miracle')} : ${i18nLocalize( - 'Range' - )}, ${i18nLocalize('Target')}, ${i18nLocalize('Duration')}` - ) - : Blank.heightBlank(0), - miracle, - new Separator(0, 0), - trappingsHeader, - trappings, - psychology.elements.length > 0 - ? new Separator(0, 0) - : Blank.heightBlank(0), - psychology.elements.length > 0 - ? new Text(0, 0, 'Psychology') - : Blank.heightBlank(0), - psychology, - critical.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0), - critical.elements.length > 0 - ? new Text(0, 0, 'Criticals') - : Blank.heightBlank(0), - critical, - disease.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0), - disease.elements.length > 0 - ? new Text(0, 0, 'Diseases') - : Blank.heightBlank(0), - disease, - injury.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0), - injury.elements.length > 0 - ? new Text(0, 0, 'Injuries') - : Blank.heightBlank(0), - injury, - mutationP.elements.length > 0 - ? new Separator(0, 0) - : Blank.heightBlank(0), - mutationP.elements.length > 0 - ? new Text( - 0, - 0, - `${i18nLocalize('Mutations')} (${i18nLocalize('Physical')})` - ) - : Blank.heightBlank(0), - mutationP, - mutationM.elements.length > 0 - ? new Separator(0, 0) - : Blank.heightBlank(0), - mutationM.elements.length > 0 - ? new Text( - 0, - 0, - `${i18nLocalize('Mutations')} (${i18nLocalize('Mental')})` - ) - : Blank.heightBlank(0), - mutationM, - ]), + 'Wounds', + `${actorStatus?.wounds?.value}/${actorStatus?.wounds?.max}` + ), + ]), + new Separator(0, 0), + new Text(0, 0, 'Skills'), + skills, + new Separator(0, 0), + new Text(0, 0, `${i18nLocalize('Talents')} : ${i18nLocalize('Tests')}`), + talents, + traits.contextElements.length > 0 + ? new Separator(0, 0) + : Blank.heightBlank(0), + traits.contextElements.length > 0 + ? new Text(0, 0, 'Traits') + : Blank.heightBlank(0), + traits, + weaponsMelee.contextElements.length > 0 + ? new Separator(0, 0) + : Blank.heightBlank(0), + weaponsMelee.contextElements.length > 0 + ? new Text( + 0, + 0, + `${i18nLocalize('SHEET.MeleeWeaponHeader')} : ${i18nLocalize( + 'Weapon Group' + )}, ${i18nLocalize('Reach')}, ${i18nLocalize( + 'Damage' + )}, ${i18nLocalize('Qualities')}, ${i18nLocalize('Flaws')}` + ) + : Blank.heightBlank(0), + weaponsMelee, + weaponsRanged.contextElements.length > 0 + ? new Separator(0, 0) + : Blank.heightBlank(0), + weaponsRanged.contextElements.length > 0 + ? new Text( + 0, + 0, + `${i18nLocalize('SHEET.RangedWeaponHeader')} : ${i18nLocalize( + 'Weapon Group' + )}, ${i18nLocalize('Range')}, ${i18nLocalize( + 'Damage' + )}, ${i18nLocalize('Qualities')}, ${i18nLocalize('Flaws')}` + ) + : Blank.heightBlank(0), + weaponsRanged, + ammunitions.contextElements.length > 0 + ? new Separator(0, 0) + : Blank.heightBlank(0), + ammunitions.contextElements.length > 0 + ? new Text( + 0, + 0, + `${i18nLocalize('Ammunition')} : ${i18nLocalize( + 'Range' + )}, ${i18nLocalize('Damage')}, ${i18nLocalize( + 'Qualities' + )}, ${i18nLocalize('Flaws')}` + ) + : Blank.heightBlank(0), + ammunitions, + armours.contextElements.length > 0 + ? new Separator(0, 0) + : Blank.heightBlank(0), + armours.contextElements.length > 0 + ? new Text(0, 0, 'Armour') + : Blank.heightBlank(0), + armours, + petty.contextElements.length > 0 + ? new Separator(0, 0) + : Blank.heightBlank(0), + petty.contextElements.length > 0 + ? new Text( + 0, + 0, + `${i18nLocalize('SHEET.PettySpell')} : ${i18nLocalize( + 'Casting Number' + )}, ${i18nLocalize('Range')}, ${i18nLocalize( + 'Target' + )}, ${i18nLocalize('Duration')}` + ) + : Blank.heightBlank(0), + petty, + spell.contextElements.length > 0 + ? new Separator(0, 0) + : Blank.heightBlank(0), + spell.contextElements.length > 0 + ? new Text( + 0, + 0, + `${i18nLocalize('SHEET.LoreSpell')} : ${i18nLocalize( + 'Casting Number' + )}, ${i18nLocalize('Range')}, ${i18nLocalize( + 'Target' + )}, ${i18nLocalize('Duration')}, ${i18nLocalize( + 'WFRP4E.TrappingType.Ingredients' + )}` + ) + : Blank.heightBlank(0), + spell, + blessing.contextElements.length > 0 + ? new Separator(0, 0) + : Blank.heightBlank(0), + blessing.contextElements.length > 0 + ? new Text( + 0, + 0, + `${i18nLocalize('Blessing')} : ${i18nLocalize( + 'Range' + )}, ${i18nLocalize('Target')}, ${i18nLocalize('Duration')}` + ) + : Blank.heightBlank(0), + blessing, + miracle.contextElements.length > 0 + ? new Separator(0, 0) + : Blank.heightBlank(0), + miracle.contextElements.length > 0 + ? new Text( + 0, + 0, + `${i18nLocalize('Miracle')} : ${i18nLocalize( + 'Range' + )}, ${i18nLocalize('Target')}, ${i18nLocalize('Duration')}` + ) + : Blank.heightBlank(0), + miracle, + new Separator(0, 0), + trappingsHeader, + trappings, + psychology.contextElements.length > 0 + ? new Separator(0, 0) + : Blank.heightBlank(0), + psychology.contextElements.length > 0 + ? new Text(0, 0, 'Psychology') + : Blank.heightBlank(0), + psychology, + critical.contextElements.length > 0 + ? new Separator(0, 0) + : Blank.heightBlank(0), + critical.contextElements.length > 0 + ? new Text(0, 0, 'Criticals') + : Blank.heightBlank(0), + critical, + disease.contextElements.length > 0 + ? new Separator(0, 0) + : Blank.heightBlank(0), + disease.contextElements.length > 0 + ? new Text(0, 0, 'Diseases') + : Blank.heightBlank(0), + disease, + injury.contextElements.length > 0 + ? new Separator(0, 0) + : Blank.heightBlank(0), + injury.contextElements.length > 0 + ? new Text(0, 0, 'Injuries') + : Blank.heightBlank(0), + injury, + mutationP.contextElements.length > 0 + ? new Separator(0, 0) + : Blank.heightBlank(0), + mutationP.contextElements.length > 0 + ? new Text( + 0, + 0, + `${i18nLocalize('Mutations')} (${i18nLocalize('Physical')})` + ) + : Blank.heightBlank(0), + mutationP, + mutationM.contextElements.length > 0 + ? new Separator(0, 0) + : Blank.heightBlank(0), + mutationM.contextElements.length > 0 + ? new Text( + 0, + 0, + `${i18nLocalize('Mutations')} (${i18nLocalize('Mental')})` + ) + : Blank.heightBlank(0), + mutationM, + ], + { + name: 'main-column', + } + ), ]); docBuilder.save(`${actor.name}`); } diff --git a/src/pdf-builder.ts b/src/pdf-builder.ts index 877747f..05f9387 100644 --- a/src/pdf-builder.ts +++ b/src/pdf-builder.ts @@ -22,7 +22,7 @@ export class PdfBuilder extends AbstractBuilder { public build(elements: AbstractElement[]) { const finalElements: AbstractElement[] = []; - for (const element of elements) { + for (const element of elements.filter((el) => el.context.isPdf)) { element.prepareRender(this.doc); finalElements.push(...element.getElements()); } @@ -69,4 +69,8 @@ export class PdfBuilder extends AbstractBuilder { } } } + + public getImageScale(): number { + return 1; + } }