fix(canvas): 图片工具 - 移除独立图片编辑入口并保留连线生成
Co-authored-by: lmj15657306288-ui <lmj15657306288-ui@users.noreply.github.com>
This commit is contained in:
@@ -4,7 +4,7 @@ import { Brush, Camera, Copy, FileText, Globe2, Grid2x2, Layers3, Lock, LockOpen
|
|||||||
import type { CanvasNodeData } from "@/types/canvas";
|
import type { CanvasNodeData } from "@/types/canvas";
|
||||||
import type { NodeToolbarGroup } from "@/lib/canvas/tool-registry";
|
import type { NodeToolbarGroup } from "@/lib/canvas/tool-registry";
|
||||||
|
|
||||||
type ImageNodeActionToolId = "copyPrompt" | "reversePrompt" | "replace" | "resize" | "annotation" | "annotationEdit" | "textEdit" | "maskEdit" | "imageEdit" | "removeBackground" | "layerDecomposition" | "emotion" | "portraitTexture" | "crop" | "split" | "upscale" | "superResolve" | "angle" | "lighting" | "panorama" | "view";
|
type ImageNodeActionToolId = "copyPrompt" | "reversePrompt" | "replace" | "resize" | "annotation" | "annotationEdit" | "textEdit" | "maskEdit" | "removeBackground" | "layerDecomposition" | "emotion" | "portraitTexture" | "crop" | "split" | "upscale" | "superResolve" | "angle" | "lighting" | "panorama" | "view";
|
||||||
|
|
||||||
type ImageToolHandlers = {
|
type ImageToolHandlers = {
|
||||||
onUpload: (node: CanvasNodeData) => void;
|
onUpload: (node: CanvasNodeData) => void;
|
||||||
@@ -13,7 +13,6 @@ type ImageToolHandlers = {
|
|||||||
onAnnotationEdit: (node: CanvasNodeData) => void;
|
onAnnotationEdit: (node: CanvasNodeData) => void;
|
||||||
onTextEdit: (node: CanvasNodeData) => void;
|
onTextEdit: (node: CanvasNodeData) => void;
|
||||||
onMaskEdit: (node: CanvasNodeData) => void;
|
onMaskEdit: (node: CanvasNodeData) => void;
|
||||||
onImageEdit: (node: CanvasNodeData) => void;
|
|
||||||
onRemoveBackground: (node: CanvasNodeData) => void;
|
onRemoveBackground: (node: CanvasNodeData) => void;
|
||||||
onLayerDecomposition: (node: CanvasNodeData) => void;
|
onLayerDecomposition: (node: CanvasNodeData) => void;
|
||||||
onEmotion: (node: CanvasNodeData) => void;
|
onEmotion: (node: CanvasNodeData) => void;
|
||||||
@@ -117,15 +116,6 @@ const imageToolDefinitions: ImageToolDefinition[] = [
|
|||||||
order: 15,
|
order: 15,
|
||||||
run: (node, handlers) => handlers.onTextEdit(node),
|
run: (node, handlers) => handlers.onTextEdit(node),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: "imageEdit",
|
|
||||||
label: "图片编辑",
|
|
||||||
description: "用文字描述要修改的内容,生成新图片",
|
|
||||||
icon: () => <WandSparkles className="size-3.5" />,
|
|
||||||
group: "primary",
|
|
||||||
order: 20,
|
|
||||||
run: (node, handlers) => handlers.onImageEdit(node),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: "removeBackground",
|
id: "removeBackground",
|
||||||
label: "去除背景",
|
label: "去除背景",
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export function CanvasNodeImageEditDialog({
|
|||||||
}, [config, open, dataUrl]);
|
}, [config, open, dataUrl]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal open={open && Boolean(dataUrl)} onCancel={onClose} footer={null} centered destroyOnHidden width={860} title="图片编辑">
|
<Modal open={open && Boolean(dataUrl)} onCancel={onClose} footer={null} centered destroyOnHidden width={860} title={preset === "remove-background" ? "去除背景" : "图片编辑"}>
|
||||||
<div className="grid gap-5 md:grid-cols-[minmax(0,1fr)_300px]">
|
<div className="grid gap-5 md:grid-cols-[minmax(0,1fr)_300px]">
|
||||||
<div className="grid min-h-[320px] place-items-center overflow-hidden rounded-xl bg-black/5 p-3 dark:bg-white/[0.04]">
|
<div className="grid min-h-[320px] place-items-center overflow-hidden rounded-xl bg-black/5 p-3 dark:bg-white/[0.04]">
|
||||||
<img src={dataUrl} alt="待编辑图片" className="max-h-[58vh] max-w-full object-contain" draggable={false} />
|
<img src={dataUrl} alt="待编辑图片" className="max-h-[58vh] max-w-full object-contain" draggable={false} />
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ type CanvasNodeToolbarProps = {
|
|||||||
onDownload: (node: CanvasNodeData) => void;
|
onDownload: (node: CanvasNodeData) => void;
|
||||||
onSaveAsset: (node: CanvasNodeData) => void;
|
onSaveAsset: (node: CanvasNodeData) => void;
|
||||||
onMaskEdit: (node: CanvasNodeData) => void;
|
onMaskEdit: (node: CanvasNodeData) => void;
|
||||||
onImageEdit: (node: CanvasNodeData) => void;
|
|
||||||
onRemoveBackground: (node: CanvasNodeData) => void;
|
onRemoveBackground: (node: CanvasNodeData) => void;
|
||||||
onLayerDecomposition: (node: CanvasNodeData) => void;
|
onLayerDecomposition: (node: CanvasNodeData) => void;
|
||||||
onEmotion: (node: CanvasNodeData) => void;
|
onEmotion: (node: CanvasNodeData) => void;
|
||||||
@@ -103,7 +102,6 @@ export function CanvasNodeToolbar({
|
|||||||
onDownload,
|
onDownload,
|
||||||
onSaveAsset,
|
onSaveAsset,
|
||||||
onMaskEdit,
|
onMaskEdit,
|
||||||
onImageEdit,
|
|
||||||
onRemoveBackground,
|
onRemoveBackground,
|
||||||
onLayerDecomposition,
|
onLayerDecomposition,
|
||||||
onEmotion,
|
onEmotion,
|
||||||
@@ -231,13 +229,13 @@ export function CanvasNodeToolbar({
|
|||||||
}
|
}
|
||||||
copyText(prompt, "提示词已复制");
|
copyText(prompt, "提示词已复制");
|
||||||
};
|
};
|
||||||
const imageTools = buildImageToolbarTools(node, { onUpload, onToggleFreeResize, onAnnotate, onAnnotationEdit, onTextEdit, onMaskEdit, onImageEdit, onRemoveBackground, onLayerDecomposition, onEmotion, onPortraitTexture, onCrop, onUpscale, onSuperResolve, onAngle, onLighting, onPanorama, onViewImage, onCopyPrompt: copyImagePrompt, onReversePrompt });
|
const imageTools = buildImageToolbarTools(node, { onUpload, onToggleFreeResize, onAnnotate, onAnnotationEdit, onTextEdit, onMaskEdit, onRemoveBackground, onLayerDecomposition, onEmotion, onPortraitTexture, onCrop, onUpscale, onSuperResolve, onAngle, onLighting, onPanorama, onViewImage, onCopyPrompt: copyImagePrompt, onReversePrompt });
|
||||||
|
|
||||||
// 构建 ToolContext——供注册表解析工具
|
// 构建 ToolContext——供注册表解析工具
|
||||||
const nodeHoverHandlers = {
|
const nodeHoverHandlers = {
|
||||||
onNodeInfo: onInfo, onNodeDelete: onDelete, onNodeRetry: onRetry, onNodeEditText: onEditText, onNodeDecreaseFont: onDecreaseFont, onNodeIncreaseFont: onIncreaseFont,
|
onNodeInfo: onInfo, onNodeDelete: onDelete, onNodeRetry: onRetry, onNodeEditText: onEditText, onNodeDecreaseFont: onDecreaseFont, onNodeIncreaseFont: onIncreaseFont,
|
||||||
onNodeToggleDialog: onToggleDialog, onNodeAnnotate: onAnnotate, onNodeGenerateImage: onGenerateImage, onNodeUpload: onUpload, onNodeDownload: onDownload,
|
onNodeToggleDialog: onToggleDialog, onNodeAnnotate: onAnnotate, onNodeGenerateImage: onGenerateImage, onNodeUpload: onUpload, onNodeDownload: onDownload,
|
||||||
onNodeSaveAsset: onSaveAsset, onNodeMaskEdit: onMaskEdit, onNodeImageEdit: onImageEdit, onNodeRemoveBackground: onRemoveBackground, onNodeEmotion: onEmotion, onNodePortraitTexture: onPortraitTexture, onNodeCrop: onCrop,
|
onNodeSaveAsset: onSaveAsset, onNodeMaskEdit: onMaskEdit, onNodeRemoveBackground: onRemoveBackground, onNodeEmotion: onEmotion, onNodePortraitTexture: onPortraitTexture, onNodeCrop: onCrop,
|
||||||
onNodeSplit: (target) => onSplit(target, { rows: 2, columns: 2 }), onNodeUpscale: onUpscale, onNodeSuperResolve: onSuperResolve, onNodeAngle: onAngle, onNodeViewImage: onViewImage,
|
onNodeSplit: (target) => onSplit(target, { rows: 2, columns: 2 }), onNodeUpscale: onUpscale, onNodeSuperResolve: onSuperResolve, onNodeAngle: onAngle, onNodeViewImage: onViewImage,
|
||||||
onNodeExtractVideoFrames: onExtractVideoFrames, onNodeExtractAudioFromVideo: onExtractAudioFromVideo, onNodeTrimVideoSegments: onTrimVideoSegments, onNodeReversePrompt: onReversePrompt, onNodeToggleFreeResize: onToggleFreeResize,
|
onNodeExtractVideoFrames: onExtractVideoFrames, onNodeExtractAudioFromVideo: onExtractAudioFromVideo, onNodeTrimVideoSegments: onTrimVideoSegments, onNodeReversePrompt: onReversePrompt, onNodeToggleFreeResize: onToggleFreeResize,
|
||||||
onNodeSubtitles: onSubtitles, onNodeTimeline: onTimeline, onNodeToggleLocked: onToggleLocked, onNodeCopyPrompt: copyImagePrompt,
|
onNodeSubtitles: onSubtitles, onNodeTimeline: onTimeline, onNodeToggleLocked: onToggleLocked, onNodeCopyPrompt: copyImagePrompt,
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ type CanvasProjectMediaDialogsProps = {
|
|||||||
onAnnotationEdit: (node: CanvasNodeData, payload: CanvasImageAnnotationPayload) => void;
|
onAnnotationEdit: (node: CanvasNodeData, payload: CanvasImageAnnotationPayload) => void;
|
||||||
onMaskEdit: (node: CanvasNodeData, payload: CanvasImageMaskEditPayload) => void;
|
onMaskEdit: (node: CanvasNodeData, payload: CanvasImageMaskEditPayload) => void;
|
||||||
onUpscale: (node: CanvasNodeData, params: CanvasImageUpscaleParams) => void;
|
onUpscale: (node: CanvasNodeData, params: CanvasImageUpscaleParams) => void;
|
||||||
onImageEdit: (node: CanvasNodeData, payload: CanvasImageEditPayload) => void;
|
onImageOperation: (node: CanvasNodeData, payload: CanvasImageEditPayload) => void;
|
||||||
onLayerDecomposition: (node: CanvasNodeData, payload: CanvasImageLayerDecompositionPayload) => void;
|
onLayerDecomposition: (node: CanvasNodeData, payload: CanvasImageLayerDecompositionPayload) => void;
|
||||||
onDetectText: () => Promise<import("@/components/canvas/canvas-node-text-edit-dialog").CanvasImageTextLine[]>;
|
onDetectText: () => Promise<import("@/components/canvas/canvas-node-text-edit-dialog").CanvasImageTextLine[]>;
|
||||||
onTextEdit: (node: CanvasNodeData, payload: CanvasImageTextEditPayload) => void;
|
onTextEdit: (node: CanvasNodeData, payload: CanvasImageTextEditPayload) => void;
|
||||||
@@ -61,7 +61,7 @@ export function CanvasProjectMediaDialogs({
|
|||||||
onAnnotationEdit,
|
onAnnotationEdit,
|
||||||
onMaskEdit,
|
onMaskEdit,
|
||||||
onUpscale,
|
onUpscale,
|
||||||
onImageEdit,
|
onImageOperation,
|
||||||
onLayerDecomposition,
|
onLayerDecomposition,
|
||||||
onDetectText,
|
onDetectText,
|
||||||
onTextEdit,
|
onTextEdit,
|
||||||
@@ -74,7 +74,7 @@ export function CanvasProjectMediaDialogs({
|
|||||||
{annotationEditNode?.metadata?.content ? <CanvasNodeAnnotationDialog image={{ url: annotationEditNode.metadata.content, storageKey: annotationEditNode.metadata.storageKey }} editMode open onClose={onCloseAnnotationEdit} onConfirm={(payload) => { if (typeof payload !== "string") onAnnotationEdit(annotationEditNode, payload); }} /> : null}
|
{annotationEditNode?.metadata?.content ? <CanvasNodeAnnotationDialog image={{ url: annotationEditNode.metadata.content, storageKey: annotationEditNode.metadata.storageKey }} editMode open onClose={onCloseAnnotationEdit} onConfirm={(payload) => { if (typeof payload !== "string") onAnnotationEdit(annotationEditNode, payload); }} /> : null}
|
||||||
{maskEditNode?.metadata?.content ? <CanvasNodeMaskEditDialog dataUrl={maskEditNode.metadata.content} config={{ ...config, model: maskEditNode.metadata.model || config.model, imageModel: maskEditNode.metadata.model || config.imageModel, size: maskEditNode.metadata.size || config.size, quality: maskEditNode.metadata.quality || config.quality, count: String(maskEditNode.metadata.count || config.count) }} open onClose={onCloseMaskEdit} onConfirm={(payload) => onMaskEdit(maskEditNode, payload)} /> : null}
|
{maskEditNode?.metadata?.content ? <CanvasNodeMaskEditDialog dataUrl={maskEditNode.metadata.content} config={{ ...config, model: maskEditNode.metadata.model || config.model, imageModel: maskEditNode.metadata.model || config.imageModel, size: maskEditNode.metadata.size || config.size, quality: maskEditNode.metadata.quality || config.quality, count: String(maskEditNode.metadata.count || config.count) }} open onClose={onCloseMaskEdit} onConfirm={(payload) => onMaskEdit(maskEditNode, payload)} /> : null}
|
||||||
{upscaleNode?.metadata?.content ? <CanvasNodeUpscaleDialog dataUrl={upscaleNode.metadata.content} open onClose={onCloseUpscale} onConfirm={(params) => onUpscale(upscaleNode, params)} /> : null}
|
{upscaleNode?.metadata?.content ? <CanvasNodeUpscaleDialog dataUrl={upscaleNode.metadata.content} open onClose={onCloseUpscale} onConfirm={(params) => onUpscale(upscaleNode, params)} /> : null}
|
||||||
{imageEditNode?.metadata?.content ? <CanvasNodeImageEditDialog dataUrl={imageEditNode.metadata.content} preset={imageEditPreset} config={{ ...config, model: imageEditNode.metadata.model || config.model, imageModel: imageEditNode.metadata.model || config.imageModel, size: imageEditNode.metadata.size || config.size, quality: imageEditNode.metadata.quality || config.quality }} open onClose={onCloseImageEdit} onConfirm={(payload) => onImageEdit(imageEditNode, payload)} /> : null}
|
{imageEditNode?.metadata?.content ? <CanvasNodeImageEditDialog dataUrl={imageEditNode.metadata.content} preset={imageEditPreset} config={{ ...config, model: imageEditNode.metadata.model || config.model, imageModel: imageEditNode.metadata.model || config.imageModel, size: imageEditNode.metadata.size || config.size, quality: imageEditNode.metadata.quality || config.quality }} open onClose={onCloseImageEdit} onConfirm={(payload) => onImageOperation(imageEditNode, payload)} /> : null}
|
||||||
{layerDecompositionNode?.metadata?.content ? <CanvasNodeLayerDecompositionDialog dataUrl={layerDecompositionNode.metadata.content} config={{ ...config, model: layerDecompositionNode.metadata.model || config.model, imageModel: layerDecompositionNode.metadata.model || config.imageModel, size: layerDecompositionNode.metadata.size || config.size, quality: layerDecompositionNode.metadata.quality || config.quality }} open onClose={onCloseLayerDecomposition} onConfirm={(payload) => onLayerDecomposition(layerDecompositionNode, payload)} /> : null}
|
{layerDecompositionNode?.metadata?.content ? <CanvasNodeLayerDecompositionDialog dataUrl={layerDecompositionNode.metadata.content} config={{ ...config, model: layerDecompositionNode.metadata.model || config.model, imageModel: layerDecompositionNode.metadata.model || config.imageModel, size: layerDecompositionNode.metadata.size || config.size, quality: layerDecompositionNode.metadata.quality || config.quality }} open onClose={onCloseLayerDecomposition} onConfirm={(payload) => onLayerDecomposition(layerDecompositionNode, payload)} /> : null}
|
||||||
{textEditNode?.metadata?.content ? <CanvasNodeTextEditDialog dataUrl={textEditNode.metadata.content} open onClose={onCloseTextEdit} onDetect={onDetectText} onConfirm={(payload) => onTextEdit(textEditNode, payload)} /> : null}
|
{textEditNode?.metadata?.content ? <CanvasNodeTextEditDialog dataUrl={textEditNode.metadata.content} open onClose={onCloseTextEdit} onDetect={onDetectText} onConfirm={(payload) => onTextEdit(textEditNode, payload)} /> : null}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -875,7 +875,6 @@ function InfiniteCanvasPage() {
|
|||||||
setMaskEditNodeId,
|
setMaskEditNodeId,
|
||||||
setImageEditNodeId,
|
setImageEditNodeId,
|
||||||
setImageEditPreset,
|
setImageEditPreset,
|
||||||
openImageEditNode,
|
|
||||||
openBackgroundRemoval,
|
openBackgroundRemoval,
|
||||||
openLayerDecomposition,
|
openLayerDecomposition,
|
||||||
decomposeImageLayers,
|
decomposeImageLayers,
|
||||||
@@ -2171,7 +2170,6 @@ function InfiniteCanvasPage() {
|
|||||||
onFocusOutput={(nodeId) => focusCanvasImageNode(nodeId)}
|
onFocusOutput={(nodeId) => focusCanvasImageNode(nodeId)}
|
||||||
onReorderReferenceColumns={(fromColumnId, toColumnId) => reorderBatchReferenceColumns(contentNode.id, fromColumnId, toColumnId)}
|
onReorderReferenceColumns={(fromColumnId, toColumnId) => reorderBatchReferenceColumns(contentNode.id, fromColumnId, toColumnId)}
|
||||||
onMoveReferenceCell={(sourceRowId, sourceColumnIndex, targetRowId, targetColumnIndex) => moveBatchReferenceCell(contentNode.id, sourceRowId, sourceColumnIndex, targetRowId, targetColumnIndex)}
|
onMoveReferenceCell={(sourceRowId, sourceColumnIndex, targetRowId, targetColumnIndex) => moveBatchReferenceCell(contentNode.id, sourceRowId, sourceColumnIndex, targetRowId, targetColumnIndex)}
|
||||||
onReplaceReference={replaceCanvasNodeMedia}
|
|
||||||
onUploadReference={(rowId, columnIndex, file) => { void handleUploadBatchReference(contentNode.id, rowId, columnIndex, file); }}
|
onUploadReference={(rowId, columnIndex, file) => { void handleUploadBatchReference(contentNode.id, rowId, columnIndex, file); }}
|
||||||
onConnectStart={(event, handleId) => handleConnectStart(event, contentNode.id, "target", handleId)}
|
onConnectStart={(event, handleId) => handleConnectStart(event, contentNode.id, "target", handleId)}
|
||||||
onConnectDrop={(event, handleId) => handleConnectDrop(event, contentNode.id, handleId)}
|
onConnectDrop={(event, handleId) => handleConnectDrop(event, contentNode.id, handleId)}
|
||||||
@@ -2838,7 +2836,6 @@ function InfiniteCanvasPage() {
|
|||||||
onAnnotate={(node) => setAnnotationNodeId(node.id)}
|
onAnnotate={(node) => setAnnotationNodeId(node.id)}
|
||||||
onAnnotationEdit={openAnnotationEditNode}
|
onAnnotationEdit={openAnnotationEditNode}
|
||||||
onMaskEdit={(node) => setMaskEditNodeId(node.id)}
|
onMaskEdit={(node) => setMaskEditNodeId(node.id)}
|
||||||
onImageEdit={openImageEditNode}
|
|
||||||
onRemoveBackground={openBackgroundRemoval}
|
onRemoveBackground={openBackgroundRemoval}
|
||||||
onLayerDecomposition={openLayerDecomposition}
|
onLayerDecomposition={openLayerDecomposition}
|
||||||
onTextEdit={openTextEditNode}
|
onTextEdit={openTextEditNode}
|
||||||
@@ -3181,7 +3178,7 @@ function InfiniteCanvasPage() {
|
|||||||
onAnnotate={(node, dataUrl) => void saveAnnotatedImageNode(node, dataUrl)}
|
onAnnotate={(node, dataUrl) => void saveAnnotatedImageNode(node, dataUrl)}
|
||||||
onAnnotationEdit={(node, payload) => void editAnnotatedImageNode(node, payload)}
|
onAnnotationEdit={(node, payload) => void editAnnotatedImageNode(node, payload)}
|
||||||
onMaskEdit={(node, payload) => void maskEditImageNode(node, payload)}
|
onMaskEdit={(node, payload) => void maskEditImageNode(node, payload)}
|
||||||
onImageEdit={(node, payload) => void editImageNode(node, payload)}
|
onImageOperation={(node, payload) => void editImageNode(node, payload)}
|
||||||
onLayerDecomposition={(node, payload) => void decomposeImageLayers(node, payload)}
|
onLayerDecomposition={(node, payload) => void decomposeImageLayers(node, payload)}
|
||||||
onDetectText={() => {
|
onDetectText={() => {
|
||||||
const node = textEditNodeId ? nodeById.get(textEditNodeId) : null;
|
const node = textEditNodeId ? nodeById.get(textEditNodeId) : null;
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ export default function SharedCanvasPage() {
|
|||||||
}} onHoverStart={keepToolbar} onHoverEnd={hideToolbar} onConnectStart={unauthorized} onResize={() => undefined} onContentChange={unauthorized} onRetry={unauthorized} onOpenTaskDetails={unauthorized} onViewImage={(target) => setInfoNodeId(target.id)} onContextMenu={(event, nodeId) => openContextMenu(event, nodeId)} />)}
|
}} onHoverStart={keepToolbar} onHoverEnd={hideToolbar} onConnectStart={unauthorized} onResize={() => undefined} onContentChange={unauthorized} onRetry={unauthorized} onOpenTaskDetails={unauthorized} onViewImage={(target) => setInfoNodeId(target.id)} onContextMenu={(event, nodeId) => openContextMenu(event, nodeId)} />)}
|
||||||
</InfiniteCanvas>
|
</InfiniteCanvas>
|
||||||
|
|
||||||
<CanvasNodeToolbar node={dragRef.current ? null : toolbarNode} viewport={viewport} containerRef={containerRef} onKeep={keepToolbar} onLeave={hideToolbar} onInfo={(node) => setInfoNodeId(node.id)} onEditText={unauthorized} onDecreaseFont={unauthorized} onIncreaseFont={unauthorized} onToggleDialog={unauthorized} onAnnotate={unauthorized} onAnnotationEdit={unauthorized} onTextEdit={unauthorized} onGenerateImage={unauthorized} onUpload={unauthorized} onDownload={unauthorized} onSaveAsset={unauthorized} onMaskEdit={unauthorized} onImageEdit={unauthorized} onRemoveBackground={unauthorized} onLayerDecomposition={unauthorized} onEmotion={unauthorized} onPortraitTexture={unauthorized} onCrop={unauthorized} onSplit={unauthorized} onUpscale={unauthorized} onSuperResolve={unauthorized} onAngle={unauthorized} onLighting={unauthorized} onPanorama={unauthorized} onViewImage={unauthorized} onExtractVideoFrames={unauthorized} onExtractAudioFromVideo={unauthorized} onTrimVideoSegments={unauthorized} extractingVideoFrames={false} extractingAudio={false} trimmingVideo={false} onSubtitles={unauthorized} onTimeline={unauthorized} onReversePrompt={unauthorized} onRetry={unauthorized} onToggleFreeResize={unauthorized} onToggleLocked={unauthorized} onDelete={unauthorized} />
|
<CanvasNodeToolbar node={dragRef.current ? null : toolbarNode} viewport={viewport} containerRef={containerRef} onKeep={keepToolbar} onLeave={hideToolbar} onInfo={(node) => setInfoNodeId(node.id)} onEditText={unauthorized} onDecreaseFont={unauthorized} onIncreaseFont={unauthorized} onToggleDialog={unauthorized} onAnnotate={unauthorized} onAnnotationEdit={unauthorized} onTextEdit={unauthorized} onGenerateImage={unauthorized} onUpload={unauthorized} onDownload={unauthorized} onSaveAsset={unauthorized} onMaskEdit={unauthorized} onRemoveBackground={unauthorized} onLayerDecomposition={unauthorized} onEmotion={unauthorized} onPortraitTexture={unauthorized} onCrop={unauthorized} onSplit={unauthorized} onUpscale={unauthorized} onSuperResolve={unauthorized} onAngle={unauthorized} onLighting={unauthorized} onPanorama={unauthorized} onViewImage={unauthorized} onExtractVideoFrames={unauthorized} onExtractAudioFromVideo={unauthorized} onTrimVideoSegments={unauthorized} extractingVideoFrames={false} extractingAudio={false} trimmingVideo={false} onSubtitles={unauthorized} onTimeline={unauthorized} onReversePrompt={unauthorized} onRetry={unauthorized} onToggleFreeResize={unauthorized} onToggleLocked={unauthorized} onDelete={unauthorized} />
|
||||||
|
|
||||||
<div className="absolute bottom-5 left-5 z-[var(--z-panel-floating)]"><CanvasZoomControls scale={viewport.k} containerRef={containerRef} onScaleChange={setZoom} onFitContent={resetViewport} isMiniMapOpen={false} onToggleMiniMap={unauthorized} onOpenShortcuts={unauthorized} /></div>
|
<div className="absolute bottom-5 left-5 z-[var(--z-panel-floating)]"><CanvasZoomControls scale={viewport.k} containerRef={containerRef} onScaleChange={setZoom} onFitContent={resetViewport} isMiniMapOpen={false} onToggleMiniMap={unauthorized} onOpenShortcuts={unauthorized} /></div>
|
||||||
<div className="pointer-events-none absolute bottom-5 right-5 z-[var(--z-panel-floating)] max-w-[340px] text-right text-xs leading-5" style={{ color: theme.node.muted }}>访客操作仅在当前页面临时生效</div>
|
<div className="pointer-events-none absolute bottom-5 right-5 z-[var(--z-panel-floating)] max-w-[340px] text-right text-xs leading-5" style={{ color: theme.node.muted }}>访客操作仅在当前页面临时生效</div>
|
||||||
|
|||||||
@@ -962,11 +962,6 @@ export function useCanvasMediaTools({
|
|||||||
}
|
}
|
||||||
}, [bindGenerationTask, effectiveConfig, finishGenerationRequest, isAiConfigReady, message, nodesRef, persistMediaNodes, projectId, setConnections, setDialogNodeId, setNodes, setRunningNodeId, setSelectedConnectionId, setSelectedNodeIds, startGenerationRequest]);
|
}, [bindGenerationTask, effectiveConfig, finishGenerationRequest, isAiConfigReady, message, nodesRef, persistMediaNodes, projectId, setConnections, setDialogNodeId, setNodes, setRunningNodeId, setSelectedConnectionId, setSelectedNodeIds, startGenerationRequest]);
|
||||||
|
|
||||||
const openImageEditNode = useCallback((node: CanvasNodeData) => {
|
|
||||||
setImageEditPreset(null);
|
|
||||||
setImageEditNodeId(node.id);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const openBackgroundRemoval = useCallback((node: CanvasNodeData) => {
|
const openBackgroundRemoval = useCallback((node: CanvasNodeData) => {
|
||||||
setImageEditPreset("remove-background");
|
setImageEditPreset("remove-background");
|
||||||
setImageEditNodeId(node.id);
|
setImageEditNodeId(node.id);
|
||||||
@@ -1247,7 +1242,6 @@ export function useCanvasMediaTools({
|
|||||||
setMaskEditNodeId,
|
setMaskEditNodeId,
|
||||||
setImageEditNodeId,
|
setImageEditNodeId,
|
||||||
setImageEditPreset,
|
setImageEditPreset,
|
||||||
openImageEditNode,
|
|
||||||
openBackgroundRemoval,
|
openBackgroundRemoval,
|
||||||
openLayerDecomposition,
|
openLayerDecomposition,
|
||||||
decomposeImageLayers,
|
decomposeImageLayers,
|
||||||
|
|||||||
Reference in New Issue
Block a user