javascript - How to Embed a Sketchfab 3D Model in a React JSX Hero Section with Proper Sizing? - Stack Overflow

I'm trying to embed a Sketchfab 3D model in my React JSX hero section, but every time I do, the mo

I'm trying to embed a Sketchfab 3D model in my React JSX hero section, but every time I do, the model appears extremely small—like a single pixel. However, the model remains tiny. How can I properly size and scale the 3D model inside my hero section so it fits well and is fully visible? im trying to use that exact model directed by the link. Other models appear fine but not this.

Any help is appreciated!

import React, { Suspense, useRef, useEffect, useState } from "react";
import { Canvas, useFrame, useLoader, useThree } from "@react-three/fiber";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { OrbitControls, Environment, Html, useGLTF } from "@react-three/drei";
import { Box3, Vector3 } from "three";
import * as THREE from 'three';

// Model component that loads and animates the 3D model
function Model() {
  const gltf = useLoader(GLTFLoader, "/traveler.glb");
  const modelRef = useRef();
  const mixer = useRef();
  const { camera } = useThree();

  useEffect(() => {
    if (!gltf || !modelRef.current) return;

    // Setup animation mixer
    if (gltf.animations.length) {
      mixer.current = new THREE.AnimationMixer(gltf.scene);
      gltf.animations.forEach((clip) => {
        mixer.current.clipAction(clip).play();
      });
    }

    // Auto-scale and center model
    const box = new THREE.Box3().setFromObject(modelRef.current);
    const center = box.getCenter(new THREE.Vector3());
    const size = box.getSize(new THREE.Vector3());

    const maxDim = Math.max(size.x, size.y, size.z);
    const fov = camera.fov * (Math.PI / 180);
    const distance = Math.abs(maxDim / Math.sin(fov / 2));

    camera.position.set(center.x, center.y, distance * 1.5);
    camera.lookAt(center);

    const scaleFactor = 2 / maxDim;
    modelRef.current.scale.setScalar(scaleFactor);
    modelRef.current.position.set(-center.x, -center.y, -center.z);
  }, [gltf]);

  useFrame((_, delta) => {
    if (mixer.current) mixer.current.update(delta);
  });

  return <primitive ref={modelRef} object={gltf.scene} />;
}

// Loader component for displaying during model loading
function Loader() {
  return (
    <Html center>
      <div style={{ color: "white", display: "flex", flexDirection: "column", alignItems: "center" }}>
        <div className="loader"></div>
        <p>Loading 3D model...</p>
      </div>
    </Html>
  );
}

// Main component
const HeroModel3D = () => {
  return (
    <div className="hero-model-3d">
      <Canvas
        camera={{ position: [0, 0, 10], fov: 50 }}
        style={{ background: "transparent" }}
      >
        <ambientLight intensity={0.8} />
        <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} intensity={1} castShadow />
        <Suspense fallback={<Loader />}>
          <Model />
          <Environment preset="city" />
          <OrbitControls 
            enableZoom={true}
            enablePan={true}
            rotateSpeed={0.5}
            autoRotate={false}
          />
        </Suspense>
      </Canvas>
    </div>
  );
};

export default HeroModel3D;

This is my inspo

I'm trying to embed a Sketchfab 3D model in my React JSX hero section, but every time I do, the model appears extremely small—like a single pixel. However, the model remains tiny. How can I properly size and scale the 3D model inside my hero section so it fits well and is fully visible? https://sketchfab/3d-models/traveler-f86f5f2a779d496c95c9aca8ba13246f#comments im trying to use that exact model directed by the link. Other models appear fine but not this.

Any help is appreciated!

import React, { Suspense, useRef, useEffect, useState } from "react";
import { Canvas, useFrame, useLoader, useThree } from "@react-three/fiber";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { OrbitControls, Environment, Html, useGLTF } from "@react-three/drei";
import { Box3, Vector3 } from "three";
import * as THREE from 'three';

// Model component that loads and animates the 3D model
function Model() {
  const gltf = useLoader(GLTFLoader, "/traveler.glb");
  const modelRef = useRef();
  const mixer = useRef();
  const { camera } = useThree();

  useEffect(() => {
    if (!gltf || !modelRef.current) return;

    // Setup animation mixer
    if (gltf.animations.length) {
      mixer.current = new THREE.AnimationMixer(gltf.scene);
      gltf.animations.forEach((clip) => {
        mixer.current.clipAction(clip).play();
      });
    }

    // Auto-scale and center model
    const box = new THREE.Box3().setFromObject(modelRef.current);
    const center = box.getCenter(new THREE.Vector3());
    const size = box.getSize(new THREE.Vector3());

    const maxDim = Math.max(size.x, size.y, size.z);
    const fov = camera.fov * (Math.PI / 180);
    const distance = Math.abs(maxDim / Math.sin(fov / 2));

    camera.position.set(center.x, center.y, distance * 1.5);
    camera.lookAt(center);

    const scaleFactor = 2 / maxDim;
    modelRef.current.scale.setScalar(scaleFactor);
    modelRef.current.position.set(-center.x, -center.y, -center.z);
  }, [gltf]);

  useFrame((_, delta) => {
    if (mixer.current) mixer.current.update(delta);
  });

  return <primitive ref={modelRef} object={gltf.scene} />;
}

// Loader component for displaying during model loading
function Loader() {
  return (
    <Html center>
      <div style={{ color: "white", display: "flex", flexDirection: "column", alignItems: "center" }}>
        <div className="loader"></div>
        <p>Loading 3D model...</p>
      </div>
    </Html>
  );
}

// Main component
const HeroModel3D = () => {
  return (
    <div className="hero-model-3d">
      <Canvas
        camera={{ position: [0, 0, 10], fov: 50 }}
        style={{ background: "transparent" }}
      >
        <ambientLight intensity={0.8} />
        <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} intensity={1} castShadow />
        <Suspense fallback={<Loader />}>
          <Model />
          <Environment preset="city" />
          <OrbitControls 
            enableZoom={true}
            enablePan={true}
            rotateSpeed={0.5}
            autoRotate={false}
          />
        </Suspense>
      </Canvas>
    </div>
  );
};

export default HeroModel3D;

This is my inspo

Share Improve this question asked Mar 10 at 17:42 Sithil SandinuSithil Sandinu 214 bronze badges 1
  • This question is similar to: 3D Model Appears Too Small in React Three Fiber (GLTFLoader). If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. – Łukasz Daniel Mastalerz Commented Mar 10 at 18:00
Add a comment  | 

1 Answer 1

Reset to default 0

Model element "metarig_45" was exported to GLB with scale and moved position. You can download blender file from sketch fab and try export it again. Or scale object in code.

const metarig_45 = model.getObjectByName("metarig_45");
metarig_45.scale.set(1, 1, 1);
metarig_45.position.set(0, 0, 0);

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744831405a4596106.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信