feat(title): 标题预览改为叠加在视频画面上 #1234

Merged
xiaoxia merged 3 commits from fix/title-preview-overlay into develop 2026-08-04 14:21:49 +08:00
@@ -21,16 +21,16 @@ interface PreviewVideoPanelProps {
titleSettings?: TitleSettings
}
/** 根据 position 返回垂直对齐样式 */
const positionAlignStyle = (position: string): React.CSSProperties => {
/** 根据 position 返回 absolute 定位样式(叠加在视频上) */
const positionOverlayStyle = (position: string): React.CSSProperties => {
switch (position) {
case "top":
return { justifyContent: "flex-start", paddingTop: 16 }
return { top: 16, left: 0, right: 0 }
case "center":
return { justifyContent: "center" }
return { top: "50%", left: 0, right: 0, transform: "translateY(-50%)" }
case "bottom":
default:
return { justifyContent: "flex-end", paddingBottom: 16 }
return { bottom: 56, left: 0, right: 0 } // 56px = 给视频控制条留空间
}
}
@@ -121,47 +121,47 @@ export const PreviewVideoPanel: React.FC<PreviewVideoPanelProps> = ({
</div>
)}
{/* 预览成功 */}
{/* 预览成功 + 标题叠加 */}
{hasPreview && (
<div className="xx-preview-video">
<video src={previewResult.videoUrl} controls preload="metadata" />
<div style={{ position: "relative" }}>
<div className="xx-preview-video">
<video src={previewResult.videoUrl} controls preload="metadata" />
</div>
{/* 标题叠加在视频画面上 */}
{showTitlePreview && (
<div
style={{
position: "absolute",
...positionOverlayStyle(titleSettings!.position),
width: "100%",
zIndex: 1,
pointerEvents: "none",
}}
>
<span style={buildTitleStyle(titleSettings!)}>
{titleText && titleText.trim() ? titleText : "请选择或输入标题"}
</span>
</div>
)}
</div>
)}
{/* 标题实时预览区域 */}
{showTitlePreview && (
{/* 无视频时的标题预览(idle/loading/error 状态下仍然显示标题预览) */}
{!hasPreview && showTitlePreview && (
<div
className="xx-preview-title-section"
style={{
background: "rgba(0,0,0,0.3)",
borderRadius: 8,
minHeight: 64,
marginTop: 12,
padding: "12px 0",
borderTop: "1px solid rgba(255,255,255,0.08)",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<div
style={{
fontSize: 12,
color: "var(--text-tertiary)",
marginBottom: 8,
paddingLeft: 4,
}}
>
</div>
<div
style={{
background: "rgba(0,0,0,0.3)",
borderRadius: 8,
minHeight: 64,
display: "flex",
alignItems: "center",
...positionAlignStyle(titleSettings!.position),
}}
>
<span style={buildTitleStyle(titleSettings!)}>
{titleText && titleText.trim() ? titleText : "请选择或输入标题"}
</span>
</div>
<span style={buildTitleStyle(titleSettings!)}>
{titleText && titleText.trim() ? titleText : "请选择或输入标题"}
</span>
</div>
)}