fix(sticky): make size presets absolute again
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* stickyPresets — sticky note size presets (shared domain module).
|
||||
*
|
||||
* Presets are defined in screen-space so they preserve the same visual intent
|
||||
* regardless of viewport zoom. Scene data still stores world-space width and
|
||||
* fontSize; callers convert through the helpers below.
|
||||
* Presets are absolute semantic sizes. Zoom changes the camera/view only; it
|
||||
* must not change what S/M/L/XL/XXL mean for an existing sticky.
|
||||
*/
|
||||
|
||||
export type StickyTextSize = 'S' | 'M' | 'L' | 'XL' | 'XXL';
|
||||
@@ -36,37 +35,3 @@ export function nearestStickySize(fontSize: number): StickyTextSize {
|
||||
export function getStickyWidthForSize(fontSize: number): number {
|
||||
return STICKY_WIDTH_MAP[nearestStickySize(fontSize)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a preset's screen-space target to world-space sticky metrics.
|
||||
* objectScale is included so old non-1 scaled stickies still respond
|
||||
* predictably when a preset is applied.
|
||||
*/
|
||||
export function getStickyWorldMetricsForPreset(
|
||||
preset: StickyTextSize,
|
||||
zoom: number,
|
||||
objectScale: number = 1,
|
||||
): { fontSize: number; width: number } {
|
||||
const safeZoom = Math.max(zoom, 0.001);
|
||||
const safeScale = Math.max(Math.abs(objectScale), 0.001);
|
||||
return {
|
||||
fontSize: STICKY_FONT_MAP[preset] / (safeZoom * safeScale),
|
||||
width: STICKY_WIDTH_MAP[preset] / (safeZoom * safeScale),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a desired on-screen font size into world-space sticky metrics by
|
||||
* snapping to the nearest preset first.
|
||||
*/
|
||||
export function getStickyWorldMetricsForScreenFont(
|
||||
screenFontSize: number,
|
||||
zoom: number,
|
||||
objectScale: number = 1,
|
||||
): { fontSize: number; width: number; preset: StickyTextSize } {
|
||||
const preset = nearestStickySize(screenFontSize);
|
||||
return {
|
||||
...getStickyWorldMetricsForPreset(preset, zoom, objectScale),
|
||||
preset,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import { DrawingSprite } from './sprites/DrawingSprite';
|
||||
import type { DrawingObject } from './scene-format';
|
||||
import { TextEditor } from './TextEditor';
|
||||
import { clampTextFontSize } from './textLimits';
|
||||
import { DEFAULT_STICKY_PRESET, getStickyWorldMetricsForPreset } from './stickyPresets';
|
||||
import { DEFAULT_STICKY_PRESET, STICKY_FONT_MAP, STICKY_WIDTH_MAP } from './stickyPresets';
|
||||
|
||||
export enum ToolType {
|
||||
SELECT = 'SELECT',
|
||||
@@ -323,10 +323,8 @@ export function activateTool(
|
||||
const rect = container.getBoundingClientRect();
|
||||
const world = viewport.toWorld(e.clientX - rect.left, e.clientY - rect.top);
|
||||
|
||||
const zoom = viewport.scale.x;
|
||||
const presetMetrics = getStickyWorldMetricsForPreset(DEFAULT_STICKY_PRESET, zoom);
|
||||
const cardW = presetMetrics.width;
|
||||
const cardH = screenToWorld(60, zoom, 40, 200);
|
||||
const cardW = STICKY_WIDTH_MAP[DEFAULT_STICKY_PRESET];
|
||||
const cardH = 60; // auto-computed by StickySprite
|
||||
const stickyData = {
|
||||
id: crypto.randomUUID(),
|
||||
type: 'sticky' as const,
|
||||
@@ -343,7 +341,7 @@ export function activateTool(
|
||||
name: '',
|
||||
visible: true,
|
||||
text: '',
|
||||
fontSize: presetMetrics.fontSize,
|
||||
fontSize: STICKY_FONT_MAP[DEFAULT_STICKY_PRESET],
|
||||
fontFamily: 'Inter, system-ui, sans-serif',
|
||||
fill: '#ffd43b', // default yellow
|
||||
textColor: '#1a1a1a',
|
||||
|
||||
Reference in New Issue
Block a user