diff --git a/components/canvas/LiblibVideoCanvasReplica.tsx b/components/canvas/LiblibVideoCanvasReplica.tsx index c380ba47d..51e9685ce 100644 --- a/components/canvas/LiblibVideoCanvasReplica.tsx +++ b/components/canvas/LiblibVideoCanvasReplica.tsx @@ -161,6 +161,12 @@ type NodeContextState = { screenY: number; } | null; +type PresetControlAnchor = { + bottomY: number; + centerX: number; + topY: number; +}; + type CanvasCreateKind = | "image-input" | "video-input" @@ -1302,7 +1308,17 @@ export function LiblibVideoCanvasReplica({ canvasId, isLoading = false }: Liblib }, []); const isBusy = isLoading || isProjectLoading; - const selectedPresetMode = getPresetMode(selectedNode); + const selectedPresetControlNode = + selectedNode?.kind === "media" && selectedNode.inputType !== "audio" ? selectedNode : null; + const selectedPresetMode = getPresetMode(selectedPresetControlNode); + const selectedPresetAnchor = useMemo(() => { + if (!selectedPresetControlNode) return null; + return { + bottomY: Math.round(viewport.y + (selectedPresetControlNode.y + selectedPresetControlNode.height) * viewport.zoom), + centerX: Math.round(viewport.x + (selectedPresetControlNode.x + selectedPresetControlNode.width / 2) * viewport.zoom), + topY: Math.round(viewport.y + selectedPresetControlNode.y * viewport.zoom), + }; + }, [selectedPresetControlNode, viewport.x, viewport.y, viewport.zoom]); return (
) : null} - {selectedPresetMode ? : null} + {selectedPresetMode && selectedPresetAnchor ? ( + + ) : null} }) { +function PresetWorkflowControls({ + anchor, + mode, +}: { + anchor: PresetControlAnchor; + mode: Exclude; +}) { if (mode === "character-three-view") { return (
- - + +
); } @@ -1944,6 +1968,7 @@ function PresetWorkflowControls({ mode }: { mode: Exclude (null); return ( <> -
+
setToolbarMenu((current) => current === "panorama" ? null : "panorama")} /> setToolbarMenu((current) => current === "orbit" ? null : "orbit")} /> setToolbarMenu((current) => current === "lighting" ? null : "lighting")} /> @@ -2028,7 +2066,7 @@ function CharacterPresetToolbar() { ))}
- {toolbarMenu ? setToolbarMenu(null)} /> : null} + {toolbarMenu ? setToolbarMenu(null)} /> : null} ); } @@ -2116,9 +2154,23 @@ function AudioToVideoScene() { ); } -function PresetFloatingToolbar({ items }: { items: Array<[string, string]> }) { +function PresetFloatingToolbar({ + anchor, + items, +}: { + anchor?: PresetControlAnchor; + items: Array<[string, string]>; +}) { return ( -
+
{items.map(([label, message]) => (
{title} @@ -2446,9 +2508,11 @@ function SceneTool({ } function SceneToolbarPopover({ + anchor, menu, onClose, }: { + anchor?: PresetControlAnchor; menu: Exclude; onClose: () => void; }) { @@ -2462,7 +2526,15 @@ function SceneToolbarPopover({ if (menu === "lighting") { return ( -
+
打光
@@ -2483,7 +2555,15 @@ function SceneToolbarPopover({ } return ( -
+
{quickOptions[menu].map((option) => (
{[