【问题标题】:Using Threejs + OrbitContols in TypeScript在 TypeScript 中使用三个 Js + OrbitControls
【发布时间】:2013-10-26 23:57:07
【问题描述】:

我无法获得 this 在 TypeScript 中使用上述组合的示例。

我的 html <head> 中有 <script src="lib/three.min.js"></script><script src="lib/OrbitControls.js"></script><body> 中有打字稿文件:

/// <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 在我点击它的那一刻就崩溃了 :)。感谢您的帮助。

【问题讨论】:

    标签: javascript html three.js typescript


    【解决方案1】:

    感觉有点傻,因为解决方案(或至少解决方法)结果非常简单......

    只需声明OrbitControls 变量:

    declare var THREE.OrbitControls: any; // even "declare var THREE.OrbitControls;" will do the trick
    

    仍有一些编译错误,但它可以工作。

    【讨论】:

    • 我认为这不是一个好主意。您应该尽量避免使用 any 来绕过打字稿问题。这是一种会掉下来的创可贴。
    • @JuanSolano 我同意,我的“解决方案”绝对是暂时的
    【解决方案2】:

    答案在 Eclipse 打字稿中对我不起作用,因为它与之前的参考声明冲突。但以下工作:

    declare module THREE {export var OrbitControls}
    

    【讨论】:

      【解决方案3】:

      虽然之前的答案可能在某种程度上可行,但您应该使用现成的definition files from DefinitelyTyped。他们还定义了OrbitControl 的属性和方法。

      【讨论】:

      【解决方案4】:

      在添加了三轨道控制类型和三轨道控制 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 语句。

      【讨论】:

        【解决方案5】:

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

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

        我正在使用 webpack 捆绑,因此我不必在 HTML 模板中添加脚本标签。

        【讨论】:

          【解决方案6】:

          在这个问题上花了几个小时后,我最终创建了一个新包:three-orbitcontrols-ts

          import * as THREE from 'three';
          import { OrbitControls } from 'three-orbitcontrols-ts';
          
          const controls = new OrbitControls(camera, renderer.domElement);
          

          【讨论】:

          • 除了轨迹球控件,有没有人发现类似的东西?
          • 干得好,但现在我们有另一个不同步的包。例如,这个包已经缺少我正在使用的其他一些组件使用的saveState 例程。
          【解决方案7】:

          在 ts 之外:

          var THREEa = THREE;
          

          ts内部:

          var controls = new THREEa.OrbitControls(pCamera, pContainer);
          

          【讨论】:

            【解决方案8】:

            在导入 THREE 后直接从源文件导入 OrbitControls 对我来说效果很好(不使用 three-orbitcontrols-ts 包):

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

            仅使用 three@types/three

            【讨论】:

            • 看起来这篇文章应该被标记为正确答案。
            • 问题是在第一次导入之后THREE 是一个导入的对象,而不是three/examples/js/controls/OrbitControls 期望的窗口对象上的属性以便安装自己。
            • 不适用于我的打字稿。 SyntaxError: Unexpected token {
            【解决方案9】:

            我无法从这里得到任何东西,这篇文章实际上有效并且看起来一致或有足够的细节可以操作。希望这个答案可以为其他人提供一些见解。

            在我的对象中,我已经通过使用类型提取三个 ts 文件进行了三个工作。这是很合理的,把ts文件放在typings/globals/three中。

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

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

            此时,一旦我将 ts 文件“包含”到我的对象中,所有基本的三种类型都可用:

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

            此时没有定义OrbitControls,因为基本三包中没有包含它。但是,typings 数据库中有 ts 数据。所以我也安装了它:

            typings install --globals three-orbitcontrols --save
            

            它把 ts 文件放在这里:

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

            我尝试了很多方法来让它工作,但我错过了一些东西。通常错误是未定义 THREE.OrbitControls。如果我删除了三个,那么它会生成不工作的 JavaScript。

            我最终做的我认为一种解决方法是编辑 typings/globals/three/index.d.ts 并将 typings/globals/three/OrbitControls/index.d.ts 的内容剪切并粘贴到 THREE 命名空间中结束。

            在 OrbitControls/index.d.ts 的顶部,它调用 &lt;reference types="three" /&gt; 不起作用,因为在这种情况下它找不到“三”。一旦我解决了它,它编译但它生成了非工作代码。

            【讨论】:

              【解决方案10】:

              不幸的是,以上答案都没有为我解决问题。我通过创建具有以下内容的three.js 文件找到了无需安装第三方软件包的解决方案:

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

              然后import THREE from './three';

              【讨论】:

                【解决方案11】:

                我在实施建议的解决方案时也遇到了一些不幸,因为它们都没有让 typescript 编译器满意。无法在编译时覆盖 THREE.OrbitControls,因为它被设置为只读。我的解决方案如下:

                使用 npm 安装“三个”和“三个轨道控制”。 (这有点愚蠢但很有必要,因为'three'已经包含了examples/js/controls/OrbitControl.js文件中轨道控制的所有代码,但没有以打字稿理解的方式导出它。如果你不想要弄乱您的 3rd 方库,只需在“three”旁边安装“three-orbit-controls”,其中包含代码的副本,但以一种很好的方式导出它。

                现在像下面这样使用它:

                从'三'导入*作为三;
                从“三轨道控制”导入 * 作为 OrbitControlsFunction;
                常量 OrbitControls = OrbitControlsFunction(三); // OrbitControls 现在是你的构造函数
                常量控件:THREE.OrbitControls = new OrbitControls(camera, element); // 从这里开始编写代码。

                【讨论】:

                  【解决方案12】:

                  解决方案来自这个issue。 只需安装three-full@types/three 并将类型定义添加到tsconfig.json 中的“compilerOptions”。

                    "compilerOptions": {
                      /* ... */
                      "baseUrl": ".",        // needed to use path aliases!
                      "paths": {
                        "three-full": ["node_modules/@types/three"]
                    }
                  }
                  

                  然后导入三个就好了

                  import * as THREE from 'three-full';
                  

                  之后一切正常,包括智能感知。

                  没有@types/three,`它仍然可以工作,但你不会得到智能感知。

                  【讨论】:

                    【解决方案13】:

                    docs 中所述,请执行以下操作:

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

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

                    【讨论】:

                      【解决方案14】:

                      如果您仍然希望从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)
                      

                      【讨论】:

                        猜你喜欢
                        • 2016-09-06
                        • 2021-04-25
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2015-11-12
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多