perf(text): remove 50ms editor delay + zoom-aware creation defaults

Replace setTimeout(50) with queueMicrotask for TEXT tool editor open
(matching STICKY tool). Add screenToWorld helper for zoom-aware font
sizes and sticky card dimensions. Remove unused Text/TextStyle imports.
This commit is contained in:
Hiren Kangad
2026-03-12 22:09:12 +05:30
parent 5158938eb3
commit d365049470
+21 -10
View File
@@ -10,7 +10,6 @@
import type { Viewport } from 'pixi-viewport'; import type { Viewport } from 'pixi-viewport';
import type { SceneManager } from './SceneManager'; import type { SceneManager } from './SceneManager';
import type { SelectionManager } from './SelectionManager'; import type { SelectionManager } from './SelectionManager';
import { Text, TextStyle } from 'pixi.js';
import { DrawingSprite } from './sprites/DrawingSprite'; import { DrawingSprite } from './sprites/DrawingSprite';
import type { DrawingObject } from './scene-format'; import type { DrawingObject } from './scene-format';
import { TextEditor } from './TextEditor'; import { TextEditor } from './TextEditor';
@@ -38,6 +37,14 @@ const defaultOptions: ToolOptions = {
type CleanupFn = (() => void) | null; type CleanupFn = (() => void) | null;
/**
* Compute world-space size from a desired screen-space size.
* Clamps to reasonable bounds to avoid extreme values.
*/
function screenToWorld(screenPx: number, zoom: number, min: number, max: number): number {
return Math.min(max, Math.max(min, screenPx / zoom));
}
export interface ToolContext { export interface ToolContext {
viewport: Viewport; viewport: Viewport;
scene: SceneManager; scene: SceneManager;
@@ -89,6 +96,7 @@ export function activateTool(
const rect = container.getBoundingClientRect(); const rect = container.getBoundingClientRect();
const world = viewport.toWorld(e.clientX - rect.left, e.clientY - rect.top); const world = viewport.toWorld(e.clientX - rect.left, e.clientY - rect.top);
const zoom = viewport.scale.x;
const textData = { const textData = {
id: crypto.randomUUID(), id: crypto.randomUUID(),
type: 'text' as const, type: 'text' as const,
@@ -105,7 +113,7 @@ export function activateTool(
name: '', name: '',
visible: true, visible: true,
text: ' ', // placeholder — will be replaced by user input text: ' ', // placeholder — will be replaced by user input
fontSize: opts.fontSize!, fontSize: screenToWorld(opts.fontSize!, zoom, 10, 72),
fill: opts.color!, fill: opts.color!,
fontFamily: 'sans-serif', fontFamily: 'sans-serif',
}; };
@@ -122,8 +130,8 @@ export function activateTool(
const canvasEl = container.querySelector('canvas'); const canvasEl = container.querySelector('canvas');
const domContainer = canvasEl?.parentElement ?? container; const domContainer = canvasEl?.parentElement ?? container;
// Small delay to let PixiJS render the text sprite // Use microtask instead of 50ms delay — PixiJS only needs one tick
setTimeout(() => { queueMicrotask(() => {
ctx.textEditor!.startEditing(item, viewport, domContainer, () => { ctx.textEditor!.startEditing(item, viewport, domContainer, () => {
// If user saved empty text, remove the item // If user saved empty text, remove the item
const text = (item.data as any).text?.trim(); const text = (item.data as any).text?.trim();
@@ -135,7 +143,7 @@ export function activateTool(
}); });
// Clear placeholder so user types from scratch // Clear placeholder so user types from scratch
ctx.textEditor!.clearText(); ctx.textEditor!.clearText();
}, 50); });
} }
// Switch back to select tool after placing // Switch back to select tool after placing
@@ -313,13 +321,16 @@ export function activateTool(
const rect = container.getBoundingClientRect(); const rect = container.getBoundingClientRect();
const world = viewport.toWorld(e.clientX - rect.left, e.clientY - rect.top); const world = viewport.toWorld(e.clientX - rect.left, e.clientY - rect.top);
const zoom = viewport.scale.x;
const cardW = screenToWorld(220, zoom, 120, 400);
const cardH = screenToWorld(66, zoom, 40, 200);
const stickyData = { const stickyData = {
id: crypto.randomUUID(), id: crypto.randomUUID(),
type: 'sticky' as const, type: 'sticky' as const,
x: world.x - 100, // center the 200px card on click x: world.x - cardW / 2,
y: world.y - 30, y: world.y - cardH / 2,
w: 200, w: cardW,
h: 60, // will be auto-computed by StickySprite h: cardH, // will be auto-computed by StickySprite
sx: 1, sx: 1,
sy: 1, sy: 1,
angle: 0, angle: 0,
@@ -329,7 +340,7 @@ export function activateTool(
name: '', name: '',
visible: true, visible: true,
text: '', text: '',
fontSize: opts.fontSize!, fontSize: screenToWorld(opts.fontSize!, zoom, 10, 48),
fontFamily: 'Inter, system-ui, sans-serif', fontFamily: 'Inter, system-ui, sans-serif',
fill: '#ffd43b', // default yellow fill: '#ffd43b', // default yellow
textColor: '#1a1a1a', textColor: '#1a1a1a',