mirror of
https://github.com/basketikun/infinite-canvas.git
synced 2026-08-07 01:54:24 +08:00
feat(canvas): enhance canvas toolbar for mode switching and improve selection box behavior
This commit is contained in:
@@ -199,6 +199,7 @@ function InfiniteCanvasPage() {
|
||||
const [chatSessions, setChatSessions] = useState<CanvasAssistantSession[]>([]);
|
||||
const [activeChatId, setActiveChatId] = useState<string | null>(null);
|
||||
const [viewport, setViewport] = useState<ViewportTransform>({ x: 0, y: 0, k: 1 });
|
||||
const [canvasTool, setCanvasTool] = useState<"select" | "pan">("select");
|
||||
const [size, setSize] = useState({ width: 1200, height: 720 });
|
||||
const [selectedNodeIds, setSelectedNodeIds] = useState<Set<string>>(new Set());
|
||||
const [selectedConnectionId, setSelectedConnectionId] = useState<string | null>(null);
|
||||
@@ -977,13 +978,6 @@ function InfiniteCanvasPage() {
|
||||
if (pendingConnectionCreateRef.current) cancelPendingConnectionCreate();
|
||||
if (event.button !== 0) return;
|
||||
|
||||
if (!event.ctrlKey && !event.metaKey) {
|
||||
setSelectionBox(null);
|
||||
setSelectedNodeIds(new Set());
|
||||
setSelectedConnectionId(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const world = screenToCanvas(event.clientX, event.clientY);
|
||||
const nextSelectionBox = {
|
||||
startWorldX: world.x,
|
||||
@@ -2775,6 +2769,7 @@ function InfiniteCanvasPage() {
|
||||
<InfiniteCanvas
|
||||
containerRef={containerRef}
|
||||
viewport={viewport}
|
||||
tool={canvasTool}
|
||||
backgroundMode={backgroundMode}
|
||||
onViewportChange={(next) => {
|
||||
setViewport(next);
|
||||
@@ -2863,17 +2858,17 @@ function InfiniteCanvasPage() {
|
||||
))}
|
||||
|
||||
{selectionBox ? (
|
||||
<div
|
||||
className="pointer-events-none absolute z-[100] border"
|
||||
<svg
|
||||
className="pointer-events-none absolute z-[100] overflow-visible"
|
||||
style={{
|
||||
left: Math.min(selectionBox.startWorldX, selectionBox.currentWorldX),
|
||||
top: Math.min(selectionBox.startWorldY, selectionBox.currentWorldY),
|
||||
width: Math.abs(selectionBox.currentWorldX - selectionBox.startWorldX),
|
||||
height: Math.abs(selectionBox.currentWorldY - selectionBox.startWorldY),
|
||||
borderColor: theme.canvas.selectionStroke,
|
||||
background: theme.canvas.selectionFill,
|
||||
}}
|
||||
/>
|
||||
>
|
||||
<rect width="100%" height="100%" fill={theme.canvas.selectionFill} stroke={theme.canvas.selectionStroke} strokeWidth={1.5 / viewport.k} strokeDasharray={`${10 / viewport.k} ${6 / viewport.k}`} />
|
||||
</svg>
|
||||
) : null}
|
||||
{pendingConnectionCreate ? <ConnectionCreateMenu pending={pendingConnectionCreate} onCreate={(type) => createConnectedNode(type, pendingConnectionCreate)} onClose={cancelPendingConnectionCreate} /> : null}
|
||||
{nodeCreatePosition ? (
|
||||
@@ -2918,6 +2913,7 @@ function InfiniteCanvasPage() {
|
||||
|
||||
<CanvasToolbar
|
||||
selectedCount={selectedNodeIds.size}
|
||||
canvasTool={canvasTool}
|
||||
canUndo={historyState.canUndo}
|
||||
canRedo={historyState.canRedo}
|
||||
backgroundMode={backgroundMode}
|
||||
@@ -2934,7 +2930,7 @@ function InfiniteCanvasPage() {
|
||||
onUpload={() => handleUploadRequest()}
|
||||
onDelete={() => deleteNodes(new Set(selectedNodeIds))}
|
||||
onClear={() => setClearConfirmOpen(true)}
|
||||
onDeselect={deselectCanvas}
|
||||
onCanvasToolChange={setCanvasTool}
|
||||
onBackgroundModeChange={setBackgroundMode}
|
||||
onShowImageInfoChange={setShowImageInfo}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user