fix: Canvas 内部分辨率不匹配导致画面变形 — 修复 ResizeObserver 未创建问题
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 42s
CI/CD Pipeline / Validate - Migration (alembic) (push) Successful in 2m4s
CI/CD Pipeline / Build Staging API Image (push) Successful in 2m18s
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 2m30s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 5m6s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 6m41s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m48s
CI/CD Pipeline / Validate - Code Quality (push) Successful in 9m4s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 1m5s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 2m18s
CI/CD Pipeline / Staging API Integration Tests (push) Failing after 3m42s
CI/CD Pipeline / Unit Tests (push) Successful in 14m8s
CI/CD Pipeline / Integration Tests (push) Successful in 6m3s
CI/CD Pipeline / CI Gate (push) Failing after 639h21m12s
CI/CD Pipeline / Production Browser E2E (push) Failing after 639h22m8s
CI/CD Pipeline / Canary Release to Production (push) Failing after 639h22m8s
CI/CD Pipeline / Build Production Worker Image (push) Failing after 639h22m10s
CI/CD Pipeline / Build Production Web Image (push) Failing after 639h22m10s
CI/CD Pipeline / Build Production API Image (push) Failing after 639h22m12s
CI/CD Pipeline / PR Build Worker Image (push) Failing after 639h36m13s
CI/CD Pipeline / PR Build API Image (push) Failing after 639h36m17s
CI/CD Pipeline / Frontend Lint (push) Failing after 639h36m19s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 639h36m21s
CI/CD Pipeline / Deploy Production (push) Failing after 639h55m54s
CI/CD Pipeline / PR Build Web Image (push) Failing after 640h10m1s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 42s
CI/CD Pipeline / Validate - Migration (alembic) (push) Successful in 2m4s
CI/CD Pipeline / Build Staging API Image (push) Successful in 2m18s
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 2m30s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 5m6s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 6m41s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m48s
CI/CD Pipeline / Validate - Code Quality (push) Successful in 9m4s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 1m5s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 2m18s
CI/CD Pipeline / Staging API Integration Tests (push) Failing after 3m42s
CI/CD Pipeline / Unit Tests (push) Successful in 14m8s
CI/CD Pipeline / Integration Tests (push) Successful in 6m3s
CI/CD Pipeline / CI Gate (push) Failing after 639h21m12s
CI/CD Pipeline / Production Browser E2E (push) Failing after 639h22m8s
CI/CD Pipeline / Canary Release to Production (push) Failing after 639h22m8s
CI/CD Pipeline / Build Production Worker Image (push) Failing after 639h22m10s
CI/CD Pipeline / Build Production Web Image (push) Failing after 639h22m10s
CI/CD Pipeline / Build Production API Image (push) Failing after 639h22m12s
CI/CD Pipeline / PR Build Worker Image (push) Failing after 639h36m13s
CI/CD Pipeline / PR Build API Image (push) Failing after 639h36m17s
CI/CD Pipeline / Frontend Lint (push) Failing after 639h36m19s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 639h36m21s
CI/CD Pipeline / Deploy Production (push) Failing after 639h55m54s
CI/CD Pipeline / PR Build Web Image (push) Failing after 640h10m1s
根因:ResizeObserver useEffect 依赖数组为空 [],组件挂载时 canPlay=false 导致 canvas 未渲染、canvasRef 为 null,effect 直接 return 后永远不会重新执行, canvas 内部分辨率停留在浏览器默认值 300×150(横屏 2:1),而 CSS 显示为竖屏容器。 修复: - useEffect 依赖改为 [useWebCodecs, canPlay],canPlay=true 时 canvas 已渲染, effect 重新执行并正确创建 ResizeObserver - 创建 ResizeObserver 前立即通过 getBoundingClientRect 设置 canvas 初始像素分辨率, 避免首帧使用默认 300×150 导致变形 - computeDrawRect 已正确基于 videoDimRef 做 letterbox 居中绘制,无需修改
This commit is contained in:
@@ -250,9 +250,17 @@ const FrontendPreviewPlayer: React.FC<FrontendPreviewPlayerProps> = ({
|
||||
// ── Canvas ResizeObserver ──
|
||||
const canvasContainerRef = useRef<HTMLDivElement>(null)
|
||||
useEffect(() => {
|
||||
if (!useWebCodecs || !canPlay) return
|
||||
const container = canvasContainerRef.current
|
||||
const canvas = canvasRef.current
|
||||
if (!container || !canvas) return
|
||||
// 立即设置一次 canvas 像素分辨率,避免默认 300×150 导致首帧变形
|
||||
const initRect = container.getBoundingClientRect()
|
||||
if (initRect.width > 0 && initRect.height > 0) {
|
||||
const dpr = window.devicePixelRatio || 1
|
||||
canvas.width = initRect.width * dpr
|
||||
canvas.height = initRect.height * dpr
|
||||
}
|
||||
const ro = new ResizeObserver((entries) => {
|
||||
for (const entry of entries) {
|
||||
const { width, height } = entry.contentRect
|
||||
@@ -264,7 +272,7 @@ const FrontendPreviewPlayer: React.FC<FrontendPreviewPlayerProps> = ({
|
||||
})
|
||||
ro.observe(container)
|
||||
return () => ro.disconnect()
|
||||
}, [])
|
||||
}, [useWebCodecs, canPlay])
|
||||
|
||||
// ── 未就绪 ──
|
||||
if (!ready || !assets.length) {
|
||||
|
||||
Reference in New Issue
Block a user