feat: remove unused texture files and add model metadata
- Deleted various texture files related to the Raspberry Pi camera model. - Introduced a new JSON file to store model metadata including IDs, names, and URLs. - Implemented authentication and session management using Supabase. - Created a header component for navigation and user session display. - Added protected routes to restrict access to certain pages. - Developed a private layout for authenticated users. - Enhanced the home page to dynamically load models from the new JSON file. - Updated the login page to handle user authentication. - Created a model uploader for users to upload 3D models. - Improved overall styling and layout for better user experience.
This commit is contained in:
@@ -14,10 +14,8 @@ import {
|
||||
} from "@/components/ui/popover";
|
||||
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import { useNavigate } from 'react-router';
|
||||
import { useNavigate, useParams } from 'react-router';
|
||||
|
||||
|
||||
// Model component
|
||||
function Model({ url, onAnimationsLoaded, isAR }: {
|
||||
url: string;
|
||||
onAnimationsLoaded: (animations: string[], actions: Record<string, any>) => void;
|
||||
@@ -32,42 +30,49 @@ function Model({ url, onAnimationsLoaded, isAR }: {
|
||||
}
|
||||
|
||||
if (isAR) {
|
||||
// 100 times smaller
|
||||
scene.scale.set(0.01, 0.01, 0.01);
|
||||
scene.position.set(0, 0, 0);
|
||||
}
|
||||
else {
|
||||
scene.position.set(10, 0, 10);
|
||||
} else {
|
||||
scene.scale.set(1, 1, 1);
|
||||
scene.position.set(0, 0, 0);
|
||||
}
|
||||
|
||||
}, [actions, animations, onAnimationsLoaded, isAR]);
|
||||
|
||||
return (
|
||||
<Bounds fit margin={.9}>
|
||||
{/* find the object in the perfect angle */}
|
||||
|
||||
<primitive object={scene} />
|
||||
</Bounds>
|
||||
);
|
||||
}
|
||||
|
||||
const store = createXRStore();
|
||||
export default function Previewer({ modelUrl }: { modelUrl: string }) {
|
||||
|
||||
export default function Previewer() {
|
||||
const { modelId } = useParams<{ modelId: string }>();
|
||||
const controlsRef = useRef<OrbitControlsImpl>(null);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [animations, setAnimations] = useState<string[]>([]);
|
||||
const [actions, setActions] = useState<Record<string, any>>({});
|
||||
const [currentAnimation, setCurrentAnimation] = useState<string | null>(null);
|
||||
const [isAR, setIsAR] = useState(false);
|
||||
|
||||
const [modelUrl, setModelUrl] = useState<string | null>(null);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
console.log("ID del modelo:", modelId);
|
||||
|
||||
useEffect(() => {
|
||||
fetch(`${import.meta.env.BASE_URL}models.json`)
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
const model = data.find((m: { id: string }) => m.id === modelId);
|
||||
if (model) setModelUrl(model.url);
|
||||
});
|
||||
}, [modelId]);
|
||||
|
||||
const playAnimation = (name: string) => {
|
||||
if (actions[name]) {
|
||||
Object.values(actions).forEach(action => action.stop()); // Stop other animations
|
||||
Object.values(actions).forEach(action => action.stop());
|
||||
actions[name].play();
|
||||
setCurrentAnimation(name);
|
||||
}
|
||||
@@ -79,6 +84,9 @@ export default function Previewer({ modelUrl }: { modelUrl: string }) {
|
||||
setCurrentAnimation(null);
|
||||
}
|
||||
};
|
||||
|
||||
if (!modelUrl) return <div className="p-10 text-center">Cargando modelo...</div>;
|
||||
|
||||
return (
|
||||
<div ref={containerRef} className="relative w-full grow bg-white/10 shadow-xl shadow-gray-300/25 rounded-lg p-6 backdrop-blur-lg h-100">
|
||||
<div className="z-10 absolute top-4 w-100 flex wrap gap-5">
|
||||
@@ -98,9 +106,9 @@ export default function Previewer({ modelUrl }: { modelUrl: string }) {
|
||||
className="w-full flex justify-between italic"
|
||||
onClick={() => {
|
||||
if (currentAnimation === anim) {
|
||||
pauseAnimation(); // Pause if it's already playing
|
||||
pauseAnimation();
|
||||
} else {
|
||||
playAnimation(anim); // Play if it's not currently playing
|
||||
playAnimation(anim);
|
||||
}
|
||||
}}
|
||||
>
|
||||
@@ -133,7 +141,6 @@ export default function Previewer({ modelUrl }: { modelUrl: string }) {
|
||||
>
|
||||
{isAR ? <Shrink className="w-5 h-5" /> : <Expand className="w-5 h-5" />}
|
||||
{isAR ? "Salir de AR" : "Ver en AR"}
|
||||
|
||||
</Button>
|
||||
</div>
|
||||
<div className="w-full h-full">
|
||||
@@ -144,19 +151,16 @@ export default function Previewer({ modelUrl }: { modelUrl: string }) {
|
||||
<OrbitControls ref={controlsRef} minPolarAngle={Math.PI / 4} maxPolarAngle={Math.PI / 1.5} />
|
||||
<Model
|
||||
url={modelUrl}
|
||||
|
||||
onAnimationsLoaded={(animNames, actionMap) => {
|
||||
setAnimations(animNames);
|
||||
setActions(actionMap);
|
||||
}}
|
||||
|
||||
isAR={isAR}
|
||||
/>
|
||||
</XR>
|
||||
</Canvas>
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user