moyebaobei 2019-07-01
Three.js官方文档比较精简,重点介绍api,没有一个合适的零基础的教程,但官网的demo十分丰富,遂产生从demo来逐渐学习Three.js的想法。
以下是目前收集到的较好的学习资源:
好,下面回归正题,这是今天要分析的: demo,官网的例子,可以直接跳到github上查看源码,我建议直接把three.js整个项目下载下来,可以直接查看demo的效果,直接打开html文件可能效果有不一样,可以看官网的说法, 也就是需要启动一个本地的服务器,如果你用的webstorm的话,直接右键html文件,就会有个 run 文件的选项,点击就可以启动一个本地服务器来启动本地的文件。
下面是demo的代码:
var camera, scene, renderer; var mesh; init(); animate(); function init() { // 初始化透视相机,参数(fov : Number, aspect : Number, near : Number, far : Number) // fov — 摄像机视锥体垂直视野角度 // aspect — 摄像机视锥体长宽比 // near — 摄像机视锥体近端面 // far — 摄像机视锥体远端面 camera = new THREE.PerspectiveCamera( 70, ( window.innerWidth - 600 ) / window.innerHeight, 1, 1000 ); // position是camera继承自Object3D的属性,表示相机对象在三维空间中的位置 camera.position.z = 400; // 初始化场景 scene = new THREE.Scene(); // 加载纹理,TextureLoader是一个加载器,load方法加载文件,返回一个新的纹理对象 var texture = new THREE.TextureLoader().load( 'textures/crate.gif' ); // BoxBufferGeometry(width : Float, height : Float, depth : Float, widthSegments : Integer, heightSegments : Integer, depthSegments : Integer) var geometry = new THREE.BoxBufferGeometry( 200, 200, 200 ); // 材质,map属性表示贴图,这里将之前的texture纹理对象添加进来 var material = new THREE.MeshBasicMaterial( { map: texture } ); // Mesh方法表示以三角形组成基本网格来形成物体 mesh = new THREE.Mesh( geometry, material ); // 将物体添加到场景中 scene.add( mesh ); // 初始化渲染器,antialias表示抗锯齿, canvas属性将three.js加载到已有的canvas元素上。 renderer = new THREE.WebGLRenderer( { antialias: true, canvas: document.getElementById('my-canvas') } ); // 设置设备像素比。通常用于避免HiDPI设备上绘图模糊 renderer.setPixelRatio( window.devicePixelRatio ); // .setSiZe( width : Integer, height : Integer, updateStyle : Boolean ) // 设置输出canvas的大小,将updateStyle设置为false以阻止对canvas的样式做改变 renderer.setSize( window.innerWidth - 600, window.innerHeight ); // domElement为自动创建或已有的canvas元素 document.body.appendChild( renderer.domElement ); // 监听浏览器尺寸的修改 window.addEventListener( 'resize', onWindowResize, false ); } // 浏览器尺寸改变时的回调,重新设置相机和渲染器参数 function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; // 在大多数属性发生改变之后,你将需要调用.updateProjectionMatrix来使得这些改变生效。 camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } // 动画 function animate() { // 每一帧调用一次 requestAnimationFrame( animate ); mesh.rotation.x += 0.005; mesh.rotation.y += 0.01; renderer.render( scene, camera ); }
对于初始化透视相机中fov — 摄像机视锥体垂直视野角度和视锥体的理解,可以看看入门指南中的透视相机一章,但视锥体的长宽比都说要和canvas的长宽比一样,我试了一下,如果不一样的话物体就会变形。有点难以理解,其实道理跟图片要在固定长宽的div填满且没有裁剪和空白的情形一样,如果图片跟div长宽比不同的话就会变形。这里的视锥体垂直视野角度在照相机距离物体角度固定的情况下,相当于固定了宽,再根据长宽比算出长,视锥体的面积就固定了,此时视锥体的就相当于一张图片,而canvas就相当于固定宽高的div,所以此时视锥体拉伸铺满。
widthSegments属性可以看入门指南中的基本形状了解。
设备像素比可以看链接
一般情况下new THREE.WebGLRenderer()
会自动创建一个canvas元素,如果想用自己定义的canvas元素的话,可以传入canvas属性,值为获取的元素。