Using Transform Controls With Virtual Scene Components
Virtual Scene Component
A virtual scene component in this context is one that takes transform props like position
or rotation
but doesn't use them in the scene, instead using them somewhere else.
Traditionally applying transform props looks like this:
export function Box({
position,
}: {
position: [x: number, y: number, z: number];
}) {
return (
<mesh position={position}>
<boxGeometry />
</mesh>
);
}
The position
prop is passed to the mesh
element where it's used in the scene.
A virtual scene component on the other hand doesn't pass transform props to a scene object, instead using it somewhere else:
export function MyVirtualSceneComponent({
position,
}: {
position: [x: number, y: number, z: number];
}) {
useEffect(() => {
// Do something with the position prop
}, [position]);
return null;
}
Using Transform Controls
To have transform controls work with virtual scene components you need to render something to the scene, even if it's not used:
export function MyVirtualSceneComponent({
position,
}: {
position: [x: number, y: number, z: number];
}) {
useEffect(() => {
// Do something with the position prop
}, [position]);
return <group />;
}
Transform controls will now be enabled for the transform mode selected. Remember the mode is only enabled if the component takes the corresponding transform prop.
Don't want the transform controls to be affected by parent object transforms? Render an object through a portal:
import { createPortal, useThree } from "@react-three/fiber";
export function MyVirtualSceneComponent({
position,
}: {
position: [x: number, y: number, z: number];
}) {
const scene = useThree((state) => state.scene);
useEffect(() => {
// Do something with the position prop
}, [position]);
return createPortal(<group />, scene);
}