threejs(一):初步认识与使用
应项目需求,学习threejs将近半个月,现在总结一下我从网上搜集的比较有份量的资料和在项目中踩到的大小坑,以下内容如果有误,感谢各位大神不吝赐教。
一、threejs学习的资料
- Threejs入门指南
- Threejs官网
- Threejs郭隆邦技术博客
- 暮志未晚的技术博客
- Threejs源码解释
- THREEJS开发指南及其章节中的案例
二、项目中大小坑总结
1.实现效果:
2.疑难点
- 如何实现加载obj和mtl文件
//导入obj外部模型function setObj() {//加载mtlfor (let i =0;i<objUrl.length;i++){//加载显示进度var onProgress = function ( xhr ) {if ( xhr.lengthComputable ) {var percentComplete = xhr.loaded/xhr.total * 100;console.log( Math.round( percentComplete, 2 ) + '% downloaded' );}};//加载出错的时候被调用var onError = function () { };new THREE.MTLLoader().setPath( 'source/').load( mtlUrl[i]+'.mtl', function ( materials ) {materials.preload();new THREE.OBJLoader().setMaterials( materials ).setPath( 'source/' ).load( objUrl[i]+'.obj', function ( object ) {//设置模型的位置object.position.x = 2+i*20;object.position.y = 2;object.position.z = 2;object.castShadow = true;object.receiveShadow = true;//将模型加入到场景中去 scene.add(object);// objects.push(object); }, onProgress, onError );} );}}
- 导入3d模型后怎么实现拖拽
拖拽的调用函数是THREE.DragControls,但是由于我们导入的是外部模型,就是说它的type是group,而dragControls认准的类型是拖拽类型是mesh,如果直接写dragcontrols的模板,你会发现根本无法实现拖拽。
//对模型实现拖拽function drag(objects) {//初始化拖拽控件var dragControls = new THREE.DragControls( objects, camera, renderer.domElement );dragControls.addEventListener('hoveron',function (event) {// 让变换控件对象和选中的对象绑定 transform.attach(event.object);});// 开始拖拽dragControls.addEventListener( 'dragstart', function () {controls.enabled = false;} );// 拖拽结束dragControls.addEventListener( 'dragend', function () {controls.enabled = true;} );}
这个时候你要查看一下threejs实现拖拽的原理,你要使用THREE.Raycaster,从相机上射出一条射线,捕获鼠标的二维坐标,将鼠标的二维坐标转换成世界坐标,通过鼠标点击的位置(二维坐标)和当前相机的矩阵计算出射线位置,接着获取与射线相交的对象数组,其中的元素按照距离排序,越近的越靠前,允许检验后代,最后才去调用dragControls。
注意:如果你想在移动端的网页也实现拖拽,在这里要注意判断当前网页是在移动端还是pc端,即此时获取的是鼠标的点击位置还是触屏的点击位置:
// 判断是在移动端还是在pc端var os = function (){var ua = navigator.userAgent,isWindowsPhone = /(?:Windows Phone)/.test(ua),isSymbian = /(?:SymbianOS)/.test(ua) || isWindowsPhone,isAndroid = /(?:Android)/.test(ua),isFireFox = /(?:Firefox)/.test(ua),isChrome = /(?:Chrome|CriOS)/.test(ua),isTablet = /(?:iPad|PlayBook)/.test(ua) || (isAndroid && !/(?:Mobile)/.test(ua)) || (isFireFox && /(?:Tablet)/.test(ua)),isPhone = /(?:iPhone)/.test(ua) && !isTablet,isPc = !isPhone && !isAndroid && !isSymbian;return {isTablet: isTablet,isPhone: isPhone,isAndroid: isAndroid,isPc: isPc};}();............ var mouse = new THREE.Vector2();if (os.isAndroid || os.isPhone) {//移动端点击位置var touch = event.touches[0];mouse.x = (touch.pageX / window.innerWidth) * 2 - 1;mouse.y = -(touch.pageY / window.innerHeight) * 2 + 1;} else if (os.isTablet) {//移动端点击位置var touch = event.touches[0];mouse.x = (touch.pageX / window.innerWidth) * 2 - 1;mouse.y = -(touch.pageY / window.innerHeight) * 2 + 1;} else if(os.isPc) {// 通过鼠标点击位置,计算出 raycaster 所需点的位置,以屏幕为中心点,范围 -1 到 1mouse.x = (event.clientX / window.innerWidth) * 2 - 1;mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;}
- 如何改变坐标的显示
需求要求用户来控制坐标显示是rotate还是translate,此时我们使用THREE中的gui来显示。即:
init() { //设置gui选项var gui_tag = new function () {this.translate = true;}var gui = new dat.GUI();gui.add(gui_tag,'translate'); ......}// 时刻渲染 function animate() {......if (gui_tag.translate === true){transform.setMode("translate");} else {transform.setMode("rotate");}}
- 如何控制相机的旋转和缩放
相机的旋转使用orbitControl来控制,但是值得注意的是当你加上相机的旋转的时候,拖拽模型的时候会发现相机也会一起移动,这个时候拖拽模型就会显得不那么顺心了,此时我们要加上:
transform.addEventListener( 'dragging-changed', function ( event ) {orbit.enabled = ! event.value;} );
完整的代码是:
function init() { // 添加相机的旋转orbit = new THREE.OrbitControls(camera,renderer.domElement);orbit.enableDamping = true;orbit.update();transform.addEventListener( 'dragging-changed', function ( event ) {orbit.enabled = ! event.value;} );orbit.addEventListener( 'change', render ); }...function animate() { ....orbit.update(); }
- threejs显示的网页如何嵌入到微信小程序上
微信小程序上有固定的标签格式,此时我们可以使用webview来跳转到指定的网页去浏览threejs模型。
3.遗留问题
对于坐标的类型显示方面在pc端网页显示可以正常转换,但转到移动端之后就会失灵。
4.注意容易犯的低级错误
- 文件中的index.html不可以直接双击打开,会报错如下:
解决方法:可以使用webstorm来打开,此时是http:localhost请求。
- 在导入的文件中会出现监听touchstart这些触摸,此时会报错如下:
此时在后面加上 {passive:false}即可。
例如:
scope.domElement.addEventListener( 'touchstart', onTouchStart, {passive: false} );
转载于:https://www.cnblogs.com/lanhuo666/p/11098592.html
threejs(一):初步认识与使用相关推荐
- Threejs系列--11游戏开发--沙漠赛车游戏【初步加载地面】
Threejs系列--11游戏开发--沙漠赛车游戏[初步加载地面] 序言 目录结构 代码一览 world/index.js代码 world/Floor.js代码 materials/Floor.js代 ...
- threejs完成一个初步的3D看房!
const renderer = new THREE.WebGL1Renderer()//渲染器 const scene = new THREE.Scene()//场景 renderer.setPix ...
- threejs在墙上挖洞_在墙上飞
threejs在墙上挖洞 当今的市场要求成功的公司必须能够及时响应客户的需求和优先事项. Web服务器行业竞争激烈. 在市场上有IBM,Sun Microsystems和Hewlett-Packard ...
- 使用ThreeJs从零开始构建3D智能仓库——第一章(一切的基础)
引用链接:https://blog.csdn.net/homula123/article/details/101197463 使用ThreeJs从零开始构建3D智能仓库--第一章 写在前面 如何实现 ...
- 使用ThreeJs从零开始构建3D智能仓库——第三章(选中物体与特效)
使用ThreeJs从零开始构建3D智能仓库--第三章 写在前面--目录结构 如何选中物体 选中物体的原理 选中物体的实现 添加选中后的发光特效 HTML更新如下 结束语 写在前面--目录结构 这一章我 ...
- 教你如何使用blender+threejs搭建一个3d展厅平台 | 大帅老猿threejs特训
效果图 页面预览链接(服务器配置比较低,加载视频会比较慢,请耐心等候):https://static-8f957b23-c692-40ef-8f26-0a8a8e5422f1.bspapp.com/i ...
- TensorRT 7.2.1开发初步
TensorRT 7.2.1开发初步 TensorRT 7.2.1开发人员指南演示了如何使用C ++和Python API来实现最常见的深度学习层.它显示了如何采用深度学习框架构建现有模型,并使用该模 ...
- SOC,System on-a-Chip技术初步
SOC,System on-a-Chip技术初步 S O C(拼作S-O-C)是一种集成电路,它包含了电子系统在单个芯片上所需的所有电路和组件.它可以与传统的计算机系统形成对比,后者由许多不同的组件组 ...
- 《OpenCV3编程入门》学习笔记3 HighGUI图形用户界面初步
第3章 HighGUI图形用户界面初步 3.1 图像的载入.显示和输出到文件 1.OpenCV命名空间2种访问方法 (1)代码开头加:usingnamespace cv; (2)每个类或函数前加:cv ...
最新文章
- 面试官问:请拿出一段体现你水平的代码,我该如何回答?
- Exchange2003中实现两个邮件系统收发邮件配置实例
- python默认参数 可变对象_当心Python函数可变默认参数(list,set,dict…)的陷阱
- 工程之道,深度学习推理性能业界最佳优化实践
- HDU1520 Anniversary party 树形动态规划
- int** 赋值_Python的赋值、浅拷贝、深拷贝之间的区别
- 51nod1229-序列求和V2【数学,拉格朗日插值】
- java swing panel问题_关于 Java swing Box 的使用问题
- PYTHON解析XML的多种方式效率对比实测
- 育碧2k微软服务器,育碧服务器出现大规模的BUG:影响到多个平台
- 杨建:网站加速--系统架构篇
- 深度学习中所需的线性代数知识
- mysql 5.6.15 winx64_mysql-5.6.15-winx64免安装 配置步骤
- 微信小程序游戏——飞机大战
- 使用R,ggplot2绘制NMDS图
- Python-nan,NaN,NAN
- FIR窗函数和IIR模拟、数字滤波器的MATLAB实现
- mPaas苹果客户端离线包引入http的js白屏问题解决办法
- MacOS VSCode 突然打开黑屏的解决办法
- 为什么说阿里的“相信小的伟大”击中奥运会痛点