Files
titan_react_node_sqllite/src/components/home/Models.tsx
T

83 lines
2.9 KiB
TypeScript

import { useRef, useMemo } from 'react';
import { useFrame } from '@react-three/fiber';
import { useScroll, useFBX } from '@react-three/drei';
import * as THREE from 'three';
export function Models() {
const scroll = useScroll();
// Load the actual FBX models from the public folder
const heroFBX = useFBX('/3dmodels/MANUAL/Cavins/GEE_TIN.fbx');
const featureFBX = useFBX('/3dmodels/MANUAL/MAA_Bottle/MAA_Bottle.fbx');
const ctaFBX = useFBX('/3dmodels/MANUAL/Fairever/Carton.fbx');
// Clone them so we don't mutate the cached originals
const heroModel = useMemo(() => heroFBX.clone(), [heroFBX]);
const featureModel = useMemo(() => featureFBX.clone(), [featureFBX]);
const ctaModel = useMemo(() => ctaFBX.clone(), [ctaFBX]);
const heroRef = useRef<THREE.Group>(null);
const featureRef = useRef<THREE.Group>(null);
const ctaRef = useRef<THREE.Group>(null);
useFrame((state, delta) => {
const offset = scroll.offset; // 0 to 1
if (heroRef.current) {
heroRef.current.rotation.y += delta * 0.3;
// Fade out and move left as we scroll down
heroRef.current.position.y = THREE.MathUtils.lerp(0, 10, offset * 3);
heroRef.current.position.x = THREE.MathUtils.lerp(3, -5, offset * 3);
// GEE_TIN increased by 50% (0.05 -> 0.075)
const scaleBase = 0.075;
heroRef.current.scale.setScalar(THREE.MathUtils.lerp(scaleBase, 0, offset * 3));
}
if (featureRef.current) {
featureRef.current.rotation.y += delta * 0.4;
const featureProgress = Math.max(0, Math.min(1, (offset - 0.2) * 2));
featureRef.current.position.y = THREE.MathUtils.lerp(-10, 0, featureProgress);
featureRef.current.position.x = THREE.MathUtils.lerp(-5, -2, featureProgress);
const scaleBase = 0.05;
if (offset > 0.6) {
const exitProgress = (offset - 0.6) * 3;
featureRef.current.position.y = THREE.MathUtils.lerp(0, 10, exitProgress);
featureRef.current.scale.setScalar(THREE.MathUtils.lerp(scaleBase, 0, exitProgress));
} else {
featureRef.current.scale.setScalar(scaleBase);
}
}
if (ctaRef.current) {
ctaRef.current.rotation.y -= delta * 0.3;
const ctaProgress = Math.max(0, Math.min(1, (offset - 0.6) * 3));
ctaRef.current.position.y = THREE.MathUtils.lerp(-10, -1, ctaProgress);
ctaRef.current.position.x = THREE.MathUtils.lerp(5, 2, ctaProgress);
// Carton decreased by 70% (0.05 -> 0.015)
const scaleBase = 0.015;
ctaRef.current.scale.setScalar(scaleBase);
}
});
return (
<group>
<group ref={heroRef} position={[3, 0, -2]}>
<primitive object={heroModel} />
</group>
<group ref={featureRef} position={[-5, -10, -3]}>
<primitive object={featureModel} />
</group>
<group ref={ctaRef} position={[5, -10, -2]}>
<primitive object={ctaModel} />
</group>
</group>
);
}