调整字幕渲染逻辑

This commit is contained in:
lmk
2026-08-18 13:43:11 +08:00
parent dca668a56b
commit 610f914085
4 changed files with 41 additions and 10 deletions
+8 -6
View File
@@ -15,6 +15,7 @@ type CaptionElement struct {
Y string `json:"y" d:"center" dc:"垂直位置:top/center/bottom或像素值"`
FontSize int `json:"fontSize" d:"36" dc:"字号(type=text有效)"`
FontColor string `json:"fontColor" d:"#FFFFFF" dc:"字体颜色"`
TextAlign string `json:"textAlign" d:"center" dc:"水平对齐:left/center/right(默认center,type=text有效)"`
FontStroke string `json:"fontStroke" dc:"字体描边,如3px #000000(空=无描边)"`
BgColor string `json:"bgColor" dc:"背景色,如#FFFF00,空=透明"`
BgOpacity float64 `json:"bgOpacity" d:"1.0" dc:"背景透明度0-1"`
@@ -35,12 +36,13 @@ type SubtitleSegment struct {
// SubtitleStyle 字幕样式配置
type SubtitleStyle struct {
FontSize int `json:"fontSize" d:"48" dc:"字号(默认48)"`
FontColor string `json:"fontColor" d:"#FFFFFF" dc:"字体颜色(默认白色)"`
BgColor *string `json:"bgColor" dc:"背景色,空字符串=透明(默认#000000)。传空字符串 '' 可去掉背景色"`
BgOpacity *float64 `json:"bgOpacity" dc:"背景透明度0-1(默认0.4)。传0可使背景完全透明"`
X string `json:"x" d:"center" dc:"水平位置:left/center/right或像素值(默认center)"`
Y string `json:"y" d:"65%" dc:"垂直位置:top/center/bottom或像素值或百分比(默认65%)"`
FontSize int `json:"fontSize" d:"38" dc:"字号(默认38)"`
FontColor string `json:"fontColor" d:"#FFFFFF" dc:"字体颜色(默认白色)"`
FontStroke *string `json:"fontStroke" dc:"字体描边,如0.5px #000000(默认0.5px #000000极细)。传空字符串 '' 可去掉描边"`
BgColor *string `json:"bgColor" dc:"背景色,空=透明(默认无背景)。传颜色值如#FFFF00可背景"`
BgOpacity *float64 `json:"bgOpacity" dc:"背景透明度0-1(默认0.4,仅在设置bgColor时生效)。传0可使背景完全透明"`
X string `json:"x" d:"center" dc:"水平位置:left/center/right或像素值(默认center)"`
Y string `json:"y" d:"65%" dc:"垂直位置:top/center/bottom或像素值或百分比(默认65%)"`
}
// ---------- 创建字幕任务 ----------
+18 -3
View File
@@ -625,6 +625,16 @@ func (s *captionService) buildElemStyle(elem dto.CaptionElement, canvasWidth, ca
if elem.FontStroke != "" {
parts = append(parts, fmt.Sprintf("-webkit-text-stroke:%s;", elem.FontStroke))
}
// 水平对齐:覆盖全局 .text-element 的居中(flex 容器用 justify-content,多行文字用 text-align
switch elem.TextAlign {
case "left":
parts = append(parts, "text-align:left;")
parts = append(parts, "justify-content:flex-start;")
case "right":
parts = append(parts, "text-align:right;")
parts = append(parts, "justify-content:flex-end;")
}
}
return strings.Join(parts, "")
@@ -864,9 +874,10 @@ func hexToRGBA(hex string, alpha float64) string {
// subtitlesToElements 将外部传入的字幕时间线转为底部字幕元素
func subtitlesToElements(subtitles []dto.SubtitleSegment, style *dto.SubtitleStyle) []dto.CaptionElement {
// 应用默认值
fontSize := 48
fontSize := 38
fontColor := "#FFFFFF"
bgColor := "#000000"
fontStroke := "0.5px #000000" // 默认极细黑描边
bgColor := "" // 默认无背景色(透明)
bgOpacity := 0.4
if style != nil {
if style.FontSize > 0 {
@@ -875,9 +886,12 @@ func subtitlesToElements(subtitles []dto.SubtitleSegment, style *dto.SubtitleSty
if style.FontColor != "" {
fontColor = style.FontColor
}
// BgColor/BgOpacity 使用 *string/*float64,精确区分"没传"和"传了零值"
// FontStroke/BgColor/BgOpacity 使用指针,精确区分"没传"和"传了零值"
// - 没传字段 → 指针为 nil → 使用默认值
// - 传了 "" 或 0 → 指针非 nil → 按用户意愿设置
if style.FontStroke != nil {
fontStroke = *style.FontStroke
}
if style.BgColor != nil {
bgColor = *style.BgColor
}
@@ -914,6 +928,7 @@ func subtitlesToElements(subtitles []dto.SubtitleSegment, style *dto.SubtitleSty
Y: subtitleY,
FontSize: fontSize,
FontColor: fontColor,
FontStroke: fontStroke,
BgColor: bgColor,
BgOpacity: bgOpacity,
TrackIndex: 10,
+5
View File
@@ -258,6 +258,11 @@ func (s *templateService) applyStyles(elem *dto.CaptionElement, styles map[strin
elem.FontColor = strings.TrimSpace(color)
}
// 水平对齐
if ta, ok := styles["text-align"]; ok {
elem.TextAlign = strings.TrimSpace(ta)
}
// 字体描边(如 -webkit-text-stroke: 3px #000000,白字黑描边效果)
if stroke, ok := styles["-webkit-text-stroke"]; ok {
elem.FontStroke = strings.TrimSpace(stroke)
+10 -1
View File
@@ -119,6 +119,9 @@ body {
6. 文字也支持 width(模板指定 width 可覆盖渲染端的默认宽度,
精确控制换行范围,如把文字限定在两张图片之间不压图)。
7. 文字水平对齐支持 text-align: left / center / right
(默认 center 居中;写 left 靠左、right 靠右)。
======================================================================
-->
@@ -214,7 +217,7 @@ body {
data-key="product_desc" 产品卖点描述(底部两个图片之间)
最终效果:
- 白字,水平居中,落在 product_image_1 与 product_image_2 之间的空隙里
- 白字,水平靠左,落在 product_image_1 与 product_image_2 之间的空隙里
- width: calc(100% - 320px) 让文字宽度随画布自适应,正好落在两图空隙内,
任何分辨率下都不会压到图片
- 因为 image_2 图片比较小(比 image_1 矮,只占上面一段),
@@ -247,6 +250,10 @@ body {
color: #FFFFFF
文字颜色(白色)
text-align: left
文字水平对齐方式
→ left = 靠左(本元素默认) center = 居中 right = 靠右
提示:文字内容里可以用 \n 换行
-->
<div data-key="product_desc" data-start="0" data-duration="0" data-track-index="3"
@@ -257,6 +264,8 @@ body {
width: calc(100% - 320px);
font-size: 17px;
color: #FFFFFF;
text-align: left;
justify-content: flex-start;
">产品卖点描述</div>
<!--