diff --git a/resources/views/rd/planning-design/index.blade.php b/resources/views/rd/planning-design/index.blade.php
index 26584332..e131dace 100644
--- a/resources/views/rd/planning-design/index.blade.php
+++ b/resources/views/rd/planning-design/index.blade.php
@@ -504,7 +504,7 @@
}
-
+
{{-- ===== Top Toolbar ===== --}}
@@ -1117,6 +1118,7 @@ function planningCanvas() {
panning: false,
panStartX: 0,
panStartY: 0,
+ spaceHeld: false,
// Connection Drawing
drawingConnection: false,
@@ -1509,11 +1511,22 @@ function planningCanvas() {
// ===== Canvas Events =====
onCanvasMouseDown(e) {
- if (e.target.closest('.pc-node') || e.target.closest('.pc-port')) return;
- if (this.tool === 'pan' || e.button === 1) {
+ if (e.target.closest('.pc-node') || e.target.closest('.pc-port')) {
+ // 스페이스바 누른 채 노드 위에서도 패닝 가능
+ if (this.spaceHeld) {
+ this.panning = true;
+ this.panStartX = e.clientX - this.panX * this.zoom;
+ this.panStartY = e.clientY - this.panY * this.zoom;
+ document.getElementById('canvasWrap')?.style.setProperty('cursor', 'grabbing');
+ e.preventDefault();
+ }
+ return;
+ }
+ if (this.tool === 'pan' || this.spaceHeld || e.button === 1) {
this.panning = true;
this.panStartX = e.clientX - this.panX * this.zoom;
this.panStartY = e.clientY - this.panY * this.zoom;
+ document.getElementById('canvasWrap')?.style.setProperty('cursor', 'grabbing');
e.preventDefault();
} else {
this.selectedNode = null;
@@ -1551,7 +1564,12 @@ function planningCanvas() {
this.pushHistory();
this.autoSave();
}
- if (this.panning) { this.panning = false; }
+ if (this.panning) {
+ this.panning = false;
+ const wrap = document.getElementById('canvasWrap');
+ if (this.spaceHeld) wrap?.style.setProperty('cursor', 'grab');
+ else wrap?.style.removeProperty('cursor');
+ }
if (this.drawingConnection) {
// Check if dropped on a node port
const target = e.target.closest('.pc-node');
@@ -1699,11 +1717,22 @@ function planningCanvas() {
// ===== Keyboard Shortcuts =====
handleKeyDown(e) {
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.isContentEditable) return;
+
+ // 스페이스바: 패닝 모드 (누르고 있는 동안)
+ if (e.key === ' ' || e.code === 'Space') {
+ e.preventDefault();
+ if (!this.spaceHeld) {
+ this.spaceHeld = true;
+ this._toolBeforeSpace = this.tool;
+ this.tool = 'pan';
+ document.getElementById('canvasWrap')?.style.setProperty('cursor', 'grab');
+ }
+ return;
+ }
+
if (e.key === 'Delete' || e.key === 'Backspace') {
if (this.selectedConnection) {
- this.connections = this.connections.filter(c => c.id !== this.selectedConnection.id);
- this.selectedConnection = null;
- this.pushHistory(); this.autoSave();
+ this.deleteSelectedConnection();
} else {
this.deleteSelectedNode();
}
@@ -1726,6 +1755,26 @@ function planningCanvas() {
}
},
+ handleKeyUp(e) {
+ if (e.key === ' ' || e.code === 'Space') {
+ if (this.spaceHeld) {
+ this.spaceHeld = false;
+ this.panning = false;
+ this.tool = this._toolBeforeSpace || 'select';
+ document.getElementById('canvasWrap')?.style.removeProperty('cursor');
+ }
+ }
+ },
+
+ // ===== Connection Delete =====
+ deleteSelectedConnection() {
+ if (!this.selectedConnection) return;
+ this.connections = this.connections.filter(c => c.id !== this.selectedConnection.id);
+ this.selectedConnection = null;
+ this.pushHistory();
+ this.autoSave();
+ },
+
// ===== Context Menu =====
showContextMenu(e) {
this.contextMenuPos = { x: e.clientX, y: e.clientY };