fix(studio): lock the canvas for scene-engine templates (no drag/resize)

For FLEXIBLE (Remotion / FlexStory) templates the render uses fixed positions —
dragging or resizing a layer on the Konva canvas does nothing to the output, which
is confusing. Make the canvas a read-only PREVIEW for those projects: the Konva
Layer is listening=false (no drag/select/transform), the Transformer is hidden, and
the auto-thumbnail capture is skipped so the flat Konva snapshot can't overwrite the
real rendered per-scene image. Editing happens only through the field form
(BlockFieldForm). AE/Konva templates are unchanged. Gated on isFlexStoryProject().

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-24 09:33:20 +03:30
parent 4bac5154ed
commit 825f25be55
+14 -6
View File
@@ -14,7 +14,7 @@ import {
resetNodeScale, resetNodeScale,
} from "@/lib/canvas-transform"; } from "@/lib/canvas-transform";
import { getShapeProps } from "@/lib/studio-layer-props"; import { getShapeProps } from "@/lib/studio-layer-props";
import { getActiveScene, useStudioStore } from "@/lib/studio-store"; import { getActiveScene, isFlexStoryProject, useStudioStore } from "@/lib/studio-store";
import type { Layer as StudioLayer } from "@/lib/studio-types"; import type { Layer as StudioLayer } from "@/lib/studio-types";
export const STAGE_WIDTH = 1280; export const STAGE_WIDTH = 1280;
@@ -36,6 +36,12 @@ export function CanvasEditor() {
const setSelectedLayer = useStudioStore((state) => state.setSelectedLayer); const setSelectedLayer = useStudioStore((state) => state.setSelectedLayer);
const updateLayer = useStudioStore((state) => state.updateLayer); const updateLayer = useStudioStore((state) => state.updateLayer);
const updateScene = useStudioStore((state) => state.updateScene); const updateScene = useStudioStore((state) => state.updateScene);
// Scene-engine (FlexStory) templates render in Remotion at fixed positions —
// dragging/resizing layers on the canvas does nothing, so the canvas becomes a
// read-only preview; editing happens only via the field form.
const lockedGeometry = useStudioStore((state) =>
isFlexStoryProject(state.chooseMode)
);
const thumbTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null); const thumbTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
@@ -90,9 +96,11 @@ export function CanvasEditor() {
} }
}, [selectedLayerId, sortedLayers, isPlaying]); }, [selectedLayerId, sortedLayers, isPlaying]);
// Auto-capture scene thumbnail whenever layers or background change // Auto-capture scene thumbnail whenever layers or background change. Skipped for
// scene-engine templates so the flat Konva snapshot doesn't overwrite the real
// rendered per-scene image.
useEffect(() => { useEffect(() => {
if (isPlaying || !activeSceneId) return; if (isPlaying || !activeSceneId || lockedGeometry) return;
if (thumbTimerRef.current) clearTimeout(thumbTimerRef.current); if (thumbTimerRef.current) clearTimeout(thumbTimerRef.current);
thumbTimerRef.current = setTimeout(() => { thumbTimerRef.current = setTimeout(() => {
@@ -182,9 +190,9 @@ export function CanvasEditor() {
height={stageHeight} height={stageHeight}
scaleX={scale} scaleX={scale}
scaleY={scale} scaleY={scale}
onMouseDown={isPlaying ? undefined : handleStagePointerDown} onMouseDown={isPlaying || lockedGeometry ? undefined : handleStagePointerDown}
> >
<Layer> <Layer listening={!lockedGeometry}>
<Rect <Rect
name="background" name="background"
x={0} x={0}
@@ -203,7 +211,7 @@ export function CanvasEditor() {
registerNode={registerNode} registerNode={registerNode}
/> />
))} ))}
{!isPlaying ? ( {!isPlaying && !lockedGeometry ? (
<Transformer <Transformer
ref={transformerRef} ref={transformerRef}
rotateEnabled rotateEnabled