UNPKG

@playcanvas/react

Version:

A React renderer for PlayCanvas – build interactive 3D applications using React's declarative paradigm.

57 lines 2.1 kB
import { useApp } from "@playcanvas/react/hooks"; import { useCallback, useEffect, useMemo, useRef } from "react"; import { Gizmo as PcGizmo, RotateGizmo, ScaleGizmo, TransformGizmo, TranslateGizmo } from "playcanvas"; /** * A gizmo component that allows you to manipulate the nodes in the scene. * @param props - The props for the gizmo. * @param props.camera - The camera component to use for the gizmo. * @param props.nodes - The nodes to attach the gizmo to. * @param props.mode - The mode of the gizmo. * @param props.onCommit - The function to call when the gizmo is committed. * @returns A gizmo component. * * @example * ```tsx * <Gizmo camera={camera} nodes={nodes} mode="rotate" onCommit={onCommit} /> * ``` */ export function Gizmo({ camera, nodes, mode, onCommit }) { const app = useApp(); const gizmoRef = useRef(null); const layer = useMemo(() => PcGizmo.createLayer(app), [app]); const onGizmoCommit = useCallback(() => { if (!gizmoRef.current) return; const updated = nodes.map((node) => ({ id: node.name, position: node.getPosition().toArray(), rotation: node.getEulerAngles().toArray(), scale: node.getLocalScale().toArray() })); onCommit(updated); }, [nodes, onCommit]); useEffect(() => { switch (mode) { case "rotate": gizmoRef.current = new RotateGizmo(camera, layer); break; case "scale": gizmoRef.current = new ScaleGizmo(camera, layer); break; case "translate": gizmoRef.current = new TranslateGizmo(camera, layer); break; } gizmoRef.current.on(TransformGizmo.EVENT_TRANSFORMEND, onGizmoCommit); return () => { gizmoRef.current?.destroy?.(); }; }, [camera, layer, mode]); useEffect(() => { if (!gizmoRef.current) return; gizmoRef.current.attach(nodes); }, [nodes]); return null; } //# sourceMappingURL=Gizmo.js.map