Reputation: 5167
I'm trying to get a simple export to OBJ button working on my react app, I'm using react-three/fiber and I'm following the export example from the Threejs website
The example code pass a scene
the the obj export function, but in react-three/fiber we have a Canvas component, so I naively attempt to pass a reference to that Canvas component to no avail, I'm getting the error object.traverse is not a function
Here is my code
import "./styles.css";
import { Fragment, useRef, useState } from "react";
import { Canvas, useFrame } from "@react-three/fiber";
import { OBJExporter } from "three/examples/jsm/exporters/OBJExporter";
// BOX COMPONENT
const Box = (props) => {
const mesh = useRef();
const [hovered, setHover] = useState(false);
const [active, setActive] = useState(false);
useFrame((state, delta) => (mesh.current.rotation.x += 0.01));
return (
<mesh
{...props}
ref={mesh}
scale={active ? 1.5 : 1}
onClick={(event) => setActive(!active)}
onPointerOver={(event) => setHover(true)}
onPointerOut={(event) => setHover(false)}
>
<boxGeometry args={[3, 3, 3]} />
<meshStandardMaterial color={hovered ? "hotpink" : "orange"} />
</mesh>
);
};
// APP
export default function App() {
const canvasRef = useRef(null);
const link = document.createElement("a");
link.style.display = "none";
document.body.appendChild(link);
function save(blob, filename) {
link.href = URL.createObjectURL(blob);
link.download = filename;
link.click();
}
function saveString(text, filename) {
save(new Blob([text], { type: "text/plain" }), filename);
}
const handleExport = () => {
const exporter = new OBJExporter();
const result = exporter.parse(canvasRef.current);
saveString(result, "object.obj");
};
return (
<Fragment>
<Canvas ref={canvasRef}>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Box position={[-1.2, -1, 0]} />
</Canvas>
<button onClick={handleExport}>Export OBJ</button>
</Fragment>
);
}
and a working example can be found here
Upvotes: 1
Views: 1215
Reputation: 21
I used Your solution but I wrapped everything in the group component and moved the ref to this group, so exports work without lights and cameras.
OBJExporter can export only meshes so maybe that was the origin of the issue.
Works for me with
react 18
@react-three/drei: "^9.40.0",
@react-three/fiber: "^8.9.1",
<Canvas camera={{ position: [14, 14, 14] }}>
<spotLight position={[0, 22, 0]} />
<group ref={canvasRef}>{children}</group> //use ref here
</Canvas>
Upvotes: 1