首先安装three.js环境
npm i 这些包自己装一下
然后再需要使用three.js的页面
import * as Three from "three";
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
// 引入gltf模型加载库GLTFLoader.js
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
//模型解压 这个东西不一定需要的哈 看你们的模型有没有压缩过
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
然后就是千篇一律的
容器,相机,场景,光源
this.container = document.getElementById("container");
//透视相机
this.camera = new Three.PerspectiveCamera(45, this.container.clientWidth / this.container.clientHeight, 0.1, 100);
this.camera.position.set(3, 2, 3);
this.scene = new Three.Scene();
this.scene.background = new Three.Color(0xa0a0a0);
this.scene.fog = new Three.Fog(0xa0a0a0, 2, 20);
/*光源 */
const hemiLight = new Three.HemisphereLight(0xffffff, 0x8d8d8d, 3);
hemiLight.position.set(0, 20, 0);
this.scene.add(hemiLight);
const dirLight = new Three.DirectionalLight(0xffffff, 3);
dirLight.position.set(5, 5, 0);
dirLight.castShadow = true;
dirLight.shadow.camera.top = 1;
dirLight.shadow.camera.bottom = - 1;
dirLight.shadow.camera.left = - 1;
dirLight.shadow.camera.right = 1;
dirLight.shadow.camera.near = 0.1;
dirLight.shadow.camera.far = 20;
this.scene.add(dirLight);
const mesh = new Three.Mesh(new Three.PlaneGeometry(50, 50), new Three.MeshPhongMaterial({ color: 0xcbcbcb, depthWrite: false }));
mesh.rotation.x = - Math.PI / 2;
mesh.receiveShadow = true;
this.scene.add(mesh);
//这里加了一个辅助的表格
const grid = new Three.GridHelper(50, 50, 0xc1c1c1, 0xc1c1c1);
this.scene.add(grid);
然后是模型加载
const loader = new GLTFLoader();
//下面四句模型没压缩的可以不用
const dracoLoader = new DRACOLoader(); //
dracoLoader.setDecoderPath('/gltf/');//设置解压库文件路径
dracoLoader.preload() //初始化_initDecoder 解码器
loader.setDRACOLoader(dracoLoader) //gltfloader使用dracoLoader
loader.load('你的模型地址', (gltf) => {
const boomBox = gltf.scene;
boomBox.scale.set(0.2, 0.2, 0.2);
for (let i = 0; i < this.list.length; i++) {
let myname = `左${i + 1}`
this.addMorph(boomBox, this.list[i].s, this.list[i].x, this.list[i].y, this.list[i].z, myname)
}
})
addMorph(mesh, speed, x, y, z, name) {
// console.log(mesh)
mesh = mesh.clone();
mesh.name = name
mesh.position.set(x, y, z);
mesh.speed = 0;
mesh.rotation.y = Math.PI / 2;
mesh.castShadow = true;
mesh.receiveShadow = true;
this.scene.add(mesh);
if (this.once === 0) {
document.addEventListener('dblclick', (e) => {
/* if (this.throttle) {
// 说明此时有定时器在执行,不允许代码继续执行了(因为继续向后执行的话,有会创建一个定时器)
return;
}*/
//绑定的点击事件
this.onclickmy(e, mesh)
/*this.throttle = setTimeout(() => {
this.throttle = null;
}, 1000);*/
})
}
},
最后渲染器和相机控制的东西
this.renderer = new Three.WebGLRenderer({ antialias: true });
// this.renderer.setClearColor(0X000000, 0)
this.renderer.setSize(this.container.clientWidth, this.container.clientHeight);
this.container.appendChild(this.renderer.domElement);
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
this.controls.target.set(0, 0.1, 0);
this.controls.update();
this.controls.minDistance = 0.5;
this.controls.maxDistance = 10;
this.controls.maxPolarAngle = 0.5 * Math.PI;
然后是调用
this.renderer.render(this.scene, this.camera);
this.controls.addEventListener('change', () => {
this.renderer.render(this.scene, this.camera); //执行渲染操作
});//监听鼠标、键盘事件
关于性能优化的地方啊 其实这里面已经做了一个 就是那种重复的模型 不要用几次加载几次啊 加载一次就行了 然后改一下模型的位置啥的 还有就是就是那种大模型如果有重复的很多块的话可以拆开一下 (此做法前端定位会麻烦一些)