feat: add local edit to infinite canvas
This commit is contained in:
parent
ac70694ef3
commit
2d59e3e3c4
@ -956,6 +956,7 @@ const CANVAS_TOOLBAR_FALLBACK_ICONS: Record<CanvasToolbarItemKey, LucideIcon> =
|
|||||||
imageEnhance: Sparkles,
|
imageEnhance: Sparkles,
|
||||||
imageRemoveBackground: Scissors,
|
imageRemoveBackground: Scissors,
|
||||||
imageBoxCutout: Scan,
|
imageBoxCutout: Scan,
|
||||||
|
imageLocalEdit: Wand2,
|
||||||
imageRemoveWatermark: Eraser,
|
imageRemoveWatermark: Eraser,
|
||||||
imageResize: Maximize2,
|
imageResize: Maximize2,
|
||||||
imageTextEdit: Type,
|
imageTextEdit: Type,
|
||||||
|
|||||||
@ -33,6 +33,7 @@ import {
|
|||||||
Tag,
|
Tag,
|
||||||
type LucideIcon,
|
type LucideIcon,
|
||||||
UserRound,
|
UserRound,
|
||||||
|
Wand2,
|
||||||
Zap,
|
Zap,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import {
|
import {
|
||||||
@ -45,6 +46,7 @@ import {
|
|||||||
} from "@/lib/canvas/video-canvas-markers";
|
} from "@/lib/canvas/video-canvas-markers";
|
||||||
import {
|
import {
|
||||||
getCanvasToolbarItem,
|
getCanvasToolbarItem,
|
||||||
|
isCanvasToolbarItemEnabled,
|
||||||
normalizeCanvasToolbarConfig,
|
normalizeCanvasToolbarConfig,
|
||||||
type CanvasToolbarConfig,
|
type CanvasToolbarConfig,
|
||||||
} from "@/lib/canvas-toolbar-config";
|
} from "@/lib/canvas-toolbar-config";
|
||||||
@ -373,6 +375,14 @@ export function CanvasWorkspace({
|
|||||||
),
|
),
|
||||||
[nodes, selectedNodeIds]
|
[nodes, selectedNodeIds]
|
||||||
);
|
);
|
||||||
|
const selectedImageLocalEditItem = getCanvasToolbarItem(
|
||||||
|
canvasToolbarConfig,
|
||||||
|
"imageLocalEdit"
|
||||||
|
);
|
||||||
|
const selectedImageLocalEditEnabled = isCanvasToolbarItemEnabled(
|
||||||
|
canvasToolbarConfig,
|
||||||
|
"imageLocalEdit"
|
||||||
|
);
|
||||||
|
|
||||||
// Store actions
|
// Store actions
|
||||||
const setViewport = useCanvasStore((state) => state.setViewport);
|
const setViewport = useCanvasStore((state) => state.setViewport);
|
||||||
@ -386,6 +396,9 @@ export function CanvasWorkspace({
|
|||||||
const resizeNode = useCanvasStore((state) => state.resizeNode);
|
const resizeNode = useCanvasStore((state) => state.resizeNode);
|
||||||
const pushHistory = useCanvasStore((state) => state.pushHistory);
|
const pushHistory = useCanvasStore((state) => state.pushHistory);
|
||||||
const updateNode = useCanvasStore((state) => state.updateNode);
|
const updateNode = useCanvasStore((state) => state.updateNode);
|
||||||
|
const requestImageNodeAction = useCanvasStore(
|
||||||
|
(state) => state.requestImageNodeAction
|
||||||
|
);
|
||||||
const clearLastAddedNodeId = useCanvasStore((state) => state.clearLastAddedNodeId);
|
const clearLastAddedNodeId = useCanvasStore((state) => state.clearLastAddedNodeId);
|
||||||
const centerTimeoutRef = useRef<number | null>(null);
|
const centerTimeoutRef = useRef<number | null>(null);
|
||||||
const isMacPlatform = React.useMemo(() => {
|
const isMacPlatform = React.useMemo(() => {
|
||||||
@ -1870,9 +1883,34 @@ export function CanvasWorkspace({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* 缩放控制器 */}
|
{/* 选中图片快捷操作 */}
|
||||||
{selectedImageNodes.length > 0 && (
|
{selectedImageNodes.length > 0 && (
|
||||||
<div className="absolute bottom-16 left-4 z-30" data-canvas-overlay>
|
<div
|
||||||
|
className="absolute bottom-16 left-4 z-30 flex items-center gap-2"
|
||||||
|
data-canvas-overlay
|
||||||
|
>
|
||||||
|
{selectedImageLocalEditEnabled && selectedImageNodes.length === 1 ? (
|
||||||
|
<Button
|
||||||
|
variant={isWorkflowCanvas ? "outline" : "secondary"}
|
||||||
|
size="sm"
|
||||||
|
className={cn(
|
||||||
|
"h-8 gap-1.5 px-3 text-xs shadow-sm border border-border/60",
|
||||||
|
isWorkflowCanvas &&
|
||||||
|
"rounded-full border-[#dbe2ee] bg-white text-[#3b4860] shadow-[0_0_0_1px_rgba(219,226,238,0.26)] hover:bg-[#f7f9ff]"
|
||||||
|
)}
|
||||||
|
onClick={() =>
|
||||||
|
requestImageNodeAction(selectedImageNodes[0].id, "local-edit")
|
||||||
|
}
|
||||||
|
title={selectedImageLocalEditItem.label}
|
||||||
|
>
|
||||||
|
<CanvasToolbarIcon
|
||||||
|
className="h-3.5 w-3.5"
|
||||||
|
fallback={Wand2}
|
||||||
|
item={selectedImageLocalEditItem}
|
||||||
|
/>
|
||||||
|
{selectedImageLocalEditItem.label}
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
<Button
|
<Button
|
||||||
variant={isWorkflowCanvas ? "outline" : "secondary"}
|
variant={isWorkflowCanvas ? "outline" : "secondary"}
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -205,6 +205,12 @@ export const DEFAULT_CANVAS_TOOLBAR_ITEMS = [
|
|||||||
label: "框选抠图",
|
label: "框选抠图",
|
||||||
description: "框选区域后抠图",
|
description: "框选区域后抠图",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: "imageLocalEdit",
|
||||||
|
group: "节点工具栏",
|
||||||
|
label: "局部编辑",
|
||||||
|
description: "框选多个彩色区域并按区域提示词局部改图",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: "imageRemoveWatermark",
|
key: "imageRemoveWatermark",
|
||||||
group: "节点工具栏",
|
group: "节点工具栏",
|
||||||
|
|||||||
@ -71,7 +71,7 @@ export interface PickedObject {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ImageNodeActionType = 'box-cutout' | 'text-edit';
|
export type ImageNodeActionType = 'box-cutout' | 'text-edit' | 'local-edit';
|
||||||
|
|
||||||
export interface ImageNodeActionRequest {
|
export interface ImageNodeActionRequest {
|
||||||
nodeId: string;
|
nodeId: string;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user