diff --git a/index.html b/index.html index c5290fb..1beefff 100644 --- a/index.html +++ b/index.html @@ -18,6 +18,12 @@ + +
@@ -99,11 +105,9 @@ /> diff --git a/src/main.ts b/src/main.ts index 4a059fd..88b500e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -27,12 +27,17 @@ cover .addStripes(STRIPE_COLORS) .setYear(new Date().getUTCFullYear()) .setLocation("Пермь") - .setTitle({ text: settings.title, fontSize: settings.fontSize }); + .setTitle({ + text: settings.title, + fontSize: settings.fontSize, + textAlign: settings.textAlign, + }); settings.onSettingsChange((data) => { cover.setTitle({ text: data.title, fontSize: data.fontSize, + textAlign: data.textAlign, }); cover.setTheme(data.theme); diff --git a/src/settings.ts b/src/settings.ts index d74317d..15c20ce 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,7 +1,10 @@ +export type TextAlign = "left" | "center" | "right"; + type SettingsData = { theme: string; title: string; fontSize: number; + textAlign: TextAlign; }; interface SettingsChangeHandler { @@ -14,11 +17,12 @@ export class SettingsManager { private readonly themeSelect: HTMLSelectElement; private readonly textarea: HTMLTextAreaElement; private readonly fontSizeInput: HTMLInputElement; + private readonly alignSelect: HTMLSelectElement; private readonly downloadButton: HTMLButtonElement; constructor(private readonly form: HTMLFormElement) { const themeSelect = - this.form.querySelector("select"); + this.form.querySelector("#theme"); if (!themeSelect) { throw new Error("Cannot find theme select"); @@ -44,6 +48,15 @@ export class SettingsManager { this.fontSizeInput = fontSizeInput; + const alignSelect = + this.form.querySelector("#align"); + + if (!alignSelect) { + throw new Error("Cannot find align select"); + } + + this.alignSelect = alignSelect; + const downloadButton = this.form.querySelector("button"); @@ -62,12 +75,14 @@ export class SettingsManager { theme: this.theme, title: this.title, fontSize: this.fontSize, + textAlign: this.textAlign, }); }; this.themeSelect.addEventListener("change", handler); this.textarea.addEventListener("input", handler); this.fontSizeInput.addEventListener("change", handler); + this.alignSelect.addEventListener("change", handler); } onDownload(callback: () => void) { @@ -86,4 +101,8 @@ export class SettingsManager { get fontSize() { return parseInt(this.fontSizeInput.value, 10) || DEFAULT_FONT_SIZE; } + + get textAlign(): TextAlign { + return this.alignSelect.value as TextAlign; + } } diff --git a/src/svg.ts b/src/svg.ts index 67d60ca..6ec251b 100644 --- a/src/svg.ts +++ b/src/svg.ts @@ -1,9 +1,11 @@ import { THEMES } from "./constants"; +import { type TextAlign } from "./settings"; import { randomInt } from "./utils"; type TextOptions = { text: string; fontSize: number; + textAlign: TextAlign; }; type RectangleOptions = { @@ -95,6 +97,21 @@ export class SvgBuilder { this.title.removeChild(this.title.firstChild); } + switch (options.textAlign) { + case "left": + this.title.setAttribute("x", "320"); + this.title.setAttribute("text-anchor", "start"); + break; + case "center": + this.title.setAttribute("x", "730"); + this.title.setAttribute("text-anchor", "middle"); + break; + case "right": + this.title.setAttribute("x", "1180"); + this.title.setAttribute("text-anchor", "end"); + break; + } + const offsetFirst = ((1 - lines.length) / 2) * lineHeight; // Create a new tspan element for each line of input