From 4e807525e9b0e0f259d523b4a81052cc20c6c63e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E9=B1=BC=E5=BC=80=E5=8F=91?= Date: Fri, 5 Jun 2026 17:43:28 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=B0=81=E9=9D=A2=E9=A2=84=E8=A7=88?= =?UTF-8?q?=E6=96=87=E5=AD=97=E6=88=AA=E6=96=AD=20=E2=80=94=20Canvas=20?= =?UTF-8?q?=E5=86=85=E9=83=A8=E5=B0=BA=E5=AF=B8=E4=BF=9D=E6=8C=81=201080?= =?UTF-8?q?=C3=971920=20=E4=B8=8D=E5=8F=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - renderCover: 移除动态改变 Canvas 内部尺寸的逻辑,始终用 1080×1920 - renderCover: 仅通过 resolutionScale 缩放元素位置/大小/阴影 - exportPng: 增加 targetWidth 参数,使用 multiplier 缩放到目标分辨率 - CoverDesign: 导出时传入 videoResolution.width,确保 720p/1080p 导出正确 --- tauri-app/src/hooks/useCoverFabric.ts | 19 ++++++++----------- .../src/pages/VideoCreation/CoverDesign.tsx | 2 +- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/tauri-app/src/hooks/useCoverFabric.ts b/tauri-app/src/hooks/useCoverFabric.ts index dc9fd06..c0916f2 100644 --- a/tauri-app/src/hooks/useCoverFabric.ts +++ b/tauri-app/src/hooks/useCoverFabric.ts @@ -284,14 +284,10 @@ export function useCoverFabric() { await loadCustomFont().catch(() => { }); - // 调整 canvas 内部渲染尺寸以匹配目标分辨率 - if (canvas.width !== targetWidth || canvas.height !== targetHeight) { - canvas.setDimensions( - { width: targetWidth, height: targetHeight }, - { cssOnly: false } - ); - } - + // Canvas 内部渲染尺寸始终保持 1080×1920 不变, + // 通过 resolutionScale 缩放所有元素,避免 Fabric.js 尺寸突变导致文字错乱。 + // CSS 显示尺寸由 initCanvas 固定为 337×600,不受此处影响。 + void targetHeight; // 保留接口兼容性,实际通过 multiplier 在导出时处理高度 const resolutionScale = targetWidth / CANVAS_WIDTH; canvas.clear(); @@ -392,11 +388,12 @@ export function useCoverFabric() { [loadBackground, loadAvatarImage] ); - // 导出 PNG - const exportPng = useCallback((): string => { + // 导出 PNG(通过 multiplier 缩放到目标分辨率) + const exportPng = useCallback((targetWidth?: number): string => { const canvas = fabricCanvasRef.current; if (!canvas) {return '';} - return canvas.toDataURL({ format: 'png', quality: 1, multiplier: 1 }); + const multiplier = (targetWidth ?? CANVAS_WIDTH) / CANVAS_WIDTH; + return canvas.toDataURL({ format: 'png', quality: 1, multiplier }); }, []); // 销毁 diff --git a/tauri-app/src/pages/VideoCreation/CoverDesign.tsx b/tauri-app/src/pages/VideoCreation/CoverDesign.tsx index 9a18a76..18017b9 100644 --- a/tauri-app/src/pages/VideoCreation/CoverDesign.tsx +++ b/tauri-app/src/pages/VideoCreation/CoverDesign.tsx @@ -332,7 +332,7 @@ export default function CoverDesign() { } } - const dataUrl = exportPng(); + const dataUrl = exportPng(videoResolution?.width); if (!dataUrl) { throw new Error('封面设计失败'); }