调整字幕渲染逻辑
This commit is contained in:
@@ -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%)"`
|
||||
}
|
||||
|
||||
// ---------- 创建字幕任务 ----------
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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>
|
||||
|
||||
<!--
|
||||
|
||||
Reference in New Issue
Block a user