From 2ee0a44735d2b930348e9774909638b2c1909738 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Wed, 29 Apr 2026 01:28:50 +0200 Subject: refactor: unify element params --- .../src/subtitles/build-subtitle-text-element.ts | 80 +++++++++++++--------- apps/web/src/subtitles/types.ts | 16 +++-- 2 files changed, 58 insertions(+), 38 deletions(-) (limited to 'apps/web/src/subtitles') diff --git a/apps/web/src/subtitles/build-subtitle-text-element.ts b/apps/web/src/subtitles/build-subtitle-text-element.ts index 4e0bdb85..c2d59f08 100644 --- a/apps/web/src/subtitles/build-subtitle-text-element.ts +++ b/apps/web/src/subtitles/build-subtitle-text-element.ts @@ -6,7 +6,13 @@ import { } from "@/text/layout"; import { DEFAULTS } from "@/timeline/defaults"; import { mediaTimeFromSeconds } from "@/wasm"; -import type { CreateTextElement } from "@/timeline"; +import type { CreateTextElement, TextBackground } from "@/timeline"; +import type { + TextAlign, + TextDecoration, + TextFontStyle, + TextFontWeight, +} from "@/text/primitives"; import type { SubtitleCue, SubtitleStyleOverrides } from "./types"; const SUBTITLE_MAX_WIDTH_RATIO = 0.8; @@ -89,8 +95,8 @@ function measureWrappedTextBlock({ ctx: CanvasRenderingContext2D; content: string; canvasHeight: number; - textAlign: CreateTextElement["textAlign"]; - background: CreateTextElement["background"]; + textAlign: TextAlign; + background: TextBackground; fontSize: number; lineHeight: number; }) { @@ -107,7 +113,7 @@ function measureWrappedTextBlock({ textAlign, block, background, - fontSizeRatio: fontSize / DEFAULTS.text.element.fontSize, + fontSizeRatio: fontSize / 15, }); return { @@ -124,13 +130,13 @@ function resolveSubtitleStyle({ fontFamily: string; fontSize: number; color: string; - textAlign: CreateTextElement["textAlign"]; - fontWeight: CreateTextElement["fontWeight"]; - fontStyle: CreateTextElement["fontStyle"]; - textDecoration: CreateTextElement["textDecoration"]; + textAlign: TextAlign; + fontWeight: TextFontWeight; + fontStyle: TextFontStyle; + textDecoration: TextDecoration; letterSpacing: number; lineHeight: number; - background: CreateTextElement["background"]; + background: TextBackground; placement: NonNullable; } { const fontSize = @@ -139,18 +145,17 @@ function resolveSubtitleStyle({ : (style?.fontSize ?? SUBTITLE_FONT_SIZE); return { - fontFamily: style?.fontFamily ?? DEFAULTS.text.element.fontFamily, + fontFamily: style?.fontFamily ?? "Arial", fontSize, - color: style?.color ?? DEFAULTS.text.element.color, + color: style?.color ?? "#ffffff", textAlign: style?.textAlign ?? "center", fontWeight: style?.fontWeight ?? "bold", - fontStyle: style?.fontStyle ?? DEFAULTS.text.element.fontStyle, - textDecoration: - style?.textDecoration ?? DEFAULTS.text.element.textDecoration, + fontStyle: style?.fontStyle ?? "normal", + textDecoration: style?.textDecoration ?? "none", letterSpacing: style?.letterSpacing ?? DEFAULTS.text.letterSpacing, lineHeight: style?.lineHeight ?? DEFAULTS.text.lineHeight, background: { - ...DEFAULTS.text.element.background, + ...DEFAULTS.text.background, enabled: false, ...(style?.background ?? {}), }, @@ -188,7 +193,7 @@ function resolvePositionX({ visualRect, }: { canvasWidth: number; - textAlign: CreateTextElement["textAlign"]; + textAlign: TextAlign; placement: ReturnType["placement"]; visualRect: { left: number; width: number }; }): number { @@ -309,25 +314,34 @@ export function buildSubtitleTextElement({ return { ...DEFAULTS.text.element, name: `Caption ${index + 1}`, - content, duration: mediaTimeFromSeconds({ seconds: caption.duration }), startTime: mediaTimeFromSeconds({ seconds: caption.startTime }), - fontSize: style.fontSize, - fontFamily: style.fontFamily, - color: style.color, - textAlign: style.textAlign, - fontWeight: style.fontWeight, - fontStyle: style.fontStyle, - textDecoration: style.textDecoration, - letterSpacing: style.letterSpacing, - lineHeight: style.lineHeight, - background: style.background, - transform: { - ...DEFAULTS.text.element.transform, - position: { - x: positionX, - y: positionY, - }, + params: { + ...DEFAULTS.text.element.params, + content, + fontSize: style.fontSize, + fontFamily: style.fontFamily, + color: style.color, + textAlign: style.textAlign, + fontWeight: style.fontWeight, + fontStyle: style.fontStyle, + textDecoration: style.textDecoration, + letterSpacing: style.letterSpacing, + lineHeight: style.lineHeight, + "background.enabled": style.background.enabled, + "background.color": style.background.color, + "background.cornerRadius": + style.background.cornerRadius ?? DEFAULTS.text.background.cornerRadius, + "background.paddingX": + style.background.paddingX ?? DEFAULTS.text.background.paddingX, + "background.paddingY": + style.background.paddingY ?? DEFAULTS.text.background.paddingY, + "background.offsetX": + style.background.offsetX ?? DEFAULTS.text.background.offsetX, + "background.offsetY": + style.background.offsetY ?? DEFAULTS.text.background.offsetY, + "transform.positionX": positionX, + "transform.positionY": positionY, }, }; } diff --git a/apps/web/src/subtitles/types.ts b/apps/web/src/subtitles/types.ts index e4f5db3c..a2de9ab7 100644 --- a/apps/web/src/subtitles/types.ts +++ b/apps/web/src/subtitles/types.ts @@ -1,4 +1,10 @@ -import type { TextBackground, TextElement } from "@/timeline"; +import type { TextBackground } from "@/timeline"; +import type { + TextAlign, + TextDecoration, + TextFontStyle, + TextFontWeight, +} from "@/text/primitives"; import type { CaptionChunk } from "@/transcription/types"; export interface SubtitlePlacementStyle { @@ -26,10 +32,10 @@ export interface SubtitleStyleOverrides { color?: string; background?: Pick & Partial>; - textAlign?: TextElement["textAlign"]; - fontWeight?: TextElement["fontWeight"]; - fontStyle?: TextElement["fontStyle"]; - textDecoration?: TextElement["textDecoration"]; + textAlign?: TextAlign; + fontWeight?: TextFontWeight; + fontStyle?: TextFontStyle; + textDecoration?: TextDecoration; letterSpacing?: number; lineHeight?: number; placement?: SubtitlePlacementStyle; -- cgit v1.3.1