fix: pr issues

This commit is contained in:
math-pixel
2026-04-29 11:23:40 +02:00
parent 7c5d7f3834
commit 2b6b045f4a
7 changed files with 67 additions and 40 deletions
+12 -23
View File
@@ -1,15 +1,9 @@
import {
createContext,
useContext,
useRef,
useState,
useEffect,
useCallback,
} from "react";
/* eslint-disable react-hooks/immutability */
import { createContext, useRef, useState, useEffect, useCallback } from "react";
import { useGLTF, useAnimations } from "@react-three/drei";
import type { AnimationAction } from "three";
import * as THREE from "three";
import type { Vector3Tuple } from "@/types/3d";
import type { Vector3Tuple } from "@/types/three";
export interface AnimatedModelConfig {
modelPath: string;
@@ -25,7 +19,7 @@ export interface AnimatedModelConfig {
onAnimationEnd?: (animationName: string) => void;
}
interface AnimatedModelContextValue {
export interface AnimatedModelContextValue {
play: (name: string, fade?: number) => void;
stop: (fade?: number) => void;
fadeTo: (name: string, fade?: number) => void;
@@ -39,13 +33,7 @@ const AnimatedModelContext = createContext<AnimatedModelContextValue | null>(
null,
);
export function useAnimatedModel(): AnimatedModelContextValue {
const context = useContext(AnimatedModelContext);
if (!context) {
throw new Error("useAnimatedModel must be used within AnimatedModel");
}
return context;
}
export { AnimatedModelContext };
interface AnimatedModelProps extends AnimatedModelConfig {
children?: React.ReactNode;
@@ -53,7 +41,6 @@ interface AnimatedModelProps extends AnimatedModelConfig {
export function AnimatedModel({
modelPath,
animations: _animations = [],
defaultAnimation = "Idle",
position = [0, 0, 0],
rotation = [0, 0, 0],
@@ -144,7 +131,11 @@ export function AnimatedModel({
);
useEffect(() => {
if (autoPlay && names.length > 0) {
if (!autoPlay || names.length === 0) {
console.log("[AnimatedModel] No animation found in model");
return;
}
console.log(`[AnimatedModel] Available animations: ${names.join(", ")}`);
let defaultAction = actions[defaultAnimation as string];
@@ -158,15 +149,14 @@ export function AnimatedModel({
if (defaultAction) {
defaultAction.play();
// eslint-disable-next-line react-hooks/set-state-in-effect
setIsReady(true);
// eslint-disable-next-line react-hooks/set-state-in-effect
setCurrentAnim(defaultAction.getClip().name);
onLoaded?.();
} else {
console.log("[AnimatedModel] No available animation in actions");
}
} else if (names.length === 0) {
console.log("[AnimatedModel] No animation found in model");
}
}, [actions, defaultAnimation, names, autoPlay, onLoaded]);
const contextValue: AnimatedModelContextValue = {
@@ -179,7 +169,6 @@ export function AnimatedModel({
names,
};
// Apply transforms to scene directly
useEffect(() => {
scene.position.set(...position);
scene.rotation.set(
+6
View File
@@ -55,6 +55,12 @@ export const docGroups: DocGroup[] = [
subtitle: "Editing workflow",
meta: "06",
},
{
path: "/docs/animation",
title: "Animation & 3D Model System",
subtitle: "Components and usage",
meta: "07",
},
],
},
];
+1
View File
@@ -1,3 +1,4 @@
/* eslint-disable react-hooks/immutability */
import { useRef, useEffect, useState, useCallback } from "react";
import { useGLTF, useAnimations } from "@react-three/drei";
import type { AnimationAction, AnimationMixer } from "three";
+13
View File
@@ -0,0 +1,13 @@
import animation from "../../../../docs/technical/animation.md?raw";
import { DocsDocument } from "@/components/docs/DocsDocument";
export function DocsAnimationPage(): React.JSX.Element {
return (
<DocsDocument
content={animation}
frContent={animation}
meta="07"
title="Animation & 3D Model System"
/>
);
}
+2
View File
@@ -7,6 +7,7 @@ import {
import { HomePage } from "@/pages/page";
import { EditorPage } from "@/pages/editor/page";
import {
DocsAnimationRoute,
DocsArchitectureRoute,
DocsEditorRoute,
DocsFeaturesRoute,
@@ -45,6 +46,7 @@ const docsChildRoutes = [
{ path: "technical-editor", component: DocsTechnicalEditorRoute },
{ path: "features", component: DocsFeaturesRoute },
{ path: "editor", component: DocsEditorRoute },
{ path: "animation", component: DocsAnimationRoute },
].map(({ path, component }) =>
createRoute({
getParentRoute: () => docsRoute,
+14
View File
@@ -42,6 +42,12 @@ const LazyDocsEditorPage = lazy(() =>
})),
);
const LazyDocsAnimationPage = lazy(() =>
import("@/pages/docs/animation/page").then((module) => ({
default: module.DocsAnimationPage,
})),
);
export function DocsLayoutRoute(): React.JSX.Element {
return (
<Suspense fallback={null}>
@@ -97,3 +103,11 @@ export function DocsEditorRoute(): React.JSX.Element {
</Suspense>
);
}
export function DocsAnimationRoute(): React.JSX.Element {
return (
<Suspense fallback={null}>
<LazyDocsAnimationPage />
</Suspense>
);
}
+2
View File
@@ -26,10 +26,12 @@ class ModelErrorBoundary extends Component<
this.state = { hasError: false };
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
static getDerivedStateFromError(_error: Error): ErrorBoundaryState {
return { hasError: true };
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
componentDidCatch(_error: Error): void {
console.warn(`Failed to load model`);
}