I have a model of a 3D fridge, and loading it is successful. I am trying to make it drag across the screen when the user scrolls, and moving the div works, however the 3d object itself refreshes. Please watch the attached video to see how it keeps refreshing.
Is there a special setting for me to specify in the canvas whenever I initialize the model? I tried looking around multiple forums and couldn't find a fix for my problem.
Code:
import React from 'react'
import Navbar from '../components/Navbar';
import {useRef, useEffect} from 'react';
import {useGLTF, Stage, PresentationControls, OrbitControls, useScroll} from '@react-three/drei';
import {Canvas} from '@react-three/fiber';
import { useLoader, useFrame, useThree } from '@react-three/fiber'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { Suspense } from 'react'
import ModelViewer from '../components/ModelViewer';
import * as THREE from 'three';
function Model(props){
const {scene} = useGLTF("model.glb");
useThree(({camera}) => {
camera.position.set(-180, 20, -160);
});
// let model = useLoader(GLTFLoader, "model.glb");
scene.traverse(child => {
if (child.isMesh) {
child.castShadow = true
child.receiveShadow = true
}
});
return <primitive object={scene} {...props} />;
}
export default function Home(props) {
const groupRef = useRef();
const [scrollY, setScrollY] = React.useState(0);
useEffect(() => {
const handleScroll = () => {
setScrollY(window.scrollY);
};
handleScroll();
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
});
useEffect(() => {
// as the user scrolls, the "fridge" div will move to center of screen
let fridge = document.getElementById('fridge');
window.addEventListener('scroll', () => {
// make it smooth
// fridge.style.transform = "translateX(" + -midScreenX + "px)";
// for every scrollY, move the fridge to the left by 1px
for(let i = 0; i < scrollY; i++){
fridge.style.transform = "translateX(" + -i + "px)";
}
});
});
return (
<section className="">
<Navbar />
<div className="flex items-center justify-center">
<div className="flex flex-col md:flex-row w-9/12 justify-center items-center h-screen">
<div className="flex items-center bg-gray-300 w-full">
<div className="flex flex-col">
<h1 className="font-CreteRoundRegular text-5xl text-center md:text-left">KitchIN</h1>
<p className="font-CreteRoundRegular text-xl text-center md:text-left">A smart fridge that helps you keep track of your food.</p>
</div>
</div>
<div className="md:w-1/2 w-full h-5/6 bg-red-200" id="fridge">
<Canvas>
{/* <Suspense fallback={null}>
<Stage>
<Model />
<OrbitControls enableZoom={false} />
</Stage>
</Suspense> */}
<Suspense fallback={null}>
<Stage>
<Model />
<OrbitControls enableZoom={false} />
</Stage>
</Suspense>
</Canvas>
</div>
</div>
</div>
<div className="flex h-screen">
<h1>Hello</h1>
</div>
</section>
)
}
useGLTF.preload("modern_fridge.glb");
You need to add empty parameter lists to the
useEffect
hook to prevent repeated re-rendersCheck this StackOverflow question for further reference on this