赞
踩
vue 安装:
npm install --save three
在要使用的页面中引入three.js
import * as Three from 'three'
参考资料:
http://www.yanhuangxueyuan.com/Three.js/
1.1的第一个3d场景
<div id="container"></div>
</div>
data() { return { camera: null, //相机对象 scene: null, //场景对象 renderer: null, //渲染器对象 mesh: null, //网格模型对象Mesh }; }, methods:{ init() { this.scene = new THREE.Scene(); /** * 创建网格模型 */ let geometry = new THREE.SphereGeometry(60, 40, 40); //创建一个球体几何对象 // let geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry let material = new THREE.MeshLambertMaterial({ color: 0x0000ff }); //材质对象Material 可以自定义颜色 this.mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh this.scene.add(this.mesh); //网格模型添加到场景中 /** * 光源设置 */ //点光源 let point = new THREE.PointLight(0xffffff); point.position.set(400, 200, 300); //点光源位置 this.scene.add(point); //点光源添加到场景中 //环境光 let ambient = new THREE.AmbientLight(0x444444); this.scene.add(ambient); // console.log(scene) // console.log(scene.children) /** * 相机设置 */ let container = document.getElementById('container'); let width = window.innerWidth; //窗口宽度 let height = window.innerHeight; //窗口高度 let k = width / height; //窗口宽高比 let s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大 //创建相机对象 this.camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000); this.camera.position.set(200, 300, 200); //设置相机位置 this.camera.lookAt(this.scene.position); //设置相机方向(指向的场景对象) // this.camera = new THREE.PerspectiveCamera(70, container.clientWidth/container.clientHeight, 0.01, 10); // this.camera.position.z = 1; /** * 创建渲染器对象 */ this.renderer = new THREE.WebGLRenderer(); this.renderer.setSize(width, height);//设置渲染区域尺寸 this.renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色 container.appendChild(this.renderer.domElement); //body元素中插入canvas对象 //执行渲染操作 指定场景、相机作为参数 this.renderer.render(this.scene, this.camera); }, }
固定高度大小
<style>
#container {
height: 400px;
}
</style>
效果图:
参考资料1.2
完成模型自动旋转:
init方法中改:
init() { this.scene = new THREE.Scene(); /** * 创建网格模型 */ // let geometry = new THREE.SphereGeometry(60, 40, 40); //创建一个球体几何对象 let geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry let material = new THREE.MeshLambertMaterial({ color: "#ffffff", }); //材质对象Material this.mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh this.scene.add(this.mesh); //网格模型添加到场景中 /** * 光源设置 */ //点光源 let point = new THREE.PointLight("red"); point.position.set(100, 100, 100); //点光源位置 xyz this.scene.add(point); //点光源添加到场景中 //环境光 let ambient = new THREE.AmbientLight("black"); this.scene.add(ambient); // console.log(scene) // console.log(scene.children) /** * 相机设置 */ let container = document.getElementById("container"); let width = window.innerWidth; //窗口宽度 let height = window.innerHeight; //窗口高度 let k = width / height; //窗口宽高比 let s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大 //创建相机对象 this.camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000); this.camera.position.set(200, 300, 200); //设置相机位置 this.camera.lookAt(this.scene.position); //设置相机方向(指向的场景对象) // this.camera = new THREE.PerspectiveCamera(70, container.clientWidth/container.clientHeight, 0.01, 10); // this.camera.position.z = 1; /** * 创建渲染器对象 */ this.renderer = new THREE.WebGLRenderer(); this.renderer.setSize(width, height); //设置渲染区域尺寸 this.renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色 container.appendChild(this.renderer.domElement); setInterval(()=>{ this.renderer.render(this.scene, this.camera); //执行渲染操作 this.mesh.rotateY(0.01); //每次绕y轴旋转0.01弧度 }, 20); },
第二种:
文章中使用了requestAnimationFrame方法
根据查找资料得知:
1、requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。
2、在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的的cpu,gpu和内存使用量。
init() { this.scene = new THREE.Scene(); /** * 创建网格模型 */ // let geometry = new THREE.SphereGeometry(60, 40, 40); //创建一个球体几何对象 let geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry let material = new THREE.MeshLambertMaterial({ color: "#ffffff", }); //材质对象Material this.mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh this.scene.add(this.mesh); //网格模型添加到场景中 /** * 光源设置 */ //点光源 let point = new THREE.PointLight("red"); point.position.set(100, 100, 100); //点光源位置 xyz this.scene.add(point); //点光源添加到场景中 //环境光 let ambient = new THREE.AmbientLight("black"); this.scene.add(ambient); // console.log(scene) // console.log(scene.children) /** * 相机设置 */ let container = document.getElementById("container"); let width = window.innerWidth; //窗口宽度 let height = window.innerHeight; //窗口高度 let k = width / height; //窗口宽高比 let s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大 //创建相机对象 this.camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000); this.camera.position.set(200, 300, 200); //设置相机位置 this.camera.lookAt(this.scene.position); //设置相机方向(指向的场景对象) // this.camera = new THREE.PerspectiveCamera(70, container.clientWidth/container.clientHeight, 0.01, 10); // this.camera.position.z = 1; /** * 创建渲染器对象 */ this.renderer = new THREE.WebGLRenderer(); this.renderer.setSize(width, height); //设置渲染区域尺寸 this.renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色 container.appendChild(this.renderer.domElement); let animloop=()=> { render(); window.requestAnimationFrame(animloop); } let render=()=> { this.renderer.render(this.scene, this.camera); //执行渲染操作 this.mesh.rotateY(0.01); //每次绕y轴旋转0.01弧度 } animloop(); // this.renderer.render(this.scene, this.camera); // requestAnimationFrame(()=>{ // this.renderer.render(this.scene, this.camera); //执行渲染操作 // this.mesh.rotateY(0.01); // }, 20); },
1.3
使用鼠标操作:
在页面中引入three.js的下方引入控制器
import * as Three from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
在data中添加控制对象
data() {
return {
camera: null, //相机对象
scene: null, //场景对象
renderer: null, //渲染器对象
mesh: null, //网格模型对象Mesh
controls: null, //控件对象
};
},
修改init()方法:
init() { this.scene = new THREE.Scene(); /** * 创建网格模型 */ // let geometry = new THREE.SphereGeometry(60, 40, 40); //创建一个球体几何对象 可以根据需要替换 let geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry //长方体 参数:长,宽,高var geometry = new THREE.BoxGeometry(100, 100, 100); // 球体 参数:半径60 经纬度细分数40,40var geometry = new THREE.SphereGeometry(60, 40, 40); // 圆柱 参数:圆柱面顶部、底部直径50,50 高度100 圆周分段数 //var geometry = new THREE.CylinderGeometry( 50, 50, 100, 25 ); // 正八面体var geometry = new THREE.OctahedronGeometry(50); // 正十二面体var geometry = new THREE.DodecahedronGeometry(50); // 正二十面体var geometry = new THREE.IcosahedronGeometry(50); let material = new THREE.MeshLambertMaterial({ color: "#ffffff", }); //材质对象Material this.mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh this.scene.add(this.mesh); //网格模型添加到场景中 /** * 光源设置 */ //点光源 let point = new THREE.PointLight("red"); point.position.set(100, 100, 100); //点光源位置 xyz this.scene.add(point); //点光源添加到场景中 //环境光 let ambient = new THREE.AmbientLight("black"); this.scene.add(ambient); // console.log(scene) // console.log(scene.children) /** * 相机设置 */ let container = document.getElementById("container"); let width = window.innerWidth; //窗口宽度 let height = window.innerHeight; //窗口高度 let k = width / height; //窗口宽高比 let s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大 //创建相机对象 this.camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000); this.camera.position.set(200, 300, 200); //设置相机位置 this.camera.lookAt(this.scene.position); //设置相机方向(指向的场景对象) // this.camera = new THREE.PerspectiveCamera(70, container.clientWidth/container.clientHeight, 0.01, 10); // this.camera.position.z = 1; /** * 创建渲染器对象 */ this.renderer = new THREE.WebGLRenderer(); this.renderer.setSize(width, height); //设置渲染区域尺寸 this.renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色 container.appendChild(this.renderer.domElement); let animloop=()=> { render(); // window.requestAnimationFrame(animloop); this.controls = new OrbitControls(this.camera,this.renderer.domElement);//创建控件对象 this.controls.addEventListener('change', render);//监听鼠标、键盘事件 } let render=()=> { this.renderer.render(this.scene, this.camera); //执行渲染操作 // this.mesh.rotateY(0.01); //每次绕y轴旋转0.01弧度 } animloop(); // this.renderer.render(this.scene, this.camera); // requestAnimationFrame(()=>{ // this.renderer.render(this.scene, this.camera); //执行渲染操作 // this.mesh.rotateY(0.01); // }, 20); },
成功!可以任意拖动
缩放:滚动—鼠标中键
旋转:拖动—鼠标左键
平移:拖动—鼠标右键
还有一种使用使用方法 requestAnimationFrame
如果threejs代码中通过requestAnimationFrame()实现渲染器渲染方法render()的周期性调用,当通过OrbitControls操作改变相机状态的时候,没必要在通过controls.addEventListener(‘change’, render)监听鼠标事件调用渲染函数,因为requestAnimationFrame()就会不停的调用渲染函数。
init() { this.scene = new THREE.Scene(); /** * 创建网格模型 */ // let geometry = new THREE.SphereGeometry(60, 40, 40); //创建一个球体几何对象 let geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry let material = new THREE.MeshLambertMaterial({ color: "#ffffff", }); //材质对象Material this.mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh this.scene.add(this.mesh); //网格模型添加到场景中 /** * 光源设置 */ //点光源 let point = new THREE.PointLight("red"); point.position.set(100, 100, 100); //点光源位置 xyz this.scene.add(point); //点光源添加到场景中 //环境光 let ambient = new THREE.AmbientLight("black"); this.scene.add(ambient); // console.log(scene) // console.log(scene.children) /** * 相机设置 */ let container = document.getElementById("container"); let width = window.innerWidth; //窗口宽度 let height = window.innerHeight; //窗口高度 let k = width / height; //窗口宽高比 let s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大 //创建相机对象 this.camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000); this.camera.position.set(200, 300, 200); //设置相机位置 this.camera.lookAt(this.scene.position); //设置相机方向(指向的场景对象) // this.camera = new THREE.PerspectiveCamera(70, container.clientWidth/container.clientHeight, 0.01, 10); // this.camera.position.z = 1; /** * 创建渲染器对象 */ this.renderer = new THREE.WebGLRenderer(); this.renderer.setSize(width, height); //设置渲染区域尺寸 this.renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色 container.appendChild(this.renderer.domElement); // let animloop=()=> { // render(); // // window.requestAnimationFrame(animloop); // this.controls = new OrbitControls(this.camera,this.renderer.domElement);//创建控件对象 // this.controls.addEventListener('change', render);//监听鼠标、键盘事件 // } let render=()=> { this.renderer.render(this.scene, this.camera); //执行渲染操作 requestAnimationFrame(render);//请求再次执行渲染函数render // this.mesh.rotateY(0.01); //每次绕y轴旋转0.01弧度 } render(); this.controls = new OrbitControls(this.camera,this.renderer.domElement);//创建控件对象 // animloop(); // this.renderer.render(this.scene, this.camera); // requestAnimationFrame(()=>{ // this.renderer.render(this.scene, this.camera); //执行渲染操作 // this.mesh.rotateY(0.01); // }, 20); },
开发中不要同时使用requestAnimationFrame()或controls.addEventListener(‘change’, render)调用同一个函数,这样会冲突。
1.4 再加一个模型
加上代码,记得要平移,或者设置位置,不然会重叠:
let geometry2 = new THREE.SphereGeometry(60, 40, 40); //创建一个立方体几何对象Geometry
let mesh = new THREE.Mesh(geometry2, material); //网格模型对象Mesh
mesh.translateX(120); //球体网格模型沿X轴正方向平移120
//或者设置 mesh.position.set(120,0,0);//设置mesh3模型对象的xyz坐标为120,0,0
this.scene.add(mesh); //网格模型添加到场景中
加入辅助坐标轴:
let axisHelper = new THREE.AxesHelper(250);
this.scene.add(axisHelper);