Add lower-corner layouts, custom blur backgrounds, and classic blur fill.

Ship composition families, optional background images for lower-corner templates, and an optional blurred cover fill for classic letterbox.
This commit is contained in:
Atakan Doğan Özban
2026-08-07 00:51:37 +02:00
parent 03634d5100
commit 848607f9e0
25 changed files with 1081 additions and 122 deletions
+33 -6
View File
@@ -11,9 +11,14 @@ import { getVideoAttributionText } from "@/lib/branding";
import {
CURATED_FONTS,
googleFontsStylesheetUrl,
SYSTEM_FONT,
type CuratedFontKey,
type WatermarkFontKey,
} from "@/lib/fonts";
import {
curatedFontApiUrl,
previewFontFamilyCss,
} from "@/lib/preview-typography";
import {
WATERMARK_OFFSET_MAX,
WATERMARK_OFFSET_MIN,
@@ -78,10 +83,7 @@ function previewStyle(
}
function previewFontFamily(fontKey: WatermarkFontKey | undefined): string {
if (!fontKey || fontKey === "system") return "ui-sans-serif, system-ui, sans-serif";
if (fontKey === "custom") return `'${CUSTOM_PREVIEW_FAMILY}', sans-serif`;
const meta = CURATED_FONTS.find((f) => f.key === fontKey);
return meta ? `'${meta.cssFamily}', sans-serif` : "sans-serif";
return previewFontFamilyCss(fontKey);
}
export function WatermarkPreview({
@@ -110,7 +112,32 @@ export function WatermarkPreview({
[value.fontKey],
);
// Load curated Google Fonts for live canvas preview
// Load bundled + curated fonts for live canvas preview (same files as FFmpeg)
useEffect(() => {
const styleId = "s2vid-watermark-preview-fonts";
let el = document.getElementById(styleId) as HTMLStyleElement | null;
if (!el) {
el = document.createElement("style");
el.id = styleId;
document.head.appendChild(el);
}
el.textContent = [
`@font-face {
font-family: '${SYSTEM_FONT.previewFamily}';
src: url('${curatedFontApiUrl(SYSTEM_FONT.key)}') format('truetype');
font-display: swap;
}`,
...CURATED_FONTS.map(
(f) => `@font-face {
font-family: 'S2VIDPreview-${f.key}';
src: url('${curatedFontApiUrl(f.key)}') format('truetype');
font-display: swap;
}`,
),
].join("\n");
}, []);
// Legacy Google Fonts link (kept for any older preview paths)
useEffect(() => {
const id = "s2vid-watermark-google-fonts";
if (document.getElementById(id)) return;
@@ -287,7 +314,7 @@ export function WatermarkPreview({
onChange={(e) => setFontKey(e.target.value as WatermarkFontKey)}
className="input-field mt-1"
>
<option value="system">System default</option>
<option value="system">{SYSTEM_FONT.label}</option>
{CURATED_FONTS.map((f) => (
<option key={f.key} value={f.key} style={{ fontFamily: f.cssFamily }}>
{f.label}