threejs-run
v1.1.11
Published
threejs-run
Readme
简介
前端快速开发3D模型应用。
快速开始
npm i threejs-run -S快速应用
全局注入
import ThreejsRun from 'threejs-run';
app.use(ThreejsRun);局部注入
import { ThreeNormal, ThreeGltf, ThreeGltfOperate } from 'threejs-run';常规用法
// 需引入
import { ThreeNormal } from 'threejs-run';构造
参数 | 类型 | 必填项 | 默认值 | 参考值 | 说明 ---- | ----- | ------ | ------ | ------ | :------ T | Object | √ | | | THREE。import * as THREE from 'three'; that | Object | √ | | | 页面的this。 dom | Object | √ | | | 模型元素。 scene_W | Number | √ | | | 模型元素宽。 scene_H | Number | √ | | | 模型元素高。 tools | Object | √ | | {OrbitControls, GLTFLoader} | 工具,外部注入需要使用的控件。
方法
参数 | 说明 ---- | :------ init({ initCamera, initLight, initControls, initWebGLRenderer, initMaterial, windowResize }) | 初始化模型。 cleanThree() | 清除THREE资源释放内存。 initClick(event, dom, materialClickChange) | 初始化射线,构建模型点击。
init方法
参数 | 类型 | 必填项 | 默认值 | 参考值 | 说明 ---- | ----- | ------ | ------ | ------ | :------ initCamera | Function | × | | | 初始化相机。可覆盖原生方法。 initLight | Function | × | | | 初始化灯光。 initControls | Function | × | | | 初始化控制器,用于控制器的操作。 initWebGLRenderer | Function | × | | | 初始化渲染器WebGLRenderer。 initMaterial | Function | × | | | 初始化素材,用于素材的操作。 windowResize | Function | × | | | 重写浏览器大小变化的控制函数。
cleanThree方法
beforeUnmount() {
// 清除THREE资源释放内存
this.threeD.cleanThree();
},注:该方法会印象系统原本打开的window.onresize监听。调用该方法后window.onresize会失效,需重新开启监听。
initClick方法
参数 | 类型 | 必填项 | 默认值 | 参考值 | 说明 ---- | ----- | ------ | ------ | ------ | :------ event | Object | √ | | | event; dom | Object | √ | | | 模型元素。 materialClickChange | Function | √ | | | 处理点击的素材的回调方法;
示例
<template>
<div id="app">
<div class="three" ref="webglBox" id="webgl" style="width: 100%; height: 100%;"></div>
</div>
</template>import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { ThreeNormal } from 'threejs-run';
export default {
data() {
return {
// 3D的实体
threeD: null,
scene_W: 0,
scene_H: 0,
};
},
mounted() {
this.init();
},
methods: {
init() {
this.$nextTick(() => {
// 获取3D加载元素的dom
const dom = document.getElementById('webgl');
// width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
this.scene_W = this.$refs.webglBox.offsetWidth; //宽度
this.scene_H = this.$refs.webglBox.offsetHeight; //高度
// new一个3D类
this.threeD = new ThreeNormal(THREE, this, dom, this.scene_W, this.scene_H, {
OrbitControls
});
// 初始化
this.threeD.init({
initMaterial: (scene) => {
// 创建坐标轴线段的几何体
const axesHelper = new THREE.AxesHelper(50); // 参数为长度
scene.add(axesHelper);
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
}
});
});
},
}
};
GLTF用法
该模块变更了引入,由原来的ThreeI, ThreeO,变更为ThreeGltf, ThreeGltfOperate。
构造
参数 | 类型 | 必填项 | 默认值 | 参考值 | 说明 ---- | ----- | ------ | ------ | ------ | :------ T | Object | √ | | | THREE。import * as THREE from 'three'; that | Object | √ | | | 页面的this。 dom | Object | √ | | | 模型元素。 url | Object | √ | | | 模型文件的基础地址,资源放置在静态目录,vue3的目录为public。 scene_W | Number | √ | | | 模型元素宽。 scene_H | Number | √ | | | 模型元素高。
url参数
参数 | 类型 | 必填项 | 默认值 | 参考值 | 说明 ---- | ----- | ------ | ------ | ------ | :------ baseUrl | String | √ | | | import.meta.env.BASE_URL。前端根目录。 gltfUrl | String | √ | | | 模型文件地址:'3d/mx.glb'。 dracoUrl | String | √ | | | 构造器文件地址:'draco/'。
方法
参数 | 说明 ---- | :------ init({ GLTFLoader, DRACOLoader, OrbitControls, initCamera, initMaterial }) | 初始化模型。 cleanThree() | 清除THREE资源释放内存。 initClick(event, dom, materialClickChange) | 初始化射线,构建模型点击。
init方法
参数 | 类型 | 必填项 | 默认值 | 参考值 | 说明 ---- | ----- | ------ | ------ | ------ | :------ GLTFLoader | Object | √ | | | GLTF加载器。import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; DRACOLoader | Object | √ | | | 解码器。import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader"; OrbitControls | Object | √ | | | 相机控件轨道控制器。import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; initCamera | Function | × | | | 初始化相机。可覆盖原生方法。; initMaterial | Function | × | | | 初始化素材,用于素材的操作。 windowResize | Function | × | | | 重写浏览器大小变化的控制函数。
cleanThree方法
beforeUnmount() {
// 清除THREE资源释放内存
this.threeD.cleanThree();
},注:该方法会印象系统原本打开的window.onresize监听。调用该方法后window.onresize会失效,需重新开启监听。
initClick方法
参数 | 类型 | 必填项 | 默认值 | 参考值 | 说明 ---- | ----- | ------ | ------ | ------ | :------ event | Object | √ | | | event; dom | Object | √ | | | 模型元素。 materialClickChange | Function | √ | | | 处理点击的素材的回调方法;
示例
<template>
<div id="app">
<div class="three" ref="webglBox" id="webgl" style="width: 100%; height: 100%;"></div>
</div>
</template>import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import { ThreeGltf } from 'threejs-run';
export default {
data() {
return {
// 3D的实体
threeD: null,
scene_W: 0,
scene_H: 0,
// 点击监听函数
threeDMousedown: null,
};
},
beforeUnmount() {
window.removeEventListener('mousedown', this.threeDMousedown);
},
activated() {
if (this.threeDMousedown !== null) {
window.addEventListener("mousedown", this.threeDMousedown, false);
}
},
deactivated() {
window.removeEventListener('mousedown', this.threeDMousedown);
},
mounted() {
this.init();
},
methods: {
// 初始化
init() {
this.$nextTick(() => {
// 获取3D加载元素的dom
const dom = document.getElementById('webgl');
// width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
this.scene_W = this.$refs.webglBox.offsetWidth; //宽度
this.scene_H = this.$refs.webglBox.offsetHeight; //高度
// new一个3D类
this.threeD = new ThreeGltf(THREE, this, dom, {
baseUrl: import.meta.env.BASE_URL,
gltfUrl: '3d/test.glb',
dracoUrl: 'draco/',
}, this.scene_W, this.scene_H);
// 初始化
this.threeD.init({GLTFLoader, DRACOLoader, OrbitControls,
initCamera: () => {
// console.log(this.scene_W, this.scene_H);
// 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000:远裁截面
this.threeD.camera = new THREE.PerspectiveCamera(17, this.scene_W / this.scene_H, 1, 1000);
// 根据需要设置相机位置具体值
// this.camera.position.set(0, 0, 0);
this.threeD.camera.position.set(this.scene_W/8, this.scene_W/15, 0);
//相机观察目标指向Threejs 3D空间中某个位置
// this.camera.lookAt(0, 0, 0);//指向mesh对应的位置
this.threeD.camera.lookAt(new THREE.Vector3( 0, 0, 0 ));//指向mesh对应的位置
},
initMaterial: (gltf) => {
// 递归遍历所有模型节点批量修改材质
gltf.scene.traverse( ( child ) => {});
}
});
// 增加点击监听
this.threeDMousedown = event => this.threeD.initClick(event, dom,
// 处理点击的素材
(raycaster) => {
// 射线交叉计算拾取模型
const intersects = raycaster.intersectObjects(this.material.list);
if (intersects.length > 0) {
// 处理点击事件
// intersects[0] 包含了第一个交点
const child = intersects[0].object;
// 隐藏的素材不触发点击事件
if (!child.visible) {
return
}
// .....
}
}
)
window.addEventListener("mousedown", this.threeDMousedown, false);
});
},
}
};
