diff --git a/src/assets/locales/en.json b/src/assets/locales/en.json index 11a4ff5f..78146bfd 100644 --- a/src/assets/locales/en.json +++ b/src/assets/locales/en.json @@ -1132,9 +1132,10 @@ "default": "Default", "raised": "Raised", "depressed": "Depressed", - "uniform": "Uniform", + "Border": "Border", "dropShadow": "Drop Shadow" - } + }, + "BorderThicknessLabel": "Border Thickness" }, "unsaved": "You have unsaved changes... ฅ^•ﻌ•^ฅ" }, diff --git a/src/components/player/atoms/settings/CaptionSettingsView.tsx b/src/components/player/atoms/settings/CaptionSettingsView.tsx index fdeb9fb4..82569c74 100644 --- a/src/components/player/atoms/settings/CaptionSettingsView.tsx +++ b/src/components/player/atoms/settings/CaptionSettingsView.tsx @@ -428,6 +428,7 @@ export function CaptionSettingsView({ backgroundBlur: 0.5, bold: false, fontStyle: "default", + borderThickness: 1, }); }; @@ -531,8 +532,8 @@ export function CaptionSettingsView({ name: t("settings.subtitles.textStyle.depressed"), }, { - id: "uniform", - name: t("settings.subtitles.textStyle.uniform"), + id: "Border", + name: t("settings.subtitles.textStyle.Border"), }, { id: "dropShadow", @@ -553,6 +554,19 @@ export function CaptionSettingsView({ } /> + {styling.fontStyle === "Border" && ( + + handleStylingChange({ ...styling, borderThickness: v }) + } + value={styling.borderThickness} + textTransformer={(s) => `${s}px`} + decimalsAllowed={1} + /> + )}
{t("settings.subtitles.textBoldLabel")} diff --git a/src/components/player/base/SubtitleView.tsx b/src/components/player/base/SubtitleView.tsx index bc581086..83a6946b 100644 --- a/src/components/player/base/SubtitleView.tsx +++ b/src/components/player/base/SubtitleView.tsx @@ -58,11 +58,25 @@ export function CaptionCue({ textShadow: "0 -2px 0 rgba(0,0,0,0.8), 0 -1.5px 1.5px rgba(0,0,0,0.9)", }; - case "uniform": + case "Border": { + const thickness = Math.max( + 0.5, + Math.min(5, styling.borderThickness || 1), + ); + const shadowColor = "rgba(0,0,0,0.8)"; return { - textShadow: - "1.5px 1.5px 1.5px rgba(0,0,0,0.8), -1.5px -1.5px 1.5px rgba(0,0,0,0.8), 1.5px -1.5px 1.5px rgba(0,0,0,0.8), -1.5px 1.5px 1.5px rgba(0,0,0,0.8)", + textShadow: [ + `${thickness}px ${thickness}px 0 ${shadowColor}`, + `-${thickness}px ${thickness}px 0 ${shadowColor}`, + `${thickness}px -${thickness}px 0 ${shadowColor}`, + `-${thickness}px -${thickness}px 0 ${shadowColor}`, + `${thickness}px 0 0 ${shadowColor}`, + `-${thickness}px 0 0 ${shadowColor}`, + `0 ${thickness}px 0 ${shadowColor}`, + `0 -${thickness}px 0 ${shadowColor}`, + ].join(", "), }; + } case "dropShadow": return { textShadow: "2.5px 2.5px 4.5px rgba(0,0,0,0.9)" }; case "default": diff --git a/src/pages/parts/settings/CaptionsPart.tsx b/src/pages/parts/settings/CaptionsPart.tsx index d0b01f8e..dbfcd4da 100644 --- a/src/pages/parts/settings/CaptionsPart.tsx +++ b/src/pages/parts/settings/CaptionsPart.tsx @@ -116,6 +116,7 @@ export function CaptionsPart(props: { bold: false, verticalPosition: 3, fontStyle: "default", + borderThickness: 1, }); }; @@ -203,8 +204,8 @@ export function CaptionsPart(props: { name: t("settings.subtitles.textStyle.depressed"), }, { - id: "uniform", - name: t("settings.subtitles.textStyle.uniform"), + id: "Border", + name: t("settings.subtitles.textStyle.Border"), }, { id: "dropShadow", @@ -227,6 +228,22 @@ export function CaptionsPart(props: { />
+ {props.styling.fontStyle === "Border" && ( + + handleStylingChange({ + ...props.styling, + borderThickness: v, + }) + } + value={props.styling.borderThickness} + textTransformer={(s) => `${s}px`} + decimalsAllowed={1} + /> + )}
{t("settings.subtitles.textBoldLabel")} diff --git a/src/stores/subtitles/index.ts b/src/stores/subtitles/index.ts index 14fb9b58..0559dd9d 100644 --- a/src/stores/subtitles/index.ts +++ b/src/stores/subtitles/index.ts @@ -36,9 +36,14 @@ export interface SubtitleStyling { /** * font style for text rendering - * "default" | "raised" | "depressed" | "uniform" | "dropShadow" + * "default" | "raised" | "depressed" | "Border" | "dropShadow" */ fontStyle: string; + + /** + * border thickness for Border font style, ranges between 0 and 10 + */ + borderThickness: number; } export interface SubtitleStore { @@ -83,6 +88,7 @@ export const useSubtitleStore = create( bold: false, verticalPosition: 3, fontStyle: "default", + borderThickness: 1, }, showDelayIndicator: false, resetSubtitleSpecificSettings() { @@ -115,6 +121,11 @@ export const useSubtitleStore = create( ); if (newStyling.fontStyle !== undefined) s.styling.fontStyle = newStyling.fontStyle; + if (newStyling.borderThickness !== undefined) + s.styling.borderThickness = Math.min( + 10, + Math.max(0, newStyling.borderThickness), + ); }); }, resetStyling() { @@ -127,6 +138,7 @@ export const useSubtitleStore = create( bold: false, verticalPosition: 3, fontStyle: "default", + borderThickness: 1, }; }); },