javascript - OrbitControls 不适用于加载文件

标签 javascript html three.js 3d

所以我有这段代码,它基本上显示了用户使用三个 js OBJLoader、STLLoader 和 3MFLoader 输入的 3D 文件(obj、STL、3mf)。一切正常,但我尝试了一些(在这段代码中)添加 OrbitControls 到此,以便用户可以使用文件放大、缩小、旋转等,但它似乎不起作用。控制台完全没有错误,但旋转、放大和缩小等功能与渲染效果不佳。

<input type="file" name="file" id="file" onchange="loadFile(event)" />
<div id="filePreview" style="width: 100%; height: 30vh"></div>
<script>
  var loadFile = function (event) {
    let oInput = document.getElementById("file");
    var _validFileExtensions = [".obj", ".stl", ".3mf"];
    function ValidateSingleInput() {
      if (oInput.type == "file") {
        var sFileName = oInput.value;
        if (sFileName.length > 0) {
          var blnValid = false;
          for (var j = 0; j < _validFileExtensions.length; j++) {
            var sCurExtension = _validFileExtensions[j];
            if (
              sFileName
                .substr(
                  sFileName.length - sCurExtension.length,
                  sCurExtension.length
                )
                .toLowerCase() == sCurExtension.toLowerCase()
            ) {
              window.fileUrl = URL.createObjectURL(event.target.files[0]);
              var scene = new THREE.Scene();

              var camera = new THREE.PerspectiveCamera(
                75,
                window.innerWidth / window.innerHeight,
                0.1,
                1000
              );

              var renderer = new THREE.WebGLRenderer();

              const controls = new THREE.OrbitControls( camera, renderer.domElement, scene );

              camera.position.z = 200;
              controls.update();

              var scene = new THREE.Scene();

              var camera = new THREE.PerspectiveCamera(
                45,
                window.innerWidth / window.innerHeight,
                1,
                2000
              );
              camera.position.z = 250;
              camera.lookAt(scene.position);
              controls.update();

              var directionalLight = new THREE.DirectionalLight(0xffeedd);
              directionalLight.position.set(0, 0, 1).normalize();
              scene.add(directionalLight);

              var mesh = null;
              if (sCurExtension == ".obj") {
                var objLoader = new THREE.OBJLoader();
                objLoader.load(window.fileUrl, function (object) {
                  mesh = object;
                  mesh.position.y = -50;
                  scene.add(mesh);
                });
              } else if (sCurExtension == ".3mf") {
                var loader = new THREE.ThreeMFLoader();
                loader.load(window.fileUrl, function (object) {
                  mesh = object;
                  mesh.position.y = -50;
                  scene.add(mesh);
                });
              } else if (sCurExtension == ".stl") {
                var loader = new THREE.STLLoader();
                loader.load(window.fileUrl, function (geometry) {
                  var material = new THREE.MeshPhongMaterial({
                    specular: 0x111111,
                    shininess: 200,
                    shading: THREE.FlatShading,
                  });
                  mesh = new THREE.Mesh(geometry, material);
                  mesh.position.y = -50;
                  scene.add(mesh);
                });
              }

              renderer.setPixelRatio(window.devicePixelRatio);
              renderer.setSize(
                filePreview.offsetWidth,
                filePreview.offsetHeight
              );

              renderer.setClearColor(0x000000);
              document.body.appendChild(renderer.domElement);

              animate();

              function animate() {
                requestAnimationFrame(animate);

                controls.update();

                renderer.render(scene, camera);
              }

              filePreview.appendChild(renderer.domElement);
              blnValid = true;
              break;
            }
          }

          if (!blnValid) {
            alert(
              "Sorry, " +
                sFileName +
                " is invalid, allowed extensions are: " +
                _validFileExtensions.join(", ")
            );
            oInput.value = "";
            return false;
          }
        }
      }
      return true;
    }

    ValidateSingleInput();
  };
</script>

<script src="http://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://threejs.org/examples/js/loaders/3MFLoader.js"></script>
<script src="https://threejs.org/examples/js/loaders/OBJLoader.js"></script>
<script src="https://threejs.org/examples/js/loaders/STLLoader.js"></script>

谁能检查一下代码并告诉我为什么它不起作用以及如何修复它?

最佳答案

OrbitControls 不会直接导出为 Three.js 库的一部分;相反,它作为示例的一部分导出。

如果您使用的是捆绑程序(例如 WebPack),您可以像这样导入它:

// Typical Three.js import
import * as THREE from "three"

// Additional OrbitControls import
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls";

或者,如果您使用脚本导入,则可以使用以下命令:

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

canvas {
  display: block;
}
<script type="module">
  import * as THREE from "https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="66120e1403032656485754574857" rel="noreferrer noopener nofollow">[email protected]</a>/build/three.module.js";
  import { OrbitControls } from "https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="93e7fbe1f6f6d3a3bda2a1a2bda2" rel="noreferrer noopener nofollow">[email protected]</a>/examples/jsm/controls/OrbitControls.js";

  const renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
  );
  const controls = new OrbitControls(camera, renderer.domElement);

  const geometry = new THREE.BoxBufferGeometry(1, 1, 1);
  const material = new THREE.MeshNormalMaterial();
  const cube = new THREE.Mesh(geometry, material);
  scene.add(cube);

  camera.position.z = 5;

  (function animate() {
    requestAnimationFrame(animate);

    controls.update();
    renderer.render(scene, camera);
  })();
</script>

然后你可以像这样使用它:

const controls = new OrbitControls( camera, renderer.domElement, scene );

关于javascript - OrbitControls 不适用于加载文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70841333/

相关文章:

javascript - 替换 document.write()

html - Flex 方向行及其内容居中

javascript - ThreeJS CSG 相交挤压形状的问题

javascript - 如何在 Three.js 中渲染地球时渲染 'atmosphere'?

html - HTML 5 中的 websockets 会代替 ajax 进行部分页面刷新吗?

javascript - 无法让 three.js EffectComposer 工作

javascript - Javascript 滚动突出显示不起作用

javascript - 我怎么知道元素是最后一项?

Javascript 检查表单 onsubmit

html - CSS:用另一个 !important 覆盖 !important 不起作用?