Runtime Hooks
Plugins können auf den aktuellen Zustand des Konfigurators zugreifen – über React Hooks, die K3 beim Laden automatisch injiziert.
Lesende Hooks
import {
useConfigurationVariables,
useConfigurationVariable,
useBOM,
useTotalPrice,
useFormattedTotalPrice,
useApp,
useK3PluginSettings,
getSettings,
} from "k3-plugin-api";
const MyComponent = () => {
const variables = useConfigurationVariables(); // alle Konfigurationsvariablen
const color = useConfigurationVariable("color"); // einzelne Variable per Key
const bom = useBOM(); // Stückliste
const price = useTotalPrice(); // Gesamtpreis als Zahl
const formattedPrice = useFormattedTotalPrice(); // z.B. "1.299,00 €"
const app = useApp(); // App-Metadaten (Produkt, Plan…)
const settings = useK3PluginSettings("vendor.my-plugin"); // eigene Plugin-Settings
return <p>{formattedPrice}</p>;
};
Alle Hooks re-rendern die Komponente automatisch, wenn sich der jeweilige Wert ändert.
| Hook / Funktion | Was wird zurückgegeben |
|---|---|
useConfigurationVariables() | Alle Variablen mit key als Record<string, K3ConfigurationVariableEntry> |
useConfigurationVariable(key) | Einzelner Variablenwert per stabilem Key |
useBOM() | Aktuelle Stückliste (K3BomEntry[]) |
useTotalPrice() | Gesamtpreis als number |
useFormattedTotalPrice() | Lokalisierter Preisstring (z.B. "1.299,00 €") |
useApp() | App-Metadaten (K3AppInfo | null) – Produkt, Plan, Flags |
useK3PluginSettings(pluginId) | Plugin-Settings reaktiv (re-rendert bei Änderungen) |
getSettings(pluginId) | Plugin-Settings als Snapshot (nicht reaktiv) |
Die Hooks funktionieren nur in React-Komponenten, die innerhalb des Konfigurators gerendert werden. getSettings() kann auch außerhalb von Komponenten (z.B. in Callbacks) verwendet werden.
Merkmale setzen
Plugins können Konfigurationswerte nicht nur lesen, sondern auch aktiv setzen:
import {
useSetConfigurationVariable,
useAcceptConfigurationConflict,
useRejectConfigurationConflict,
} from "k3-plugin-api";
const MyControls = () => {
const setVariable = useSetConfigurationVariable();
const acceptConflict = useAcceptConfigurationConflict();
const rejectConflict = useRejectConfigurationConflict();
const onPickColor = async (valueId: number) => {
const res = await setVariable("color", valueId);
if (res.conflict) {
// Änderung wurde noch nicht übernommen – res.changes zeigt, was sich ändern würde
console.log("Würde auch ändern:", res.changes);
acceptConflict(); // oder: rejectConflict()
}
};
const onSetWidth = async () => {
await setVariable("width", 120); // Zahlenmerkmal: Rohwert, Snapping passiert intern
};
return <button onClick={() => onPickColor(42)}>Farbe setzen</button>;
};
| Hook / Funktion | Beschreibung |
|---|---|
useSetConfigurationVariable() | Gibt setVariable(keyOrId, value) zurück → Promise<K3SetVariableResult> |
useAcceptConfigurationConflict() | Nimmt den ausstehenden Regelkonflikt an und wendet die Änderungen an |
useRejectConfigurationConflict() | Verwirft den ausstehenden Regelkonflikt |
Bei einem Regelkonflikt wird die Änderung nicht sofort übernommen (result.conflict === true). result.changes listet die betroffenen Merkmale auf – danach kann mit accept oder reject entschieden werden.
Komponenteninstanzen steuern
Für Merkmale vom Typ „Komponente" können Instanzen reaktiv gelesen und verändert werden:
import {
useConfigurationInstances,
useAddConfigurationInstance,
useRemoveConfigurationInstance,
} from "k3-plugin-api";
const CabinetControls = () => {
const cabinets = useConfigurationInstances("cabinets"); // reaktive Liste
const addInstance = useAddConfigurationInstance();
const removeInstance = useRemoveConfigurationInstance();
return (
<>
<button onClick={() => addInstance("cabinet")}>Schrank hinzufügen</button>
{cabinets.map((c) => (
<button key={c.id} onClick={() => removeInstance(c.id)}>
{c.label} entfernen
</button>
))}
</>
);
};
| Hook / Funktion | Beschreibung |
|---|---|
useConfigurationInstances(keyOrId) | Reaktive Liste der Instanzen einer Komponenten-Variable |
useAddConfigurationInstance() | Gibt add(valueKeyOrId, parentInstanceId?) zurück → Promise<K3SetVariableResult> |
useRemoveConfigurationInstance() | Gibt remove(instanceId) zurück → Promise<K3SetVariableResult> |
useOpenInstance() | Reaktiv: die Instanz, die der Nutzer gerade in der Seitenleiste offen hat (K3OpenInstance) |
useOpenInstance() sagt, welche von mehreren gleichartigen Unterkonfigurationen gerade bearbeitet wird. Auf der obersten Ebene ist nichts offen, dann ist isRoot === true.
Kamera steuern
Ein Plugin kann die Kamera des Viewers setzen, etwa um senkrecht auf ein Seitenteil zu schauen, sobald der Nutzer es öffnet:
import { useOpenInstance, useSetCameraPosition } from "k3-plugin-api";
const setCameraPosition = useSetCameraPosition();
const openInstance = useOpenInstance();
useEffect(() => {
if (openInstance.id !== sidewallId) return;
// 1 m entlang der Wandnormale heraustreten und zurückschauen.
setCameraPosition({
position: [wall.x + normal.x, wall.y, wall.z + normal.z],
lookAt: [wall.x, wall.y, wall.z],
objectNames: [wallObjectName], // K3 rahmt auf diese Objekte ein
});
return () => setCameraPosition(null); // Kamera wieder freigeben
}, [openInstance.id, sidewallId, setCameraPosition]);
camera.position direkt setzenEin Schreibzugriff über useThree() wird im nächsten Frame überschrieben – das K3-Kamerasystem und die OrbitControls treiben die Kamera fortlaufend. Nur useSetCameraPosition() geht denselben Weg wie die benannten Kameras des Szenen-Editors.
Felder von K3CameraTarget:
| Feld | Bedeutung |
|---|---|
position | Weltkoordinaten [x, y, z], auf die die Kamera fährt |
lookAt | Weltkoordinaten, auf die die Kamera zielt |
focusType | "dynamic" (Standard): K3 rahmt auf die Bounding-Box von objectNames/modelIds ein und behält die Richtung. "static": position und lookAt werden unverändert genutzt |
objectNames | Beschränkt den dynamischen Fokus auf diese Three.js-Objektnamen |
modelIds | Beschränkt den dynamischen Fokus auf diese K3-Modell-IDs |
zoom | Zoom-Faktor (orthografisch) bzw. Multiplikator des Blickwinkels (perspektivisch) |
disableFocus | Unterdrückt K3s eigene Szenen-Fokus-Animation, solange diese Kamera aktiv ist (Standard true) |
Es gibt nur eine Kamera. Setzen mehrere Plugins gleichzeitig, gewinnt das letzte; die Übernahme wird geloggt. Geben Sie die Kamera mit setCameraPosition(null) wieder frei – das wirkt nur, wenn Ihr Plugin sie noch hält.
Wie Sie zusätzlich die Drehung der Kamera einschränken, steht unter Orbit-Rotation einschränken.
Merkmale rendern: StandaloneVariable
Mit der StandaloneVariable-Komponente kann ein einzelnes Merkmal direkt in der Plugin-UI gerendert werden – unabhängig davon, auf welchem Schritt es im Konfigurator liegt:
import { StandaloneVariable } from "k3-plugin-api";
const MyWidget = () => (
<div>
<StandaloneVariable variableKey="color" />
<StandaloneVariable variableKey="width" />
</div>
);
Das Merkmal muss im Konfigurator angelegt sein. Es kann optional „aus dem Schritt entfernt" werden, damit es nur hier erscheint und nicht in der normalen Gruppenansicht.