diff --git a/src/components/image-editor/ImageCanvasEditorView.tsx b/src/components/image-editor/ImageCanvasEditorView.tsx index dc4512b39..1e50147d2 100644 --- a/src/components/image-editor/ImageCanvasEditorView.tsx +++ b/src/components/image-editor/ImageCanvasEditorView.tsx @@ -1116,7 +1116,6 @@ export function ImageCanvasEditorView({ () => ({ layersRef, viewportRef, - canvasViewportRef, canvasGenerationDialogsRef, canvasBackgroundColorRef, }), @@ -1156,6 +1155,7 @@ export function ImageCanvasEditorView({ layers, canvasGenerationDialogs, viewport, + canvasSize, canvasBackgroundColor, isViewportInteracting, canAccessProtectedData: authUi ? authUi.canAccessProtectedData : true, diff --git a/src/components/image-editor/useImageCanvasProjectPersistence.test.tsx b/src/components/image-editor/useImageCanvasProjectPersistence.test.tsx index 8ebb77d8f..1673a2011 100644 --- a/src/components/image-editor/useImageCanvasProjectPersistence.test.tsx +++ b/src/components/image-editor/useImageCanvasProjectPersistence.test.tsx @@ -113,12 +113,12 @@ function ProjectPersistenceHarness({ y: 0, scale: 1, }); + const canvasSize = { width: 900, height: 640 }; const [isViewportInteracting, setIsViewportInteracting] = useState(false); const [projectTitle, setProjectTitle] = useState(''); const [projectRenameValue, setProjectRenameValue] = useState(''); const layersRef = useRef(layers); const viewportRef = useRef(viewport); - const canvasViewportRef = useRef(null); const canvasGenerationDialogsRef = useRef(generationDialogs); const canvasBackgroundColorRef = useRef(canvasBackgroundColor); const selectedLayerRef = useRef(null); @@ -147,7 +147,6 @@ function ProjectPersistenceHarness({ () => ({ layersRef, viewportRef, - canvasViewportRef, canvasGenerationDialogsRef, canvasBackgroundColorRef, }), @@ -173,6 +172,7 @@ function ProjectPersistenceHarness({ layers, canvasGenerationDialogs: generationDialogs, viewport, + canvasSize, canvasBackgroundColor, isViewportInteracting, canAccessProtectedData, diff --git a/src/components/image-editor/useImageCanvasProjectPersistence.ts b/src/components/image-editor/useImageCanvasProjectPersistence.ts index b1617927e..44a447ce4 100644 --- a/src/components/image-editor/useImageCanvasProjectPersistence.ts +++ b/src/components/image-editor/useImageCanvasProjectPersistence.ts @@ -22,7 +22,6 @@ import { canvasDisplayViewportToViewport, type CanvasLayerResourceMetadata, DEFAULT_CANVAS_BACKGROUND_COLOR, - DEFAULT_CANVAS_SIZE, hydrateLayer, isInlineEditorMediaSource, serializeCanvasLayout, @@ -40,6 +39,7 @@ import { PROJECT_COVER_SNAPSHOT_ASSET_KIND, PROJECT_COVER_SNAPSHOT_OBJECT_ASSET_KIND, PROJECT_COVER_SNAPSHOT_SIZE, + type ProjectCoverSnapshotViewportSize, } from './ImageCanvasProjectCoverSnapshotModel'; type ProjectResourceOptions = { @@ -66,7 +66,6 @@ type CachedEditorProjectSnapshot = { type ImageCanvasProjectPersistenceRefs = { layersRef: RefObject; viewportRef: RefObject; - canvasViewportRef: RefObject; canvasGenerationDialogsRef: RefObject; canvasBackgroundColorRef: RefObject; }; @@ -90,6 +89,7 @@ type ImageCanvasProjectPersistenceOptions = { layers: CanvasLayer[]; canvasGenerationDialogs: CanvasGenerationDialogState[]; viewport: CanvasViewport; + canvasSize: ProjectCoverSnapshotViewportSize; canvasBackgroundColor: string; isViewportInteracting: boolean; canAccessProtectedData: boolean; @@ -116,21 +116,6 @@ function isEditorProjectRevisionConflict(error: unknown) { return error instanceof ApiClientError && error.status === 409; } -function resolveProjectCoverViewportSize( - viewportElement: HTMLDivElement | null, -) { - const width = viewportElement?.clientWidth ?? 0; - const height = viewportElement?.clientHeight ?? 0; - return { - width: - width > 0 && Number.isFinite(width) ? width : DEFAULT_CANVAS_SIZE.width, - height: - height > 0 && Number.isFinite(height) - ? height - : DEFAULT_CANVAS_SIZE.height, - }; -} - const EDITOR_PROJECT_LAYOUT_RETRYABLE_STATUS_CODES = new Set([ 408, 425, 429, 502, 503, 504, ]); @@ -330,6 +315,7 @@ export function useImageCanvasProjectPersistence({ layers, canvasGenerationDialogs, viewport, + canvasSize, canvasBackgroundColor, isViewportInteracting, canAccessProtectedData, @@ -354,6 +340,7 @@ export function useImageCanvasProjectPersistence({ const projectTitleRef = useRef('未命名画布'); const coverSnapshotSignatureRef = useRef(null); const coverSnapshotUploadRequestRef = useRef(0); + const coverSnapshotViewportSizeRef = useRef(canvasSize); const [projectId, setProjectId] = useState(null); const [isProjectReady, setIsProjectReady] = useState(false); const { @@ -366,6 +353,7 @@ export function useImageCanvasProjectPersistence({ restoreCanvasGenerationDialogs, applyCanvasBackgroundColor, } = setters; + coverSnapshotViewportSizeRef.current = canvasSize; const clearPendingProjectLayoutSave = useCallback(() => { pendingProjectLayoutSaveRef.current = null; @@ -478,9 +466,7 @@ export function useImageCanvasProjectPersistence({ } const coverViewport = canvasDisplayViewportToViewport(coverDisplayViewport); - const viewportSize = resolveProjectCoverViewportSize( - refs.canvasViewportRef.current, - ); + const viewportSize = coverSnapshotViewportSizeRef.current; const backgroundColor = refs.canvasBackgroundColorRef.current; const signature = buildProjectCoverSnapshotSignature({ layers: coverLayers,