83 lines
2.9 KiB
TypeScript
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>
|
|
);
|
|
}
|