Files
claude-office/src/lib/positions.ts
T

63 lines
1.8 KiB
TypeScript
Raw Normal View History

import { MEETING_CENTER, ZONES } from "./constants";
import type { Point } from "./types";
export interface DeskSlot {
x: number;
y: number;
}
function gridSlots(
zone: { x: number; y: number; width: number; height: number },
cols: number,
rows: number,
padX: number,
padTop: number,
padBottom: number,
): DeskSlot[] {
const availW = zone.width - padX * 2;
const availH = zone.height - padTop - padBottom;
const cellW = availW / cols;
const cellH = availH / rows;
const slots: DeskSlot[] = [];
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
slots.push({
x: Math.round(zone.x + padX + cellW * (col + 0.5)),
y: Math.round(zone.y + padTop + cellH * (row + 0.5)),
});
}
}
return slots;
}
/** 6 fixed desks for main agents (3 × 2). */
export const DESK_SLOTS = gridSlots(ZONES.desk, 3, 2, 60, 66, 40);
/** 8 hot desks for subagents (4 × 2). */
export const HOT_DESK_SLOTS = gridSlots(ZONES.hotDesk, 4, 2, 50, 70, 36);
/** Standing spots in the lounge, between the sofas and the reception desk. */
export const LOUNGE_ANCHORS: Point[] = (() => {
const lz = ZONES.lounge;
return [
{ x: lz.x + 200, y: lz.y + 88 },
{ x: lz.x + 265, y: lz.y + 140 },
{ x: lz.x + 360, y: lz.y + 88 },
{ x: lz.x + 60, y: lz.y + 150 },
{ x: lz.x + 145, y: lz.y + 140 },
{ x: lz.x + 430, y: lz.y + 150 },
];
})();
/** Circular seats around the meeting table. */
export function meetingSeats(count: number, center: Point = MEETING_CENTER): Point[] {
const radius = Math.min(74 + count * 6, 108);
return Array.from({ length: count }, (_, i) => {
const angle = (2 * Math.PI * i) / count - Math.PI / 2;
return {
x: Math.round(center.x + Math.cos(angle) * radius),
y: Math.round(center.y + Math.sin(angle) * radius),
};
});
}