在TypeScript中使用Threejs + OrbitControls

19

我无法在TypeScript中使用上述组合的这个示例

我在我的HTML <head> 中有 <script src="lib/three.min.js"></script><script src="lib/OrbitControls.js"></script>,以及在 <body> 中有 TypeScript 文件:

/// <reference path="lib\three.d.ts" />
...
this.controls = new THREE.OrbitControls(this.camera); //there's the error
this.controls.addEventListener('change', this.render);
...

this.controls.update();

在被周期性调用的render()函数中。据我所知,设置与示例相同,但在编译OrbitControls构造函数行时给我一个庞大的错误(缩写):

The property 'OrbitControls' does not exist on value of type '{REVISION:string;   
CullFace: {[x: number ...

我猜这个错误涉及到整个Threejs,因为当我点击它时,Visual Studio立刻崩溃了:)感谢你的帮助。

14个回答

26

文档所述,按照以下步骤:

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

重要的是使用文件夹jsm而不是js。请记住,还不是所有模块都可在jsm文件夹中使用。


19

经过几个小时的研究,我最终创建了一个新的包:three-orbitcontrols-ts

import * as THREE from 'three';
import { OrbitControls } from 'three-orbitcontrols-ts';

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

有人找到类似于这个但是针对轨迹球控制的吗? - Pablo K
1
干得好,但现在我们又有另一个包要脱节了。例如,这个包已经缺少了一些我正在使用的其他组件所使用的“saveState”例程。 - user9315861
1
这个答案已经过时了:从那时起,threejs提供了适当的js模块,请参见https://dev59.com/p2Ik5IYBdhLWcg3wPcGB#56338877 - rotoglup

8

在导入THREE之后,直接从源文件中导入OrbitControls对我非常有用(而不使用three-orbitcontrols-ts软件包):

import * as THREE from 'three';
import 'three/examples/js/controls/OrbitControls';

只使用three@types/three这两个包


看起来这篇帖子应该标记为正确答案。 - daniel.bavrin
2
问题在于第一次导入后,THREE是一个已导入的对象,而不是窗口对象上的属性,因为three/examples/js/controls/OrbitControls期望安装自己。 - user9315861
对我来说无法与TypeScript一起使用。SyntaxError:意外的令牌{。 - workwise

4

很遗憾以上的答案都没能解决我的问题。我找到了一种不需要安装第三方软件包的解决方法,即创建一个包含以下内容的three.js文件:

import * as THREE from 'three';
window.THREE = THREE;
require('three/examples/js/controls/OrbitControls');

export default THREE;

然后导入'./three'模块:


3

虽然之前的回答在某种程度上可能有效,但你应该选择来自DefinitelyTyped的现成定义文件。它们还定义了OrbitControl的属性和方法。


2
链接已损坏。 - smartmeta
抱歉,这是更新后的链接:https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/three/three-orbitcontrols.d.ts - TommyMason
这并没有回答如何引入OrbitControls本身的问题。 - user9315861

1
如果您仍然希望从THREE访问OrbitControls,则以下内容对我有效:
import * as __THREE from 'three';
import * as X from 'three/examples/jsm/controls/OrbitControls.js';

type THREE = typeof __THREE & typeof X

唯一真正的区别是现在如果您指定控件类型,它将呈现为类似于:

const controls: X.OrbitControls = new THREE.OrbitControls(camera, renderer.domElement)

1
感觉有点傻,因为解决方案(或至少是变通方法)非常简单...
只需声明OrbitControls变量即可:
declare var THREE.OrbitControls: any; // even "declare var THREE.OrbitControls;" will do the trick

仍然存在一些编译错误,但它可以工作。


我认为这不是一个好主意。你应该尽量避免使用 any 来绕过 TypeScript 的问题。它只是一个临时的解决方法,迟早会失效。 - Juan Solano
@JuanSolano 我同意,我的“解决方案”肯定是暂时的。 - asdf

1

我尝试了一些建议的解决方案,但无法使其正常工作。经过一些试验后,我最终得到了以下结果:

import * as THREE from 'three';
import OrbitControlsLibrary = require('three-orbit-controls');
var OrbitControls = OrbitControlsLibrary(THREE);
...
this.controls = new OrbitControls(this.camera);

我正在使用Webpack打包,因此无需在HTML模板中添加脚本标签。

0
在添加了three-orbitcontrols typings和three-orbit-controls npm包之后(为什么它们的名称不一样?),我仍然无法在Typescript中使其正常工作。如果对其他不想使用解决方法的人有帮助,这个解决方法对我有效:
import * as three from 'three';
three.OrbitControls = require('three-orbit-controls')(three);

let camera = new three.PerspectiveCamera(75, aspectRatio, 1, 1000);
let renderer = new three.WebGLRenderer();
let controls = new three.OrbitControls(camera, renderer.domElement);

截至今日,看起来OrbitControls npm包正在使用旧的导出风格,需要一个传递Three库的旧式require语句。


0

我之前在这里找不到任何有用的信息,但是这篇文章确实有效并且看起来很一致或者有足够的细节可以操作。希望我的回答能为其他人提供一些见解。

在我的对象中,我已经使用 typings 提取了 THREE ts 文件,并且已经有三个工作正常。这非常合理,并将 ts 文件放置在 typings/globals/three 中。

以下是假设您已经下载并安装了 node.js 的步骤。这也会安装 npm(Node 项目管理器),您可以从命令提示符运行它以执行下面的所有步骤。

npm install typings --global
typings install dt~three --global --save

在这一点上,一旦我将ts文件“包含”到我的对象中,所有基本的THREE类型都可用:

/// <reference path="typings/globals/three/index.d.ts" />

目前OrbitControls未定义,因为基本的three package不包括它。然而,在typings数据库中有ts数据。所以我也安装了它:

typings install --globals three-orbitcontrols --save

它把ts文件放在这里:

node_modules\three-orbitcontrols-ts\dist\index.d.ts

我尝试了许多方法来使它工作,但似乎还缺少一些东西。通常出现的错误是THREE.OrbitControls未定义。如果我删除了“THREE”,那么它会生成不工作的JavaScript代码。

最终我做的事情被认为是一种解决方法,就是编辑typings/globals/three/index.d.ts,并将typings/globals/three/OrbitControls/index.d.ts的内容剪切并粘贴到末尾的THREE名称空间中。

在OrbitControls/index.d.ts的顶部,它调用了<reference types="three" />,但这样做无效,因为在该上下文中找不到“three”。一旦我解决了这个问题,它就编译了,但它生成的代码仍然不能正常工作。


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