refactor: centralize font-size clamps in textLimits.ts
Single source of truth for font-size constraints (text 6–160, sticky 8–96) used by creation defaults, resize-bake, and any future mutation paths. Replaces scattered hardcoded min/max values.
This commit is contained in:
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* textLimits — single source of truth for font-size constraints.
|
||||||
|
*
|
||||||
|
* Every path that creates, resizes, or mutates fontSize on text/sticky
|
||||||
|
* items must go through these helpers. This prevents inconsistent
|
||||||
|
* clamping when ranges are widened later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Plain text: generous range for direct manipulation
|
||||||
|
const TEXT_FONT_MIN = 6;
|
||||||
|
const TEXT_FONT_MAX = 160;
|
||||||
|
|
||||||
|
// Sticky note text: narrower range (card layout breaks at extremes)
|
||||||
|
const STICKY_FONT_MIN = 8;
|
||||||
|
const STICKY_FONT_MAX = 96;
|
||||||
|
|
||||||
|
export function clampTextFontSize(size: number): number {
|
||||||
|
return Math.round(Math.min(TEXT_FONT_MAX, Math.max(TEXT_FONT_MIN, size)));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clampStickyFontSize(size: number): number {
|
||||||
|
return Math.round(Math.min(STICKY_FONT_MAX, Math.max(STICKY_FONT_MIN, size)));
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ import type { SelectionManager } from './SelectionManager';
|
|||||||
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';
|
||||||
|
import { clampTextFontSize, clampStickyFontSize } from './textLimits';
|
||||||
|
|
||||||
export enum ToolType {
|
export enum ToolType {
|
||||||
SELECT = 'SELECT',
|
SELECT = 'SELECT',
|
||||||
@@ -117,7 +118,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: screenToWorld(DEFAULT_TEXT_SCREEN_FONT, zoom, 10, 72),
|
fontSize: clampTextFontSize(screenToWorld(DEFAULT_TEXT_SCREEN_FONT, zoom, 6, 160)),
|
||||||
fill: opts.color!,
|
fill: opts.color!,
|
||||||
fontFamily: 'sans-serif',
|
fontFamily: 'sans-serif',
|
||||||
};
|
};
|
||||||
@@ -344,7 +345,7 @@ export function activateTool(
|
|||||||
name: '',
|
name: '',
|
||||||
visible: true,
|
visible: true,
|
||||||
text: '',
|
text: '',
|
||||||
fontSize: screenToWorld(DEFAULT_STICKY_SCREEN_FONT, zoom, 10, 48),
|
fontSize: clampStickyFontSize(screenToWorld(DEFAULT_STICKY_SCREEN_FONT, zoom, 8, 96)),
|
||||||
fontFamily: 'Inter, system-ui, sans-serif',
|
fontFamily: 'Inter, system-ui, sans-serif',
|
||||||
fill: '#ffd43b', // default yellow
|
fill: '#ffd43b', // default yellow
|
||||||
textColor: '#1a1a1a',
|
textColor: '#1a1a1a',
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { PinOverlay } from '../canvas/PinOverlay';
|
|||||||
import { CropOverlay } from '../canvas/CropOverlay';
|
import { CropOverlay } from '../canvas/CropOverlay';
|
||||||
import { TextSprite } from '../canvas/sprites/TextSprite';
|
import { TextSprite } from '../canvas/sprites/TextSprite';
|
||||||
import { TextSharpnessManager } from '../canvas/textSharpness';
|
import { TextSharpnessManager } from '../canvas/textSharpness';
|
||||||
|
import { clampTextFontSize } from '../canvas/textLimits';
|
||||||
// PresenceOverlay removed — remote selection highlighting was too heavy for minimal benefit
|
// PresenceOverlay removed — remote selection highlighting was too heavy for minimal benefit
|
||||||
import { connectSocket, disconnectSocket } from '../socket';
|
import { connectSocket, disconnectSocket } from '../socket';
|
||||||
import api from '../api';
|
import api from '../api';
|
||||||
@@ -218,7 +219,7 @@ export function useCanvasSetup(deps: CanvasSetupDeps) {
|
|||||||
// Use average scale as font multiplier
|
// Use average scale as font multiplier
|
||||||
const scale = (absSx + absSy) / 2;
|
const scale = (absSx + absSy) / 2;
|
||||||
const d = item.data as any;
|
const d = item.data as any;
|
||||||
d.fontSize = Math.round(d.fontSize * scale);
|
d.fontSize = clampTextFontSize(d.fontSize * scale);
|
||||||
d.sx = item.data.sx > 0 ? 1 : -1;
|
d.sx = item.data.sx > 0 ? 1 : -1;
|
||||||
d.sy = item.data.sy > 0 ? 1 : -1;
|
d.sy = item.data.sy > 0 ? 1 : -1;
|
||||||
if (item.displayObject instanceof TextSprite) {
|
if (item.displayObject instanceof TextSprite) {
|
||||||
|
|||||||
Reference in New Issue
Block a user