VUE使用Three.js实现模型,点击交互,相机旋转视角跟随移动(Threejs中使用Tweenjs,含demo源码) | 您所在的位置:网站首页 › 元素相机 › VUE使用Three.js实现模型,点击交互,相机旋转视角跟随移动(Threejs中使用Tweenjs,含demo源码) |
目录 一、Three.js是什么? 二、VUE简单使用Three.js步骤 1.npm安装 2.template模板 3.引入库 4.定义全局变量 5.初始化场景 6.初始化相机 7.初始化灯光 8.初始化渲染器 9.创建模型(这里我搭建的模型是一个简单双面货架模型) 10.根据浏览器窗口自适应 11.初始化函数,页面加载完成时调用(mounted()中调用) 12.Style样式 三、VUE进阶使用Three.js步骤(完成各种事件和效果) 在简单使用Three.js的基础上,添加以下控件和代码 1.引入库及需要使用的组件 2.template模板 3.定义全局变量 4.使用OrbitControls控制给模型添加缩放,旋转,平移和拖拽等效果 5.点击模型后的模型样式效果 6.相机跟随点击事件移动动画效果 7.返回主视角按钮事件 8.添加鼠标点击模型事件,并调用相机移动方法(第6点)和点击后样式方法(第5点) 9.运行动画 10.初始化函数,页面加载完成时调用(mounted()中调用) 11.Style样式 四、源码地址 一、Three.js是什么?Three.js是一款基于原生WebGL封装通用Web 3D引擎,在小游戏、产品展示、物联网、数字孪生、智慧城市园区、机械、建筑、全景看房、GIS等各个领域基本上都有three.js的身影 二、VUE简单使用Three.js步骤 1.npm安装 npm install three npm install @tweenjs/tween.js 2.template模板 3.引入库 import * as THREE from "three"; 4.定义全局变量 data() { return { isDisabled: true, scene: null, camera: null, renderer: null, light: null, light2: null, //定义模型架子的长度 long: 100, //定义模型架子的宽度 tall: 24, //定义模型架子横纵板的宽度 thickness: 0.4, }; } 5.初始化场景 //初始化场景 initScene() { this.scene = new THREE.Scene(); }, 6.初始化相机 //初始化相机 initCamera() { const { long, tall } = this; this.camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 50000 ); this.camera.position.set(0, -(5 * tall) / 12, (6 * long) / 5); } 7.初始化灯光 //初始化灯光 initLight() { let ambientLight = new THREE.AmbientLight(0x404040); this.scene.add(ambientLight); //定义灯,并设置位置 this.light = new THREE.DirectionalLight(0x333333); this.light.position.set(60, 30, 40); this.light2 = new THREE.DirectionalLight(0xdddddd); this.light2.position.set(-20, 20, -20); this.scene.add(this.light); this.scene.add(this.light2); }, 8.初始化渲染器 //初始化渲染器 initRender() { //dom元素渲染器 this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); this.renderer.setSize(window.innerWidth, window.innerHeight); // 设置渲染区域尺寸 this.renderer.setClearColor(0x000000, 0); // 设置背景颜色 //window.devicePixelRatio 当前设备的物理分辨率与css分辨率之比 this.renderer.setPixelRatio(window.devicePixelRatio); //按层级先后渲染 this.renderer.sortObjects = true; document.getElementById("model").appendChild(this.renderer.domElement); }, 9.创建模型(这里我搭建的模型是一个简单双面货架模型) //创建载入模型 initModel() { const { long, tall, thickness } = this; //坐标系 // let axes = new THREE.AxesHelper(4000); // this.scene.add(axes); //所有横板 for (let index = 1; index { let x = pos.x; let y = pos.y; let z = pos.z; this.camera.position.set(x, y, z); }; tween.onUpdate(onUpdate); tween.start(); //设置相机target位置(看向坐标轴零点的位置) this.controls.target.set(0, 0, 0); //相机返回原点后,返回主视角禁用 this.isDisabled = true; //相机返回原点后,开启模型自动旋转 this.controls.autoRotate = true; } } 8.添加鼠标点击模型事件,并调用相机移动方法(第6点)和点击后样式方法(第5点) // 鼠标点击模型 onMouseClick(event) { //通过鼠标点击的位置计算出raycaster所需要的点的位置,以屏幕中心为原点,值的范围为-1到1 this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1; this.mouse.y = -(event.clientY / (window.innerHeight-50)) * 2 + 1; // 通过鼠标点的位置和当前相机的矩阵计算出raycaster this.raycaster.setFromCamera(this.mouse, this.camera); // 获取raycaster直线和所有模型相交的数组集合 let intersects = this.raycaster.intersectObjects(this.scene.children); if (!intersects[0]) { return; } else { //这样会获取所有模型,因为我们这里只需要小格子 //所以只需要获取我们之前设置name!=""属性的object即可 if (!intersects[0].object.name == "") { this.selectedObjects = []; this.selectedObjects.push(intersects[0].object); //调用高亮显示模型(呼吸灯)的方法给点击的格子添加点击后的样式 this.outlineObj(this.selectedObjects); //拿到格子的position坐标 this.positionObj = { x: intersects[0].object.position.x, y: intersects[0].object.position.y, z: intersects[0].object.position.z, }; //调用机移动动画,将相机移动至被点击的格子处 this.initTween( this.positionObj.x, this.positionObj.y, this.positionObj.z ); //点击格子后,开放返回主视角的点击权限 this.isDisabled = false; //点击格子后,禁止模型自动旋转 this.controls.autoRotate = false; } } } 9.运行动画 //运行动画 animate() { //运行相机旋转动画 TWEEN.update(); //渲染场景和相机 this.renderer.render(this.scene, this.camera); this.controls.update(); if (this.composer) { this.composer.render(); } //使用requestAnimationFrame周期性渲染 requestAnimationFrame(this.animate); } 10.初始化函数,页面加载完成时调用(mounted()中调用) //初始化函数,页面加载完成时调用 init() { this.initScene(); this.initCamera(); this.initLight(); this.initRender(); this.initModel(); this.renderer.render(this.scene, this.camera); this.initControls(); this.animate(); window.onresize = this.onWindowResize; window.onclick = this.onMouseClick; } 11.Style样式 .container { width: 100%; height: 100%; position: relative; } #btns { position: absolute; background-color: #031b34; bottom: 0; left: 50%; width: 80px; height: 30px; line-height: 30px; transform: translate(-50%, -50%); text-align: center; z-index: 9999; color: #00eeff; font-weight: bold; box-shadow: 0px 0px 2px 1px #00f6ff; border-radius: 6px; border: 1px solid #00f6ff; padding: 0; } /*模型样式*/ #model { width: 100%; height: 100%; position: relative; overflow: hidden; }呈现效果如下图,如下图。 建议认真看每一部分的代码,实在不清楚可以看源码,毕竟最近才做这方面的项目,写的不好的地方,还请各位嘴下留情。货架三维模型: 简单的货架三维模型实现点击交互,相机旋转等功能 |
CopyRight 2018-2019 实验室设备网 版权所有 |