refactor(review): extract shared anchor math into reviewAnchors.ts

This commit is contained in:
Hiren Kangad
2026-03-12 22:09:12 +05:30
parent 318b7358e1
commit 7aa55b66f0
2 changed files with 52 additions and 14 deletions
+6 -14
View File
@@ -2,8 +2,8 @@ import { Container, Graphics, Text, TextStyle } from 'pixi.js';
import type { Viewport } from 'pixi-viewport';
import type { AnnotationStore } from '../stores/annotationStore';
import type { SceneManager } from './SceneManager';
import { getItemWorldBounds } from './SceneManager';
import { getAuthorColorHex, getAuthorInitial } from '../utils/authorColors';
import { getThreadAnchorWorld, getPointAnchorWorld } from './reviewAnchors';
const PIN_RADIUS = 11;
const PIN_COLOR_RESOLVED = 0x555555;
@@ -76,13 +76,7 @@ export class PinOverlay extends Container {
}
private _getAnchorWorld(thread: { object_id: string; anchor_type: string; pin_x: number | null; pin_y: number | null }): { x: number; y: number } | null {
const item = this._scene.items.get(thread.object_id);
if (!item) return null;
const b = getItemWorldBounds(item);
if (thread.anchor_type === 'point' && thread.pin_x != null && thread.pin_y != null) {
return { x: b.x + thread.pin_x * b.w, y: b.y + thread.pin_y * b.h };
}
return { x: b.x + b.w * 0.9, y: b.y };
return getThreadAnchorWorld(this._scene, thread);
}
/**
@@ -257,12 +251,10 @@ export class PinOverlay extends Container {
if (!this._ghostPin) return;
const item = this._scene.items.get(this._ghostPin.objectId);
if (!item) return;
const b = getItemWorldBounds(item);
const wx = b.x + this._ghostPin.pinX * b.w;
const wy = b.y + this._ghostPin.pinY * b.h;
const pos = getPointAnchorWorld(this._scene, this._ghostPin.objectId, this._ghostPin.pinX, this._ghostPin.pinY);
if (!pos) return;
const wx = pos.x;
const wy = pos.y;
const scale = 1 / this._viewport.scale.x;
const r = PIN_RADIUS * scale;
+46
View File
@@ -0,0 +1,46 @@
import type { SceneManager } from './SceneManager';
import { getItemWorldBounds } from './SceneManager';
/**
* Compute the world-space position for a point-pinned anchor.
* Returns null if the target object no longer exists in the scene.
*/
export function getPointAnchorWorld(
scene: SceneManager,
objectId: string,
pinX: number,
pinY: number,
): { x: number; y: number } | null {
const item = scene.items.get(objectId);
if (!item) return null;
const b = getItemWorldBounds(item);
return { x: b.x + pinX * b.w, y: b.y + pinY * b.h };
}
/**
* Compute the world-space position for an object-level anchor.
* Default position: top-right corner (90% x, 0% y).
*/
export function getObjectAnchorWorld(
scene: SceneManager,
objectId: string,
): { x: number; y: number } | null {
const item = scene.items.get(objectId);
if (!item) return null;
const b = getItemWorldBounds(item);
return { x: b.x + b.w * 0.9, y: b.y };
}
/**
* Compute anchor world position for a thread (point or object anchor).
* This is the unified entry point — replaces PinOverlay._getAnchorWorld().
*/
export function getThreadAnchorWorld(
scene: SceneManager,
thread: { object_id: string; anchor_type: string; pin_x: number | null; pin_y: number | null },
): { x: number; y: number } | null {
if (thread.anchor_type === 'point' && thread.pin_x != null && thread.pin_y != null) {
return getPointAnchorWorld(scene, thread.object_id, thread.pin_x, thread.pin_y);
}
return getObjectAnchorWorld(scene, thread.object_id);
}