feat: implement MoveCommand for undoable layer movement

Critical Fix - Move Tool Undo/Redo:
- Create MoveCommand class to track layer position changes
- Capture initial and final positions during move operation
- Only add to history if position actually changed
- Real-time visual feedback during drag (via updateLayer)
- Single undo point per move operation (not per pixel)

Command Pattern:
- MoveCommand extends BaseCommand
- Implements execute() and undo() methods
- captureAfterPosition() called on pointer up
- hasChanged() prevents no-op entries in history

Files:
- core/commands/move-command.ts - New command class
- tools/move-tool.ts - Updated to use MoveCommand
- core/commands/index.ts - Export MoveCommand

This fixes the critical issue where moving layers had no undo support.
Users can now undo/redo layer movements as expected.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-21 09:19:09 +01:00
parent b7b072f6d2
commit 6e35849f4e
3 changed files with 83 additions and 0 deletions

View File

@@ -1,3 +1,4 @@
export * from './base-command';
export * from './layer-commands';
export * from './draw-command';
export * from './move-command';

View File

@@ -0,0 +1,60 @@
import { BaseCommand } from './base-command';
import { useLayerStore } from '@/store/layer-store';
/**
* Command for moving a layer
* Captures start and end positions for undo/redo
*/
export class MoveCommand extends BaseCommand {
private layerId: string;
private beforePosition: { x: number; y: number };
private afterPosition: { x: number; y: number } | null = null;
constructor(layerId: string, beforePosition: { x: number; y: number }) {
super('Move Layer');
this.layerId = layerId;
this.beforePosition = beforePosition;
}
/**
* Capture the final position after the move is complete
*/
captureAfterPosition(x: number, y: number): void {
this.afterPosition = { x, y };
}
execute(): void {
if (!this.afterPosition) {
// No-op on first execute (position already set during drag)
return;
}
// Restore after position (for redo)
const { updateLayer } = useLayerStore.getState();
updateLayer(this.layerId, {
x: this.afterPosition.x,
y: this.afterPosition.y,
updatedAt: Date.now(),
});
}
undo(): void {
const { updateLayer } = useLayerStore.getState();
updateLayer(this.layerId, {
x: this.beforePosition.x,
y: this.beforePosition.y,
updatedAt: Date.now(),
});
}
/**
* Check if this move actually changed position
*/
hasChanged(): boolean {
if (!this.afterPosition) return false;
return (
this.beforePosition.x !== this.afterPosition.x ||
this.beforePosition.y !== this.afterPosition.y
);
}
}