add border caption style with thickness slider
Some checks are pending
Linting and Testing / Run Linters (push) Waiting to run
Linting and Testing / Build project (push) Waiting to run
Linting and Testing / Build Docker (push) Waiting to run

This commit is contained in:
Pas 2025-10-25 14:39:15 -06:00
parent e20bbf27ad
commit 422f46b406
5 changed files with 68 additions and 10 deletions

View file

@ -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... ฅ^•ﻌ•^ฅ"
},

View file

@ -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({
}
/>
</div>
{styling.fontStyle === "Border" && (
<CaptionSetting
label={t("settings.subtitles.BorderThicknessLabel")}
max={10}
min={0}
onChange={(v) =>
handleStylingChange({ ...styling, borderThickness: v })
}
value={styling.borderThickness}
textTransformer={(s) => `${s}px`}
decimalsAllowed={1}
/>
)}
<div className="flex justify-between items-center">
<Menu.FieldTitle>
{t("settings.subtitles.textBoldLabel")}

View file

@ -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":

View file

@ -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: {
/>
</div>
</div>
{props.styling.fontStyle === "Border" && (
<CaptionSetting
label={t("settings.subtitles.BorderThicknessLabel")}
max={10}
min={0}
onChange={(v) =>
handleStylingChange({
...props.styling,
borderThickness: v,
})
}
value={props.styling.borderThickness}
textTransformer={(s) => `${s}px`}
decimalsAllowed={1}
/>
)}
<div className="flex justify-between items-center">
<Menu.FieldTitle>
{t("settings.subtitles.textBoldLabel")}

View file

@ -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,
};
});
},