- Teile aus der Palette in die Szene ziehen: Stapel öffnet sich, erlaubte Plätze leuchten, Vorschau rastet ein; erlaubte Plätze per applyHiveOps auf einer Kopie (gleiche Regeln wie der Server) - Vorhandene Teile verschieben, auf „Entfernen“ ziehen; Einsätze aus offenen Zargen ziehen, dünne Teile mit Mindest-Trefferhöhe - Drücken auf ein Teil dreht das Modell nie (Prüfung erst beim Dreh- Beginn, passend zur Ereignisfolge von R3F); Abbruch mit Esc, Fenster- wechsel oder Maus ohne Taste - Zoom 0,6–2,5 per Knöpfen (Fokus bleibt an den Grenzen), Rad und Pinch - Verdunster verschieben fragt nicht mehr nach Behandlungsende; Ansage „… verschoben“; gemeinsame Helfer fresh-part und feeder-slots - Neuzeichnen nur bei Zeigerbewegung, geteilte Materialien Gates: Frontend lint, typecheck, 2804 Tests, build; 3D-Chunk 292 kB gzip. Review (Opus) und Browserprüfung Maus/Touch. Refs #21 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
23 lines
1.0 KiB
TypeScript
23 lines
1.0 KiB
TypeScript
import type { CatalogPartType, HiveFrame, HivePart } from "./types";
|
|
|
|
// A new part as the editor adds it (dialog and drag and drop alike): every
|
|
// state field set to its default, a new box filled with foundation frames.
|
|
|
|
/** Level 0, the first option of a choice. */
|
|
export function defaultPartState(type: CatalogPartType): HivePart["state"] {
|
|
const state: HivePart["state"] = {};
|
|
for (const field of type.stateSchema) state[field.key] = field.kind === "level" ? 0 : (field.options[0] ?? "");
|
|
return state;
|
|
}
|
|
|
|
/** Frames of a new box: every slot a foundation (spec 9.5). */
|
|
export function newBoxFrames(type: CatalogPartType): HiveFrame[] {
|
|
return Array.from({ length: type.frameSlots ?? 0 }, (_, index): HiveFrame => ({ slot: index + 1, type: "FOUNDATION" }));
|
|
}
|
|
|
|
export function freshPart(type: CatalogPartType, id: string, state: HivePart["state"] = defaultPartState(type)): HivePart {
|
|
const part: HivePart = { id, partTypeId: type.id, state };
|
|
if (type.kind === "BOX") part.frames = newBoxFrames(type);
|
|
return part;
|
|
}
|