Hello,
I am loading models via a config file. The problem is that when I click the arrow to go next, it re-renders the app and plays a loading gif that was intended to be just for the inital render of the app.
I’m thinking I need to preload these glb files. I saw the .preload() and think this would work, however, it is outside the scope of the component .: I cannot pass the prop(path) down to it.
Is the only option redux toolkit/ context?
import React, { useRef } from ‘react’;
import { useLoader, useThree, useFrame } from ‘@react-three/fiber’;
import { GLTFLoader } from ‘three/examples/jsm/loaders/GLTFLoader’;
import { useDrag } from “@use-gesture/react”;
import { animated, useSpring } from “@react-spring/three”;
import * as THREE from “three”;
const Model = ({ path, scale = 1 }) => {
const { size, viewport } = useThree();
const aspect = size.width / viewport.width;
let planeIntersectPoint = new THREE.Vector3();
const floorPlane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);
const ref = useRef();
const { scene } = useLoader(GLTFLoader, path);
const [spring, api] = useSpring(() => ({
from: { x: 0 },
to: { x: 2 },
scale: 1,
config: { mass: 10, tension: 1000, friction: 50, precision: 0.0001 }
}));
const bind = useDrag(
({ active, movement: [x, y], timeStamp, event }) => {
if (active) {
event.ray.intersectPlane(floorPlane, planeIntersectPoint);
}
// setIsDragging(active);
//activate this when you want to disable the camera drag and import setIsDragging as a prop in the main function
api.start({
scale: active ? 1.2 : 1,
rotation: [y / aspect * 0, x / aspect, 2],
bounds: { left: 1 / 2, right: 1 / 2, top: 0 / 2, bottom: 0 / 2 },
});
return timeStamp;
},
{ delay: false }
)
useFrame((state, delta) => {
ref.current.rotation.y += 0.01;
});
return (
<animated.mesh ref={ref} {...spring} {...bind()} castShadow receiveShadow rotation = [0, 0, 0] position={[0, 0, 0]}>
<primitive
object={scene}
scale={scale}
/>
</animated.mesh>
)
}
export default Model;
thanks!