import React from "react";
import {interpolate} from "remotion";
const clampInterpolation = {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
} as const;
export type VQSpeechSubtitleStyleOptions = Readonly<{
fontFamily?: string;
fontSize?: number;
fontWeight?: React.CSSProperties["fontWeight"];
color?: string;
lineHeight?: number;
padding?: string;
backgroundColor?: string;
borderRadius?: number;
boxShadow?: string;
maxWidth?: number;
speakerLabelFontSize?: number;
containerStyle?: React.CSSProperties;
speakerLabelStyle?: React.CSSProperties;
textStyle?: React.CSSProperties;
}>;
export type VQSpeechSubtitleProps = VQSpeechSubtitleStyleOptions &
Readonly<{
text: string;
progress: number;
speakerName?: string;
accentColor?: string;
}>;
export const VQSpeechSubtitle: React.FC<VQSpeechSubtitleProps> = ({
text,
progress,
speakerName,
accentColor = "#1f2a44",
fontFamily = "system-ui, sans-serif",
fontSize = 36,
fontWeight = 700,
color = "#1a1a1a",
lineHeight = 1.4,
padding = "18px 28px",
backgroundColor = "rgba(255, 255, 255, 0.88)",
borderRadius = 18,
boxShadow = "0 10px 30px rgba(31, 42, 68, 0.15)",
maxWidth = 980,
speakerLabelFontSize = 20,
containerStyle,
speakerLabelStyle,
textStyle,
}) => {
const opacity = interpolate(progress, [0, 1], [0, 1], clampInterpolation);
const translateY = interpolate(progress, [0, 1], [16, 0], clampInterpolation);
return (
<div
style={{
fontFamily,
fontSize,
fontWeight,
color,
lineHeight,
padding,
backgroundColor,
borderRadius,
border: `2px solid ${accentColor}33`,
boxShadow,
maxWidth,
opacity,
transform: `translateY(${translateY}px)`,
...containerStyle,
}}
>
{speakerName ? (
<div
style={{
display: "inline-block",
fontSize: speakerLabelFontSize,
color: "#ffffff",
backgroundColor: accentColor,
borderRadius: 999,
padding: "4px 14px",
marginBottom: 8,
...speakerLabelStyle,
}}
>
{speakerName}
</div>
) : null}
<div style={textStyle}>{text}</div>
</div>
);
};