I have 3 .GLB files which I want to change based on the state (Sort of a gallery and one main image), but it loads weirdly when changing and it doesn't render some 3d models. Using three.js, ChakraUI, and nextJS. As I've only begun to test out 3d model I don't know if this is the correct way to re-render or conditionally show the model.
Series.js
const itemData = [
{
image: "/images/ssr-img1.jpg",
model: "zombie.glb",
},
{
image: "/images/ssr-img2.jpg",
model: "star-icon.glb",
},
{
image: "/images/ssr-img3.jpg",
model: "dog.glb",
},
{
image: "/images/ssr-img4.jpg",
model: "zombie.glb",
},
{
image: "/images/ssr-img5.jpg",
model: "star-icon.glb",
},
{
image: "/images/ssr-img6.jpg",
model: "dog.glb",
},
];
export default function Series() {
const [items, setItems] = useState(itemData);
const [model, setModel] = useState("star-icon.glb");
const [currentImage, setCurrentImage] = useState(itemData[0].image);
return (
<Box id="nfc" bg="#edf3f8" py="2rem">
<Suspense fallback={null}>
<Test model={model} />
</Suspense>
<Title color="black">Rarity List</Title>
<Stack>
<HStack align="center" justify="center" my="1rem" maxW="full">
{items.map((item, index) => (
<Image
maxW="5%"
key={index}
onClick={() => setModel(item.model)}
cursor="pointer"
src={item.image}
alt="test"
/>
))}
</HStack>
</Stack>
</Box>
);
}
Test.js (The 3d model)
import { Canvas, useFrame } from "@react-three/fiber";
import { useGLTF, Environment, OrbitControls } from "@react-three/drei";
import { Box } from "@chakra-ui/react";
function Dog(props) {
const { scene } = useGLTF(props.model);
return <primitive object={scene} {...props} />;
}
function Zoom() {
useFrame((state, delta) => {
state.camera.zoom += delta / 100;
state.camera.updateProjectionMatrix();
});
}
export default function Test({ model }) {
return (
<Box h="xl">
<Canvas camera={{ position: [2.5, 2.5, -2.5], fov: 35 }}>
<ambientLight intensity={0.5} />
<Dog
model={model}
position={[-0.1, -0.2, 0]}
rotation={[0, Math.PI / 2, 0]}
scale={0.2}
/>
<Environment preset="city" />
<OrbitControls
minPolarAngle={Math.PI / 2.5}
maxPolarAngle={Math.PI / 2.5}
/>
<Zoom />
</Canvas>
</Box>
);
}