import {
Bounds,
Center,
OrbitControls,
useAnimations,
useGLTF,
} from "@react-three/drei";
import { Canvas } from "@react-three/fiber";
import {
Component,
Suspense,
useEffect,
useMemo,
useRef,
useState,
type ReactNode,
} from "react";
import * as THREE from "three";
import { SkyModel } from "@/components/three/world/SkyModel";
import {
GAME_SCENE_FALLBACK_SKY_MODEL_PATH,
GAME_SCENE_FALLBACK_SKY_MODEL_SCALE,
GAME_SCENE_SKY_MODEL_PATH,
GAME_SCENE_SKY_MODEL_SCALE,
} from "@/data/world/environmentConfig";
import { galleryModels, type GalleryModel } from "@/data/galleryModels";
interface GalleryModelProps {
model: GalleryModel;
}
interface GalleryViewerErrorBoundaryProps {
children: ReactNode;
resetKey: string;
}
interface GalleryViewerErrorBoundaryState {
hasError: boolean;
}
class GalleryViewerErrorBoundary extends Component<
GalleryViewerErrorBoundaryProps,
GalleryViewerErrorBoundaryState
> {
constructor(props: GalleryViewerErrorBoundaryProps) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(): GalleryViewerErrorBoundaryState {
return { hasError: true };
}
componentDidUpdate(previousProps: GalleryViewerErrorBoundaryProps): void {
if (previousProps.resetKey !== this.props.resetKey && this.state.hasError) {
this.setState({ hasError: false });
}
}
render(): ReactNode {
if (this.state.hasError) {
return (
Ce modèle ne peut pas être affiché pour le moment.
);
}
return this.props.children;
}
}
function GalleryModelPreview({ model }: GalleryModelProps): React.JSX.Element {
const groupRef = useRef(null);
const { animations, scene } = useGLTF(model.path);
const modelScene = useMemo(() => scene.clone(true), [scene]);
const { actions } = useAnimations(animations, groupRef);
useEffect(() => {
const animationActions = Object.values(actions).filter(
(action): action is THREE.AnimationAction => Boolean(action),
);
for (const action of animationActions) {
action.reset().play();
}
return () => {
for (const action of animationActions) {
action.stop();
}
};
}, [actions]);
return (
);
}
function GalleryScene({ model }: GalleryModelProps): React.JSX.Element {
return (
<>
>
);
}
export function GalleryPage(): React.JSX.Element {
const [activeModelIndex, setActiveModelIndex] = useState(0);
const activeModel = galleryModels[activeModelIndex] ?? galleryModels[0]!;
const modelCount = galleryModels.length;
const goToPreviousModel = (): void => {
setActiveModelIndex((currentIndex) =>
currentIndex === 0 ? modelCount - 1 : currentIndex - 1,
);
};
const goToNextModel = (): void => {
setActiveModelIndex((currentIndex) =>
currentIndex === modelCount - 1 ? 0 : currentIndex + 1,
);
};
return (
Galerie des modèles
Merci aux designers de La Fabrik
Une vitrine simple pour parcourir les modèles 3D du projet dans leur
propre canvas, avec la même skybox que l'expérience principale.
{activeModelIndex + 1} / {modelCount}
{activeModel.name}
{activeModel.path}
Utilise les flèches pour changer de modèle. Tu peux tourner autour du
modèle avec la souris ou le doigt.
);
}