feat(text-tool): implement Photoshop-style on-canvas text editor
- Replaced modal dialog with inline on-canvas text editor - Text objects stored as editable entities (non-rasterized) - Live preview with transparent textarea overlay - Click on existing text to re-edit - Drag transform handles to move text - Auto-commit on click outside (via overlay) - Text selection with visible highlight - Hidden original text during editing to prevent double vision - Position alignment fixes for editing existing text - Keyboard shortcuts: Ctrl+Enter to commit, Escape to cancel 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -16,10 +16,34 @@ export interface TextSettings {
|
||||
letterSpacing: number;
|
||||
}
|
||||
|
||||
export interface TextObject {
|
||||
id: string;
|
||||
layerId: string;
|
||||
x: number;
|
||||
y: number;
|
||||
text: string;
|
||||
fontFamily: string;
|
||||
fontSize: number;
|
||||
fontStyle: FontStyle;
|
||||
fontWeight: FontWeight;
|
||||
color: string;
|
||||
align: TextAlign;
|
||||
baseline: TextBaseline;
|
||||
lineHeight: number;
|
||||
letterSpacing: number;
|
||||
}
|
||||
|
||||
export interface TextStore {
|
||||
settings: TextSettings;
|
||||
isDialogOpen: boolean;
|
||||
clickPosition: { x: number; y: number } | null;
|
||||
|
||||
// Text objects (non-rasterized text)
|
||||
textObjects: TextObject[];
|
||||
|
||||
// On-canvas editor state
|
||||
isOnCanvasEditorActive: boolean;
|
||||
editorPosition: { x: number; y: number } | null; // Canvas coordinates
|
||||
editorText: string; // Current text being edited
|
||||
editingTextId: string | null; // ID of text object being edited (null for new text)
|
||||
|
||||
// Setters
|
||||
setText: (text: string) => void;
|
||||
@@ -34,7 +58,15 @@ export interface TextStore {
|
||||
setLetterSpacing: (letterSpacing: number) => void;
|
||||
updateSettings: (settings: Partial<TextSettings>) => void;
|
||||
|
||||
// Dialog control
|
||||
openDialog: (x: number, y: number) => void;
|
||||
closeDialog: () => void;
|
||||
// Text object management
|
||||
addTextObject: (textObject: Omit<TextObject, 'id'>) => void;
|
||||
updateTextObject: (id: string, updates: Partial<TextObject>) => void;
|
||||
deleteTextObject: (id: string) => void;
|
||||
getTextObjectAt: (x: number, y: number, layerId: string) => TextObject | null;
|
||||
|
||||
// On-canvas editor control
|
||||
activateOnCanvasEditor: (canvasX: number, canvasY: number, textId?: string) => void;
|
||||
deactivateOnCanvasEditor: () => void;
|
||||
updateEditorPosition: (canvasX: number, canvasY: number) => void;
|
||||
updateEditorText: (text: string) => void;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user