feat: 用 Canvas 替换 CSS overlay 实现标题预览 #1246
Reference in New Issue
Block a user
Delete Branch "feat/title-preview-canvas"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
改动说明
根因: 当前用
<div>+ CSS textAlign/wordBreak/flex 叠加标题,CSS 文字布局和 ASS 字幕渲染的文字引擎不同,不同字数/字号/字体下行为不可预测,已反复修复仍不生效。方案: 在视频画面上用
<canvas>绘制标题文字,放弃 CSS overlay。主要改动
wrapText()逐字换行函数(与 ASS 换行行为一致)drawTitleOnCanvas()统一绘制函数(支持描边/阴影/多行居中/高清屏适配)loadedmetadata事件触发重绘positionOverlayStyle函数和buildTitleStyleCSS 函数验收标准
🚀 预览环境已部署
CI全绿,自动审批通过。
CI全绿,自动审批通过。
【阻塞级判定】
📊 审查概览
🔴 阻塞级问题(必须修复)
无
💡 改进建议(不阻塞合并)
[PreviewVideoPanel.tsx: 180-186] ResizeObserver 回调性能优化
ResizeObserver的回调中直接调用drawVideoTitle/drawNoVideoTitle可能会导致在窗口拖拽缩放时频繁触发重绘,造成性能开销。建议使用requestAnimationFrame对回调进行节流,确保每一帧只绘制一次,提升交互流畅度。[PreviewVideoPanel.tsx: 55] 缺少对 TitleSettings 属性的防御性检查
drawTitleOnCanvas函数中直接使用settings.size和settings.font。如果传入的titleSettings对象属性不完整(例如为空对象{}),会导致fontSize计算为NaN,进而导致ctx.font设置无效,文字无法绘制。建议增加默认值处理(如settings.size || 16)或确保上游数据完整性。✅ 良好实践
pointerEvents: "none"确保 Canvas 覆盖层不会阻挡视频控件的交互操作。ResizeObserver替代window.onresize,能够更精准地监听容器尺寸变化。devicePixelRatio,确保在高分屏下文字清晰不模糊。useEffect清理函数中正确调用了observer.disconnect(),避免了内存泄漏风险。wrapText) 使用逐字测量,能较好地模拟 ASS 字幕的渲染行为。🤖 由 AI 代码审查机器人自动生成 | 2026-08-05 11:00:27 | 模型:
🗑️ 预览环境已清理
PR #1246 已关闭或合并,对应的预览环境已被清理。