首页 > 其他分享 >react+three.js导入外部gltf格式

react+three.js导入外部gltf格式

时间:2024-05-30 13:28:54浏览次数:21  
标签:current const scene controls three react camera renderer js

我把gltf文件放在了public/static下面了。其他地方还没适用。因为之前想导入obj一直没成功,就跟着官网和各种例子成功导入了gltf格式的
gltf存放的位置
然后其他的没啥。看代码吧。大部分我都写了备注
components组件

import React, { useEffect, useRef } from "react";
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";

function ThreeContainer({ style }) {
  const defaultStyle = {
    height: "50vh",
    width: "50vw",
    backgroundColor: "transparent",
    margin: "0 auto",
  };
  const isContainerRunning = useRef(false);
  const containerRef = useRef(null);
  useEffect(() => {
    console.log(isContainerRunning, "====>", containerRef);
    if (!isContainerRunning.current && containerRef.current) {
      isContainerRunning.current = true;
      const containerWidth = containerRef.current.offsetWidth;
      const containerHeight = containerRef.current.offsetHeight;
      const loader = new GLTFLoader();

      //创建场景
      const scene = new THREE.Scene();

      //创建相机
      const camera = new THREE.PerspectiveCamera(
        75, // 视野角度,视野角值越大,场景中的物体越小
        containerWidth / containerHeight, //宽高比
        0.1, // 近裁剪面
        1000 // 远裁剪面
      );
      camera.position.set(-280, 290, -10);

      // 生成渲染器
      const renderer = new THREE.WebGLRenderer({
        antialias: true, // 抗锯齿
        alpha: true, //用于设置透明度
      });
      renderer.setSize(containerWidth * 0.9995, containerHeight * 0.9995);
      containerRef.current.appendChild(renderer.domElement);
      renderer.outputColorSpace = THREE.SRGBColorSpace; //设置为SRGB颜色空间
      // 设置背景颜色,透明("rgb()", 0)
      renderer.setClearColor(0x000000, 0);

      //添加光源
      const ambientLight = new THREE.AmbientLight("#FF9D6E", 20); // 环境光
      scene.add(ambientLight);
      const directionalLight = new THREE.DirectionalLight("#fff", 5); // 方向光颜色和强度
      directionalLight.position.set(1, 1, 1); // 光源位置
      scene.add(directionalLight);

      //创建控制器
      const controls = new OrbitControls(camera, renderer.domElement);
      controls.enableDamping = true; // 允许阻尼效果,使动画更平滑
      controls.dampingFactor = 0.05; // 阻尼系数
      controls.rotateSpeed = 0.1; // 旋转速度

      // 加载模型
      loadModel(loader, scene);
      // 渲染场景
      // animate(isContainerRunning, camera, renderer, scene);

      function animate(runningFlag, camera, renderer, scene) {
        // console.log(runningFlag, "ruim==>");
        if (!runningFlag.current) {
          controls.autoRotate = true; //是否自动旋转
          //旋转
          // const radius = 140;
          // const angle = Date.now() * 0.0005;
          // const x = Math.cos(angle) * radius;
          // const z = Math.sin(angle) * radius;
          // camera.position.set(x, 200, z);
          // camera.lookAt(0, 50, 0);
          // console.log('controls.target====', controls.target);
        }
        controls.target.set(0, 50, 0); //与lookAt参数保持一致
        requestAnimationFrame(() =>
          animate(runningFlag, camera, renderer, scene)
        );
        controls.update(); //更新控制器状态update()函数内会执行camera.lookAt(controls.target)
        renderer.render(scene, camera);
      }
      function loadModel(loader, scene) {
        loader.load(
          "static/test-glt.gltf",
          function (gltf) {
            isContainerRunning.current = false;
            gltf.scene.traverse(function (child) {
              console.log(child, "child=====>", camera);
              if (child.isMesh) {
                child.frustumCulled = false;
                //模型阴影
                child.castShadow = false;
                //模型自发光(模型自己的颜色)
                // child.material.emissive = child.material.color;
                // child.material.emissiveMap = child.material.map;
              }
            });

            scene.add(gltf.scene);
            animate(isContainerRunning, camera, renderer, scene);
            // 添加点击事件监听器
            // containerRef.current.addEventListener("mousedown", onm ouseDown, false)
            // 滚轮事件
            containerRef.current.addEventListener(
              "mousewheel",
              mousewheel,
              false
            );
            function mousewheel(e) {
              // var animationId = ''
              // cancelAnimationFrame(animationId);
              e.preventDefault();
              if (e.deltaY < 0) {
                // 当滚轮向上滚动时
                camera.position.z -= 1; // 向前移动相机
              } else {
                // 当滚轮向下滚动时
                camera.position.z += 1; // 向后移动相机
              }
              console.log(e.deltaY, "====>", camera, scene);
              renderer.render(scene, camera);
            }
            // 窗口大小改变事件
            window.addEventListener("resize", (e) => {
              const width = window.innerWidth;
              const height = window.innerHeight;
              camera.aspect = width / height;
              camera.updateProjectionMatrix();
              renderer.setSize(width, height);
            });
          },
          // called while loading is progressing
          function (xhr) {
            console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
          },
          // called when loading has errors
          function (error) {
            console.log("An error happened");
          }
        );
      }
    }
  }, []);

  return (
    <div>
      <div
        ref={containerRef}
        id="container"
        style={{ ...defaultStyle, ...style }}
      />
      {/* <div onClick={() => { isContainerRunning.current = true }}>
                开始旋转
            </div>
            <div onClick={() => { isContainerRunning.current = false }}>
                停止旋转
            </div> */}
    </div>
  );
}

