polish realtime canvas controls
This commit is contained in:
parent
f0340d3d96
commit
440f778bf3
@ -26,6 +26,7 @@ import {
|
||||
Eraser,
|
||||
Layers3,
|
||||
Loader2,
|
||||
MousePointer2,
|
||||
Paintbrush,
|
||||
Plus,
|
||||
Square,
|
||||
@ -69,6 +70,7 @@ type RealtimeConfig = {
|
||||
};
|
||||
|
||||
type RealtimeStatus = "idle" | "connecting" | "live" | "error";
|
||||
type RealtimeBrushMode = "select" | "brush" | "eraser" | "rect" | "circle" | "line";
|
||||
|
||||
type ImageLayer = {
|
||||
id: string;
|
||||
@ -160,7 +162,7 @@ const defaultRealtimeConfig: RealtimeConfig = {
|
||||
},
|
||||
};
|
||||
|
||||
function isShapeMode(mode: "brush" | "eraser" | "rect" | "circle" | "line") {
|
||||
function isShapeMode(mode: RealtimeBrushMode) {
|
||||
return mode === "rect" || mode === "circle" || mode === "line";
|
||||
}
|
||||
|
||||
@ -685,10 +687,10 @@ export function RealtimeCanvasDialog({
|
||||
|
||||
const [config, setConfig] = useState<RealtimeConfig>(defaultRealtimeConfig);
|
||||
const [status, setStatus] = useState<RealtimeStatus>("idle");
|
||||
const [statusMessage, setStatusMessage] = useState("等待连接");
|
||||
const [, setStatusMessage] = useState("等待连接");
|
||||
const [prompt, setPrompt] = useState(FALLBACK_PROMPT);
|
||||
const [previewUrl, setPreviewUrl] = useState("");
|
||||
const [brushMode, setBrushMode] = useState<"brush" | "eraser" | "rect" | "circle" | "line">("brush");
|
||||
const [brushMode, setBrushMode] = useState<RealtimeBrushMode>("brush");
|
||||
const [brushColor, setBrushColor] = useState<string>(DEFAULT_BRUSH_COLOR);
|
||||
const [canvasBackground, setCanvasBackground] = useState<string>(canvasBackgroundRef.current);
|
||||
const [imageLayers, setImageLayers] = useState<ImageLayer[]>([]);
|
||||
@ -1734,6 +1736,12 @@ export function RealtimeCanvasDialog({
|
||||
event.currentTarget.setPointerCapture(event.pointerId);
|
||||
return;
|
||||
}
|
||||
if (brushMode === "select") {
|
||||
setSelectedLayerId(DRAW_LAYER_ID);
|
||||
lastPointRef.current = null;
|
||||
shapeStartPointRef.current = null;
|
||||
return;
|
||||
}
|
||||
if (isShapeMode(brushMode)) {
|
||||
shapeStartPointRef.current = point;
|
||||
clearPreviewCanvas();
|
||||
@ -2347,6 +2355,21 @@ export function RealtimeCanvasDialog({
|
||||
</div>
|
||||
|
||||
<div className="flex h-10 shrink-0 items-center gap-0.5 rounded-full border border-black/10 bg-white px-1">
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
className={cn(
|
||||
"h-8 w-8 rounded-full text-zinc-600 hover:bg-zinc-100",
|
||||
brushMode === "select" && "bg-black text-white hover:bg-black"
|
||||
)}
|
||||
onClick={() => {
|
||||
setSelectedLayerId(DRAW_LAYER_ID);
|
||||
setBrushMode("select");
|
||||
}}
|
||||
title="鼠标"
|
||||
>
|
||||
<MousePointer2 className="h-4.5 w-4.5" />
|
||||
</Button>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
@ -2625,7 +2648,9 @@ export function RealtimeCanvasDialog({
|
||||
? "cursor-move"
|
||||
: brushMode === "brush" || brushMode === "eraser"
|
||||
? "cursor-none"
|
||||
: "cursor-crosshair"
|
||||
: brushMode === "select"
|
||||
? "cursor-default"
|
||||
: "cursor-crosshair"
|
||||
)}
|
||||
onPointerDown={handlePointerDown}
|
||||
onPointerMove={handlePointerMove}
|
||||
@ -2853,12 +2878,9 @@ export function RealtimeCanvasDialog({
|
||||
placeholder="输入指令,基于当前画布实时生成"
|
||||
className="h-9 flex-1 border-0 bg-transparent px-1 text-sm shadow-none focus-visible:ring-0"
|
||||
/>
|
||||
<span className="hidden whitespace-nowrap text-xs text-zinc-500 xl:inline">
|
||||
{statusMessage}
|
||||
</span>
|
||||
<Button
|
||||
size="sm"
|
||||
className="h-9 shrink-0 rounded-full px-4 font-medium"
|
||||
className="h-9 shrink-0 rounded-full bg-black px-4 font-medium text-white hover:bg-black/90"
|
||||
onClick={triggerGenerate}
|
||||
disabled={status === "connecting"}
|
||||
>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user