feat: Dynamic text scaling based on video resolution

This commit is contained in:
2026-06-02 22:18:00 -05:00
parent 58d9b095a3
commit 32a993d6a9
+19 -7
View File
@@ -3,6 +3,7 @@ import { Img, Video } from '../../engine/components';
import { TimelineElement, DesignMD } from '../../types'; import { TimelineElement, DesignMD } from '../../types';
import { ChromaKeyImage } from './ChromaKeyImage'; import { ChromaKeyImage } from './ChromaKeyImage';
import { ChromaKeyVideo } from './ChromaKeyVideo'; import { ChromaKeyVideo } from './ChromaKeyVideo';
import { useVideoConfig } from '../../engine/player';
interface ElementRendererProps { interface ElementRendererProps {
element: TimelineElement; element: TimelineElement;
@@ -28,23 +29,34 @@ export const ElementRenderer: React.FC<ElementRendererProps> = ({
ckTolerance, ckTolerance,
ckSoftness, ckSoftness,
}) => { }) => {
const { width } = useVideoConfig();
const scaleFactor = width / 1080;
if (el.type === 'text') { if (el.type === 'text') {
const fontSize = (el.fontSize ?? 56) * scaleFactor;
const shadowOffset = (el.shadowOffset ?? 3) * scaleFactor;
const shadowBlur = (el.shadowBlur ?? 6) * scaleFactor;
const letterSpacing = el.letterSpacing ? el.letterSpacing * scaleFactor : undefined;
const strokeWidth = el.textStrokeWidth ? el.textStrokeWidth * scaleFactor : undefined;
const bgPadding = (el.textBackgroundPadding ?? 8) * scaleFactor;
const bgRadius = (el.textBackgroundRadius ?? 4) * scaleFactor;
return ( return (
<div <div
style={{ style={{
fontFamily: el.fontFamily ?? designMD.baseFont, fontFamily: el.fontFamily ?? designMD.baseFont,
color: el.color ?? designMD.textColor, color: el.color ?? designMD.textColor,
fontSize: el.fontSize ? `${el.fontSize}px` : '56px', fontSize: `${fontSize}px`,
fontWeight: el.fontWeight ?? 'bold', fontWeight: el.fontWeight ?? 'bold',
fontStyle: el.fontStyle ?? 'normal', fontStyle: el.fontStyle ?? 'normal',
textDecoration: el.textDecoration && el.textDecoration !== 'none' ? el.textDecoration : undefined, textDecoration: el.textDecoration && el.textDecoration !== 'none' ? el.textDecoration : undefined,
textShadow: `${el.shadowOffset ?? 3}px ${el.shadowOffset ?? 3}px ${el.shadowBlur ?? 6}px ${el.shadowColor ?? 'rgba(0,0,0,0.8)'}`, textShadow: `${shadowOffset}px ${shadowOffset}px ${shadowBlur}px ${el.shadowColor ?? 'rgba(0,0,0,0.8)'}`,
textAlign: el.textAlign ?? 'center', textAlign: el.textAlign ?? 'center',
lineHeight: el.lineHeight ?? 1.2, lineHeight: el.lineHeight ?? 1.2,
letterSpacing: el.letterSpacing ? `${el.letterSpacing}px` : undefined, letterSpacing: letterSpacing ? `${letterSpacing}px` : undefined,
textTransform: el.textTransform ?? 'none', textTransform: el.textTransform ?? 'none',
WebkitTextStroke: el.textStrokeWidth WebkitTextStroke: strokeWidth
? `${el.textStrokeWidth}px ${el.textStrokeColor ?? '#000000'}` ? `${strokeWidth}px ${el.textStrokeColor ?? '#000000'}`
: undefined, : undefined,
...(el.textGradient ? { ...(el.textGradient ? {
background: el.textGradient, background: el.textGradient,
@@ -53,8 +65,8 @@ export const ElementRenderer: React.FC<ElementRendererProps> = ({
backgroundClip: 'text', backgroundClip: 'text',
} : el.textBackground ? { } : el.textBackground ? {
background: el.textBackground, background: el.textBackground,
padding: `${el.textBackgroundPadding ?? 8}px ${(el.textBackgroundPadding ?? 8) * 2}px`, padding: `${bgPadding}px ${bgPadding * 2}px`,
borderRadius: `${el.textBackgroundRadius ?? 4}px`, borderRadius: `${bgRadius}px`,
display: 'inline-block', display: 'inline-block',
} : {}), } : {}),
whiteSpace: 'pre-wrap', whiteSpace: 'pre-wrap',