export default ThreeContainer;

view/indexGltf/index.js

// import "./App.css";
import ThreeContainer from "../../components/ThreeContainer.jsx";

function IndexGltf() {
    return (
        <div>
            <ThreeContainer />
        </div>
    );
}

export default IndexGltf;


App.js文件

import './App.css';
import IndexGltf from './view/indexGltf/index.js';
function App() {
  return (
    <div className="App">
      <IndexGltf />
    </div>
  );
}

export default App;

然后就是文件夹的一个截图吧
所有文件截图

标签:current,const,scene,controls,three,react,camera,renderer,js
From: https://blog.csdn.net/weixin_47454566/article/details/139254025

相关文章

  • JS小知识点
    js是单线程的所有的同步任务都是按顺序依次执行的,前面的执行完了之后才会执行后面的任务../上级目录./当前文件夹目录说出==和===的区别普通相等:==在比较类型不相同的情况下,会将运算元先转成Number的值,再进行比较(即会进行隐式转换)严格不等:===在进行比......
  • js事件基础知识
    事件的基础知识事件三要素:事件源:  事件被触发的对象 谁被触发事件类型:如何触发,什么事件例如鼠标点击,鼠标经过,键盘按下等事件处理程序:通过函数赋值的方式完成常用的事件:1)、鼠标事件onclick   当点击鼠标时运行的事件onmousedown  当按下鼠标按钮时运行的事......
  • JS中?? 与 || 的区别
     1)相同点:??和||的用法相同,都是前后是值,中间用符号连接,根据前面的值来判断最终是返回前面的值还是后面的值。One??TwoOne||Two2)不同点:判断的方法不同:使用??时,只有One为null或者undefined时才会返回two;使用||时,One会先转化为布尔值判断,为true时返回One......
  • 在三维前端项目开发中THREE.PerspectiveCamera创建透视相机对象
    在Three.js中,可以使用THREE.PerspectiveCamera函数创建一个透视相机对象。大家好!艾斯视觉作为在IT行业中负责ui设计和前端开发环节的服务商很高兴能在这里与大家共同探讨学习:THREE.PerspectiveCamera的参数如下:fov:垂直视野角度,以角度为单位。通常,这个值在45到90之间。a......
  • 三维前端开发项目中Threejs的THREEScene函数详解
    THREE.Scene函数用于创建一个场景对象。大家好!艾斯视觉作为在IT行业中负责ui设计和前端开发环节的服务商很高兴能在这里与大家共同探讨学习:场景是Three.js中所有图形元素的容器,它可以包含相机、光源、几何体、材质等。创建场景对象的基本语法如下:constscene=newTHREE.S......
  • React
    react依赖react-native移动端跨平台16.13.1版本react:核心代码react-dom:渲染在不同平台需要的核心代码babel:jsx转换react代码工具//crossorigin在控制台显示远程的错误信息<scriptsrc="https://unpkg.com/react@16/umd/react.development.js"crossorigin></scrip......
  • JS-07 深入了解闭包
    目录1变量作用域2 作用域链3认识闭包4经典面试题5闭包的应用6闭包内存释放7闭包的优势1变量作用域变量作用域的概念:就是一个变量可以使用的范围JS中首先有一个最外层的作用域:称之为全局作用域JS中还可以通过函数创建出一个独立的作用域(局部),其中函数可以嵌......
  • 如何初始化 FIrebase 云函数,以便使用凭据和 JSON 验证 Firebase Admin SDK 服务账户?
    我觉得我已经阅读了所有可用的资料,但我仍然无法理解这一点。我非常喜欢Google的产品,但有时其文档的简洁性令人头疼。我阅读了这个令人难以置信的雄辩答案,这个答案的作者和我一样毫无头绪,但他觉得有必要写一本循序渐进的儿童指南。不幸的是,他的回答过于针对他的项目,而不是我的项......
  • C#解析json的几种方式
    json格式的数据是javascript原生的一种数据格式,比xml更简洁。它有两种形式:json对象和json对象数组。 在此之前,有必要解释几个基本概念:json字符串,就是string,它一定是由双引号包起来的,如"{'name':'jerry'}"。这是一个string,尽管去掉双引号后它就是一个json对象。json对象,就是以......
  • Springboot报class path resource [xxxxx.json] cannot be resolved to URL because i
    当Springboot解析resources文件下的json文件时,在本地环境好用,部署到服务器上找不到文件内容报错classpathresource[xxxxx.json]cannotberesolvedtoURLbecauseitdosenotexist问题排查(1)pom.xml文件配置<build><resources><resource><d......