如何将 Three.js 加载程序导入 Angular 6 项目
How to import a Three.js loader into an Angular 6 project
我想使用 Three.js (@types/three/index
) 扩展导入到 ng6 项目中的类型定义,并使用一组函数直接附加到同一个 "namespace"。类似于:THREE.myFunction()
。 我不想将 THREE 声明为 any
以抑制类型检查和 linter,我想可以包装一个扩展 THREE 的 vanilla JS 函数使用 TS class/function 然后利用 typings.d.ts
.
正在导入加载器
首先,我想将一个 THREE.js 加载程序导入到我的项目中,这通常定义了一个扩展 THREE
.
的普通函数
我正在尝试将 BinaryLoader
导入到 ng 服务中,但我不确定如何以正确的方式进行。
到目前为止我做了什么:
npm install three --save
npm install @types/three --save-dev
import * as THREE from 'three';
- 将 BinaryLoader 添加到新的 angular.json
scripts
数组
angular.json
"scripts": [
"./node_modules/three/examples/js/loaders/BinaryLoader.js"
]
到目前为止一切顺利,但现在我需要创建一个二进制加载程序:
import * as THREE from 'three';
// import { BinaryLoader } from 'three';
// import 'three/examples/js/loaders/BinaryLoader';
export class ThreeManagerService {
const loader = new THREE.BinaryLoader();
...
而且我必须设法以某种方式将 BinaryLoader
添加到 @types/three/index
。通过这种方式,我应该能够 扩展类型定义 以便能够创建新类型 THREE.BinaryLoader
。有可能做这样的事情吗?
我得到的警告是:
WARNING in ./src/app/shared/three-manager.service.ts
24:25-43 "export 'BinaryLoader' (imported as 'THREE') was not found in 'three'
静音类型警告和 TS 转译器
消除警告和错误的解决方法可能是这样的:
import * as THREEJS from 'three';
declare const THREE: any;
export class ThreeManagerService {
const loader = new THREE.BinaryLoader();
事实上,我认为这个解决方法非常丑陋 "fix"。我想尽可能多地使用类型系统。
编辑:获取示例以很好地使用 Intellisense 和 Typescript
在等待完全重写示例以与 ES6 模块和命名空间兼容时,可以定义一个公开和扩充全局的本地模块,在 /src/node_modules/three-extras/index.ts
:
import * as THREE from 'three';
declare global {
interface Window {
THREE: typeof THREE;
}
}
window.THREE = THREE;
require('three/examples/js/controls/OrbitControls');
require('three/examples/js/loaders/GLTFLoader');
来自:https://github.com/mrdoob/three.js/issues/9562#issuecomment-386522819
相关且有用的 SO 答案:
我终于找到了两个可行的解决方案(=> 准确地说是解决方法)。
使用 Webpack 的 imports-loader
[...] import-loader is a Webpack plugin allows you to inject a global variable into your module's scope. So the global (!
) namespace of your execution context still remains completely clean, but during "compilation", Webpack will be able to figure out where to lookup the binding for a module that only comes with a global variable.
import "imports?THREE=three!loaders/BinaryLoader";
使用这个导入我们告诉 Webpack 使用 THREE
作为 npm 模块定义的全局变量 'three'
并且 BinaryLoader 不会绑定到任何变量。
使用三全来提供三个命名空间
项目 three-full 扩展了标准 three.js 库定义的命名空间,添加了几个 "examples" 加载器和控件。使用它而不是经典的 three
npm 包,将有可能为最常见和最有用的 类 提供对 ES6 命名空间的全面支持,这些命名空间通常是绝大多数基于 three.js.
npm install --save three-full
然后就可以导入整个命名空间了:
import * as THREE from 'three-full';
...
const loader = new THREE.ColladaLoader();
如何使用一个小帮助程序库,我想做同样的事情 - 我找到了这个:https://www.npmjs.com/package/ng-three
两步,先安装包再安装类型。
- npm 安装三 --save
- npm install @types/three --save-dev
然后在您的组件中导入如下:
从 'three';
导入 * 作为三个
类型和包都设置好了。
我想使用 Three.js (@types/three/index
) 扩展导入到 ng6 项目中的类型定义,并使用一组函数直接附加到同一个 "namespace"。类似于:THREE.myFunction()
。 我不想将 THREE 声明为 any
以抑制类型检查和 linter,我想可以包装一个扩展 THREE 的 vanilla JS 函数使用 TS class/function 然后利用 typings.d.ts
.
正在导入加载器
首先,我想将一个 THREE.js 加载程序导入到我的项目中,这通常定义了一个扩展 THREE
.
我正在尝试将 BinaryLoader
导入到 ng 服务中,但我不确定如何以正确的方式进行。
到目前为止我做了什么:
npm install three --save
npm install @types/three --save-dev
import * as THREE from 'three';
- 将 BinaryLoader 添加到新的 angular.json
scripts
数组
angular.json
"scripts": [
"./node_modules/three/examples/js/loaders/BinaryLoader.js"
]
到目前为止一切顺利,但现在我需要创建一个二进制加载程序:
import * as THREE from 'three';
// import { BinaryLoader } from 'three';
// import 'three/examples/js/loaders/BinaryLoader';
export class ThreeManagerService {
const loader = new THREE.BinaryLoader();
...
而且我必须设法以某种方式将 BinaryLoader
添加到 @types/three/index
。通过这种方式,我应该能够 扩展类型定义 以便能够创建新类型 THREE.BinaryLoader
。有可能做这样的事情吗?
我得到的警告是:
WARNING in ./src/app/shared/three-manager.service.ts 24:25-43 "export 'BinaryLoader' (imported as 'THREE') was not found in 'three'
静音类型警告和 TS 转译器
消除警告和错误的解决方法可能是这样的:
import * as THREEJS from 'three';
declare const THREE: any;
export class ThreeManagerService {
const loader = new THREE.BinaryLoader();
事实上,我认为这个解决方法非常丑陋 "fix"。我想尽可能多地使用类型系统。
编辑:获取示例以很好地使用 Intellisense 和 Typescript
在等待完全重写示例以与 ES6 模块和命名空间兼容时,可以定义一个公开和扩充全局的本地模块,在 /src/node_modules/three-extras/index.ts
:
import * as THREE from 'three';
declare global {
interface Window {
THREE: typeof THREE;
}
}
window.THREE = THREE;
require('three/examples/js/controls/OrbitControls');
require('three/examples/js/loaders/GLTFLoader');
来自:https://github.com/mrdoob/three.js/issues/9562#issuecomment-386522819
相关且有用的 SO 答案:
我终于找到了两个可行的解决方案(=> 准确地说是解决方法)。
使用 Webpack 的 imports-loader
[...] import-loader is a Webpack plugin allows you to inject a global variable into your module's scope. So the global (
!
) namespace of your execution context still remains completely clean, but during "compilation", Webpack will be able to figure out where to lookup the binding for a module that only comes with a global variable.
import "imports?THREE=three!loaders/BinaryLoader";
使用这个导入我们告诉 Webpack 使用 THREE
作为 npm 模块定义的全局变量 'three'
并且 BinaryLoader 不会绑定到任何变量。
使用三全来提供三个命名空间
项目 three-full 扩展了标准 three.js 库定义的命名空间,添加了几个 "examples" 加载器和控件。使用它而不是经典的 three
npm 包,将有可能为最常见和最有用的 类 提供对 ES6 命名空间的全面支持,这些命名空间通常是绝大多数基于 three.js.
npm install --save three-full
然后就可以导入整个命名空间了:
import * as THREE from 'three-full';
...
const loader = new THREE.ColladaLoader();
如何使用一个小帮助程序库,我想做同样的事情 - 我找到了这个:https://www.npmjs.com/package/ng-three
两步,先安装包再安装类型。
- npm 安装三 --save
- npm install @types/three --save-dev
然后在您的组件中导入如下: 从 'three';
导入 * 作为三个类型和包都设置好了。