如何使用import语法加载three-orbitcontrols?

18

有人尝试过在ReactJS中使用OrbitControls函数吗? 这是我编写的示例代码:

import React, { Component } from 'react';
import 'tachyons';
import * as THREE from 'react';
import OrbitControls from 'three-orbitcontrols';
class App extends Component {
render() {
...
//Controls
const controls = new OrbitControls(camera, renderer.domElement)
controls.dampingFactor = 0.25
controls.enableZoom = false

它返回以下错误:

./node_modules/three-orbitcontrols/OrbitControls.js 1054:70-89 "export 'OrbitControls' (imported as 'THREE') was not found in 'three'

有谁知道如何解决这个问题吗?


我不认为你已经到达了3D对象运动部分。但我不确定问题具体是什么。这可能与你正在使用的模块有关。 - pailhead
2
这行代码看起来不正确:import * as THREE from 'react'; - Mugen87
除了OrbitControls之外,THREE模块的所有其他功能都正常工作。我正在尝试不同的方法。当我找到解决方案时,我会在这里发布,以便其他需要帮助的人可以参考。 - Neville Lusimba
5个回答

37

还有一种选项是直接从“three”软件包导入OrbitControls,如下所示:

import React, { Component } from "react";
import ReactDOM from "react-dom";
import * as THREE from 'three';
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls";

并且可以在应用程序中使用它而没有任何问题:

this.controls = new OrbitControls(camera, domElement);

在最新版本的Three.js中,必须将domElement作为第二个参数传递。可以使用React的ref来实现。

这是一个使用最新的React和Three.js的实时演示:https://codesandbox.io/s/github/supromikali/react-three-demo


1
如果您对答案不满意,请留下评论,以便我能改进。 - Alexander Solovyev
1
谢谢!正如@mikael-lepistö所评论的那样,这是官方的方法:https://threejs.org/docs/#manual/en/introduction/Import-via-modules - Mike Goodstadt
谢谢,这比添加另一个包要好得多。 - firebait
1
我必须执行 OrbitControls(camera, renderer.domElement); 没有任何想法为什么。 - sabithpocker
@sabithpocker 在最新版本的Three.js中,将domElement作为第二个参数传递是必须的(之前默认挂载点是页面的body),感谢您对此发表评论。 - Alexander Solovyev
1
正是我所需要的..谢谢! - SAUMITRA KUMAR

5
问题在于,当你导入THREE时,它不是全局范围的,而这是“three-orbitcontrols”模块所依赖的。您可以使用此模块代替 - “three-orbit-controls” (https://www.npmjs.com/package/three-orbit-controls) 并像下面这样导入:const OrbitControls = require('three-orbit-controls')(THREE); 现在您可以像现在一样使用轨道控件,但是在这里,THREE的实例被传递给了Orbit Controls模块。
编辑 - 2020
尽管上述答案在问题首次提出时很有用,但@Marquizzo正确指出这已不再是情况。
轨道控制器现在已经打包到three.js中,因此无需使用require(),而应该使用import语句。
现在请参考此答案 - https://dev59.com/e1QK5IYBdhLWcg3wKcxM#55929101

尽管这是被接受的答案,但它已经非常过时了。建议使用的库已经4年没有维护了,而且现在JavaScript允许模块导入,所以require()已经不再有用了。 - M -
是的,这个答案已经有两年了,就像技术领域中的大多数事物一样,它已经无法经受时间的考验。我相信你已经找到了更好和更新的解决方案,所以请随意与社区分享,而不是批评 :) - danlong
抱歉要批评一下,希望你不要个人化。只是这个问题经常被问到,我已经向几个人指出了这个问题。我希望新的访客知道,在您下面的答案中使用了推荐的import语句,没有理由使用require()three-orbit-controls,因为它已经与Three.js本身集成了。 - M -
并非所有人都能做到,我很高兴还有人在寻找并能指引他人去获取最新的信息。我现在回答这个问题会和两年前完全不同。我会编辑我的回答并引导人们去获取最新的信息。谢谢 :) - danlong

5
2020更新:

three.js现在默认将OrbitControls导出为一个模块,正如其他人所指出的,它可以按照以下方式使用:

import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

原始回答:

有一个你可以使用的npm包:Orbit Controls ES6

链接:https://www.npmjs.com/package/orbit-controls-es6

安装:

npm i orbit-controls-es6 --save

使用方法:

import OrbitControls from 'orbit-controls-es6';

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

3

当使用Parcel打包工具时,我是按照以下方式进行的:

app.js:

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

// the rest of the example from threejs web page 
// https://github.com/mrdoob/three.js/blob/master/examples/misc_controls_orbit.html

index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Parcel threejs example</title>
    <style>
      body {
        margin: 0;
      }
    </style>
  </head>
  <body>
    <script src="app.js"></script>
  </body>
</html>

package.json:

{
  "name": "test-threejs-with-parcel",
  "version": "0.1.0",
  "description": "Threejs with parcel test",
  "main": "app.js",
  "scripts": {
    "start": "parcel index.html",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "parcel-bundler": "^1.10.0"
  },
  "dependencies": {
    "three": "^0.109.0"
  }
}

你的script标签中需要有type="module" - Nijat Mursali
@NijatMursali 在三年前使用Parcel将所有内容捆绑在一起时不需要这样做(或者不确定Parcel的新版本是否需要这样做)。 - Mikael Lepistö

2
我必须同意Anurag的观点。最初我安装了danlong建议的three-orbit-controls,但在尝试启动WebClient时出现了require未定义的问题。之后我转而使用orbit-controls-es6,一切都正常工作了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接