fix: enable text tool pointer events and add tool options
Fixed two critical issues preventing text tool usage: **Pointer Event Integration:** - Added text tool to canvas pointer event handler - Text tool now properly responds to canvas clicks - Opens text dialog on click with correct position **Tool Options Bar:** - Added text tool options section to toolbar - Font family selection (6 common fonts) - Font size control (8-500px with number input) - Color picker with hex input - Helpful hint: "Click on canvas to add text" - Options bar now appears when text tool is active **Changes:** - components/canvas/canvas-with-tools.tsx: - Added dedicated text tool handler before selection tools - Handles pointer down event to open text dialog - components/editor/tool-options.tsx: - Imported useTextStore - Added isTextTool check - Created text tool options UI section - Shows font, size, and color controls Text tool is now fully functional - click the Type icon, then click anywhere on canvas to open the text editor dialog! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -202,6 +202,24 @@ export function CanvasWithTools() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Text tool
|
||||||
|
if (activeTool === 'text') {
|
||||||
|
const activeLayer = getActiveLayer();
|
||||||
|
if (!activeLayer || !activeLayer.canvas || activeLayer.locked) return;
|
||||||
|
|
||||||
|
const newPointer: PointerState = {
|
||||||
|
isDown: true,
|
||||||
|
x: canvasPos.x,
|
||||||
|
y: canvasPos.y,
|
||||||
|
prevX: canvasPos.x,
|
||||||
|
prevY: canvasPos.y,
|
||||||
|
pressure: e.pressure || 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
tools.text.onPointerDown(newPointer, {} as any, settings);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Selection tools
|
// Selection tools
|
||||||
const selectionTools = ['select', 'rectangular-select', 'elliptical-select', 'lasso-select', 'magic-wand'];
|
const selectionTools = ['select', 'rectangular-select', 'elliptical-select', 'lasso-select', 'magic-wand'];
|
||||||
if (e.button === 0 && !e.shiftKey && selectionTools.includes(activeTool)) {
|
if (e.button === 0 && !e.shiftKey && selectionTools.includes(activeTool)) {
|
||||||
|
|||||||
@@ -3,11 +3,13 @@
|
|||||||
import { useToolStore } from '@/store';
|
import { useToolStore } from '@/store';
|
||||||
import { useShapeStore } from '@/store/shape-store';
|
import { useShapeStore } from '@/store/shape-store';
|
||||||
import { useSelectionStore } from '@/store/selection-store';
|
import { useSelectionStore } from '@/store/selection-store';
|
||||||
|
import { useTextStore } from '@/store/text-store';
|
||||||
|
|
||||||
export function ToolOptions() {
|
export function ToolOptions() {
|
||||||
const { activeTool, settings, setSize, setOpacity, setHardness, setColor, setFlow } = useToolStore();
|
const { activeTool, settings, setSize, setOpacity, setHardness, setColor, setFlow } = useToolStore();
|
||||||
const { settings: shapeSettings, setShapeType } = useShapeStore();
|
const { settings: shapeSettings, setShapeType } = useShapeStore();
|
||||||
const { selectionType, setSelectionType } = useSelectionStore();
|
const { selectionType, setSelectionType } = useSelectionStore();
|
||||||
|
const { settings: textSettings, setFontFamily, setFontSize, setColor: setTextColor } = useTextStore();
|
||||||
|
|
||||||
// Drawing tools: brush, pencil, eraser
|
// Drawing tools: brush, pencil, eraser
|
||||||
const isDrawingTool = ['brush', 'eraser', 'pencil'].includes(activeTool);
|
const isDrawingTool = ['brush', 'eraser', 'pencil'].includes(activeTool);
|
||||||
@@ -24,8 +26,11 @@ export function ToolOptions() {
|
|||||||
// Selection tool
|
// Selection tool
|
||||||
const isSelectionTool = activeTool === 'select';
|
const isSelectionTool = activeTool === 'select';
|
||||||
|
|
||||||
|
// Text tool
|
||||||
|
const isTextTool = activeTool === 'text';
|
||||||
|
|
||||||
// Don't show options bar if no options available
|
// Don't show options bar if no options available
|
||||||
if (!isDrawingTool && !isFillTool && !isShapeTool && !isSelectionTool) {
|
if (!isDrawingTool && !isFillTool && !isShapeTool && !isSelectionTool && !isTextTool) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,6 +213,66 @@ export function ToolOptions() {
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Text Tool Options */}
|
||||||
|
{isTextTool && (
|
||||||
|
<>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<label className="text-sm font-medium text-card-foreground whitespace-nowrap">
|
||||||
|
Font:
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
value={textSettings.fontFamily}
|
||||||
|
onChange={(e) => setFontFamily(e.target.value)}
|
||||||
|
className="px-3 py-1.5 text-sm rounded-md border border-border bg-background text-foreground"
|
||||||
|
>
|
||||||
|
<option value="Arial">Arial</option>
|
||||||
|
<option value="Helvetica">Helvetica</option>
|
||||||
|
<option value="Times New Roman">Times New Roman</option>
|
||||||
|
<option value="Georgia">Georgia</option>
|
||||||
|
<option value="Courier New">Courier New</option>
|
||||||
|
<option value="Verdana">Verdana</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<label className="text-sm font-medium text-card-foreground whitespace-nowrap">
|
||||||
|
Size:
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min="8"
|
||||||
|
max="500"
|
||||||
|
value={textSettings.fontSize}
|
||||||
|
onChange={(e) => setFontSize(Number(e.target.value))}
|
||||||
|
className="w-20 px-2 py-1 text-sm rounded border border-border bg-background text-foreground"
|
||||||
|
/>
|
||||||
|
<span className="text-sm text-muted-foreground">px</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<label className="text-sm font-medium text-card-foreground whitespace-nowrap">
|
||||||
|
Color:
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="color"
|
||||||
|
value={textSettings.color}
|
||||||
|
onChange={(e) => setTextColor(e.target.value)}
|
||||||
|
className="h-8 w-16 rounded border border-border cursor-pointer"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={textSettings.color}
|
||||||
|
onChange={(e) => setTextColor(e.target.value)}
|
||||||
|
className="w-24 px-2 py-1 text-xs rounded border border-border bg-background text-foreground"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="text-sm text-muted-foreground italic">
|
||||||
|
Click on canvas to add text
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user