feat: click-drag drawing, layer tree, settings modal, UI improvements
- interaction: click-drag drawing for 2-point tools (line, rect, circle, dimension, leader) - interaction: preview rendering during drag with setPreviewElement - interaction: handleDrawDown only sets phase=drawing on first point - CanvasArea: sync activeLayerId to LayerManager - CanvasArea: callback refresh useEffect prevents stale closures - App.tsx: functional setElements updates for handleElementCreated/Deleted/Modified - LayerPanel: tree structure with sub-layers (onReorder, onAddSubLayer) - TreeView: drag-and-drop reordering support - RightSidebar: onReorder, onAddSubLayer, onUpdateElement props - PropertiesPanel: onUpdateElement prop - SettingsModal: personal/password/language/theme/users/plugins/AI tabs - styles.css: extensive UI styling additions - types: updated RightSidebarProps, CanvasAreaProps, LayerPanelProps
This commit is contained in:
@@ -349,6 +349,21 @@ export class InteractionEngine {
|
||||
this.selectionEngine.finishBoxSelect(this.allElements);
|
||||
this.emitSelectionChange();
|
||||
this.requestRender();
|
||||
return;
|
||||
}
|
||||
|
||||
// Click-drag: confirm draw on mouseup for 2-point tools
|
||||
if (this.state.phase === 'drawing' && this.state.points.length >= 1) {
|
||||
const raw = this.getWorldCoords(e);
|
||||
const snapped = this.applySnap(raw.x, raw.y);
|
||||
const final = this.applyOrtho(snapped.x, snapped.y);
|
||||
const tool = this.state.activeTool;
|
||||
// For 2-point tools: use mouseup position as second point
|
||||
if (tool === 'line' || tool === 'rect' || tool === 'circle' || tool === 'dimension' || tool === 'leader') {
|
||||
this.state.points.push(final);
|
||||
this.confirmDraw();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,7 +481,10 @@ export class InteractionEngine {
|
||||
}
|
||||
|
||||
private handleDrawDown(pt: { x: number; y: number }): void {
|
||||
this.state.phase = 'drawing';
|
||||
// Clear any previous points when starting a new draw operation
|
||||
if (this.state.points.length === 0) {
|
||||
this.state.phase = 'drawing';
|
||||
}
|
||||
this.state.points.push(pt);
|
||||
|
||||
// Arc: auto-confirm after 3 points (center, start, end)
|
||||
@@ -481,12 +499,8 @@ export class InteractionEngine {
|
||||
return;
|
||||
}
|
||||
|
||||
// Line, rect, circle, dimension, leader: auto-confirm after 2 points
|
||||
if ((this.state.activeTool === 'line' || this.state.activeTool === 'rect' || this.state.activeTool === 'circle' || this.state.activeTool === 'dimension' || this.state.activeTool === 'leader') && this.state.points.length >= 2) {
|
||||
this.updatePreview(pt);
|
||||
this.confirmDraw();
|
||||
return;
|
||||
}
|
||||
// Line, rect, circle, dimension, leader: wait for mouseup (click-drag behavior)
|
||||
// Points are collected on mousedown, confirmed on mouseup
|
||||
|
||||
this.updatePreview(pt);
|
||||
this.notifyToolStateChanged();
|
||||
@@ -1000,6 +1014,7 @@ export class InteractionEngine {
|
||||
if (this.animationFrame !== null) return;
|
||||
this.animationFrame = requestAnimationFrame(() => {
|
||||
this.animationFrame = null;
|
||||
this.renderEngine.setPreviewElement(this.state.previewElement);
|
||||
this.renderEngine.render();
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user