From d161fc95a811bc8faf96bc11f5d8993ea5b01923 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 18:47:42 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=B0=81=E9=9D=A2=E8=AE=BE=E8=AE=A1=207?= =?UTF-8?q?20p=20=E9=A2=84=E8=A7=88=E4=B8=8E=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - loadBackground 居中改用 canvas.width/height,适配动态分辨率 - renderCover 修改 Canvas 内部尺寸后重设 CSS 预览尺寸,避免 overflow:hidden 裁剪内容 - 恢复 CoverDesign.tsx exportPng() 无参调用,匹配 hook 签名 --- tauri-app/src/hooks/useCoverFabric.ts | 37 ++++++++++++------- .../src/pages/VideoCreation/CoverDesign.tsx | 2 +- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/tauri-app/src/hooks/useCoverFabric.ts b/tauri-app/src/hooks/useCoverFabric.ts index c0916f2..c3ce64d 100644 --- a/tauri-app/src/hooks/useCoverFabric.ts +++ b/tauri-app/src/hooks/useCoverFabric.ts @@ -200,18 +200,20 @@ export function useCoverFabric() { } const fabricImg = new FabricImage(img); + const cw = canvas.width ?? CANVAS_WIDTH; + const ch = canvas.height ?? CANVAS_HEIGHT; // 使用 Math.min 确保图片完整显示在 Canvas 内,不会被过度放大 const scale = Math.min( - CANVAS_WIDTH / (fabricImg.width || 1), - CANVAS_HEIGHT / (fabricImg.height || 1) + cw / (fabricImg.width || 1), + ch / (fabricImg.height || 1) ); fabricImg.scale(scale); - // 居中定位 + // 居中定位(按 Canvas 当前实际尺寸) const scaledWidth = (fabricImg.width || 1) * scale; const scaledHeight = (fabricImg.height || 1) * scale; fabricImg.set({ - left: (CANVAS_WIDTH - scaledWidth) / 2, - top: (CANVAS_HEIGHT - scaledHeight) / 2, + left: (cw - scaledWidth) / 2, + top: (ch - scaledHeight) / 2, originX: 'left', originY: 'top', selectable: false, @@ -284,10 +286,20 @@ export function useCoverFabric() { await loadCustomFont().catch(() => { }); - // Canvas 内部渲染尺寸始终保持 1080×1920 不变, - // 通过 resolutionScale 缩放所有元素,避免 Fabric.js 尺寸突变导致文字错乱。 - // CSS 显示尺寸由 initCanvas 固定为 337×600,不受此处影响。 - void targetHeight; // 保留接口兼容性,实际通过 multiplier 在导出时处理高度 + // 调整 canvas 内部渲染尺寸以匹配目标分辨率 + if (canvas.width !== targetWidth || canvas.height !== targetHeight) { + canvas.setDimensions( + { width: targetWidth, height: targetHeight }, + { cssOnly: false } + ); + // 重新固定 CSS 预览尺寸,防止 Fabric.js 把 CSS 也改成目标分辨率 + // 导致容器 overflow:hidden 把内容裁掉 + canvas.setDimensions( + { width: DISPLAY_WIDTH, height: DISPLAY_HEIGHT }, + { cssOnly: true } + ); + } + const resolutionScale = targetWidth / CANVAS_WIDTH; canvas.clear(); @@ -388,12 +400,11 @@ export function useCoverFabric() { [loadBackground, loadAvatarImage] ); - // 导出 PNG(通过 multiplier 缩放到目标分辨率) - const exportPng = useCallback((targetWidth?: number): string => { + // 导出 PNG + const exportPng = useCallback((): string => { const canvas = fabricCanvasRef.current; if (!canvas) {return '';} - const multiplier = (targetWidth ?? CANVAS_WIDTH) / CANVAS_WIDTH; - return canvas.toDataURL({ format: 'png', quality: 1, multiplier }); + return canvas.toDataURL({ format: 'png', quality: 1, multiplier: 1 }); }, []); // 销毁 diff --git a/tauri-app/src/pages/VideoCreation/CoverDesign.tsx b/tauri-app/src/pages/VideoCreation/CoverDesign.tsx index 18017b9..9a18a76 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(videoResolution?.width); + const dataUrl = exportPng(); if (!dataUrl) { throw new Error('封面设计失败'); }