Files
platform/src/apps/landing/DuckAvatar.tsx
T

65 lines
2.2 KiB
TypeScript

import { Canvas, useThree } from '@react-three/fiber';
import { OrbitControls, useGLTF, useAnimations } from '@react-three/drei';
import { useEffect, useState, useRef } from 'react';
function DuckModel({ onLoaded }: { onLoaded: () => void }) {
const character = useGLTF('/duck3D/Character_output.glb');
const animations = useGLTF('/duck3D/Meshy_Merged_Animations.glb');
const meshRef = useRef<any>(null);
const { actions } = useAnimations(animations.animations, meshRef);
useEffect(() => {
onLoaded();
}, [character, animations, onLoaded]);
useEffect(() => {
if (!actions) return;
const action = actions['Walking'];
if (!action) return;
action.reset();
action.setLoop(2201, Infinity);
action.clampWhenFinished = false;
action.fadeIn(0.4);
action.play();
}, [actions]);
return <primitive ref={meshRef} object={character.scene} position={[0, -0.2, 0]} scale={4.5} rotation={[-0.1, (10 * Math.PI) / 180, 0]} />;
}
function Camera() {
const { camera } = useThree();
const controlsRef = useRef<any>(null);
useEffect(() => {
if (controlsRef.current) {
controlsRef.current.target.set(0.3, 3.29, -0.4);
camera.position.set(2.89, 5.24, 7.38);
controlsRef.current.update();
}
}, [camera]);
return <OrbitControls ref={controlsRef} enabled={false} target={[0.3, 3.29, -0.4]} />;
}
export function DuckAvatar() {
const [isLoaded, setIsLoaded] = useState(false);
return (
<div
className="fixed top-12 md:top-auto md:bottom-0 left-1/2 -translate-x-1/2 w-[60vh] h-[75vh] overflow-visible z-1 pointer-events-none"
style={{ background: 'transparent', opacity: isLoaded ? 1 : 0 }}
>
<div className="w-full h-full pointer-events-none overflow-visible" style={{ background: 'transparent' }}>
<Canvas camera={{ position: [2.89, 5.24, 7.38], fov: 65, near: 0.1, far: 1000 }} style={{ background: 'transparent' }}>
<ambientLight intensity={1.5} />
<directionalLight position={[10, 10, 5]} intensity={2} />
<directionalLight position={[-10, -10, -5]} intensity={1} />
<pointLight position={[0, 5, 0]} intensity={1.5} />
<Camera />
<DuckModel onLoaded={() => setIsLoaded(true)} />
</Canvas>
</div>
</div>
);
}