Three.js官⽅案例源码解析----TrackballControls控制器进⾏3D
图⽚查看
官⽅及⽹上对TrackballControls的资料少之⼜少,分享以下对官⽅案例的理解,错误之处还请指出,共同学习
以下是对官⽅案例的源码分析:
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - trackball controls</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
color: #000;
font-family:Monospace;
font-size:13px;
text-align:center;
font-weight: bold;
background-color: #fff;
margin: 0px;
原生js和js的区别overflow: hidden;
}
#info {
color:#000;
position: absolute;
top: 0px; width: 100%;
padding: 5px;
}
a {
color: red;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="info">
<a href="" target="_blank" rel="noopener">three.js</a> - trackball controls example<br />
MOVE mouse & press LEFT/A: rotate, MIDDLE/S: zoom, RIGHT/D: pan
</div>
<script src="../js/three.js"></script>
<script src="../js/TrackballControls.js"></script>
<script src="../js/Detector.js"></script>
<script src="../js/stats.min.js"></script>
<script>
//许多官⽅案例都以此开头,其实就是检测当前浏览器是否⽀持或者开启了WebGL
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
//声明对象
var container; //容器,就是html中的div
var stats; //性能监视器(就是那个显⽰FPS和ms的⼩框框)
var camera; //相机
var controls; //本节重点(控制器)
var scene;  //场景
var renderer; //渲染器
var cross; //声明了,没⽤到,不知道是啥玩意
init(); //初始化⽅法(将要⽤到的东西都进⾏初始化)
animate(); //进⾏游戏循环,以及调⽤ controls.update()
function init() {
//透视投影相机THREE.PerspectiveCamera(近⼤远⼩,使⽤的较为普遍)
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );//还有⼀种是正投影相机THREE.OrthographicCamera,不论远    camera.position.z = 500; //相机位置,根据右⼿坐标系进⾏判断
//今天内容的主⾓,我并没有在官⽅⽂档⾥到相关的说明,根据案例⾥的使⽤进⾏摸索
controls = new THREE.TrackballControls( camera ); //看来是要给controls控制器传递⼀个当前使⽤的相机camera参数
controls.panSpeed = 0.8;  //按住⿏标右键后的平移速度
controls.minDistance = 200;  //设置滚轮能滚到的最近距离
controls.maxDistance = 1000;  //设置滚轮能滚到的最远距离
controls.staticMoving = true; //试了⼀下, 如果设置为false, 则移动速度贼鸡⼉快,嗖的⼀下就不见了, 具体是⼲啥玩意的没摸清
controls.dynamicDampingFactor = 0.3; //动态阻尼, 蛤? 我也不知道是啥,翻译过来就是
controls.keys = [ 65, 83, 68 ];  //注释掉貌似效果也没啥区别,反正我是没发现
/*
原⽣JS的⽅法,查看TrackballControls.js源码,对该⽅法进⾏了⼀定程度的重写,是绑定⼀些,⿏标点击,移动,滚轮,键盘等事件的
这个案例中如果不写这⾏代码,就⽆法⽤controls查看图⽚了,但是其他案例中并没有该⾏,但是功能
却依然能实现,不知为何
*/
controls.addEventListener( 'change', render );
// world
scene = new THREE.Scene(); //场景
scene.background = new THREE.Color( 0xcccccc ); //给场景设置背景⾊
/*
FogExp2( hex, density ) --指数雾
这个hex参数被传递给 Color 构造函数来设置颜⾊属性。hex是⼀个⼗六进制整数或CSS样式的字符串。
*/
scene.fog = new THREE.FogExp2( 0xcccccc, 0.002 );
/*
CylinderGeometry--创建圆柱⼏何体模型的类
CylinderGeometry(radiusTop, radiusBottom, height, radiusSegments, heightSegments, openEnded, thetaStart, thetaLength)
radiusTop — 圆柱体顶端半径. 默认值为20.
radiusBottom — 圆柱体底端半径. 默认值为20.
height — 圆柱体⾼度. 默认值为100.
radiusSegments — 围绕圆柱体周长的分割⾯数量. 默认值为8.
heightSegments — 沿圆柱体⾼度的分割⾯数量. 默认值为1.
openEnded — 指⽰圆柱体两端是打开还是覆盖的布尔值. 默认值为false, 意思是覆盖.
thetaStart — 第⼀个分割⾯的开始⾓度, 默认值 = 0 (3点钟⽅向).
thetaLength — 圆形扇形的圆⼼⾓通常称为θ。默认为2 * Pi,这形成了⼀个完整的圆柱体.
*/
var geometry = new THREE.CylinderGeometry( 0, 10, 30, 4, 1 );
//材质
var material = new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: true } );
for ( var i = 0; i < 500; i ++ ) {
var mesh = new THREE.Mesh( geometry, material );
mesh.position.x = ( Math.random() - 0.5 ) * 1000;
mesh.position.y = ( Math.random() - 0.5 ) * 1000;
mesh.position.z = ( Math.random() - 0.5 ) * 1000;
//更新对象的局部变换。
mesh.updateMatrix(); //注意,如果注释掉该⾏,那么下⼀⾏为false时效果不能正确显⽰,为true时效果不受影响
//当设置为true时会⾃动更新矩阵,包括计算位置矩阵(旋转或四元数),逐帧缩放,也会重新计算世界矩阵(matrixWorld)属性。缺省值 – true      mesh.matrixAutoUpdate = false;
//将mesh放到场景中
scene.add( mesh );
}
// 光照效果
// ⽅向光(类似太阳)
var light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 1, 1, 1 );
scene.add( light );
var light = new THREE.DirectionalLight( 0x002288 );
light.position.set( -1, -1, -1 );
scene.add( light );
// 环境光,⽆处不在
var light = new THREE.AmbientLight( 0x222222 );
scene.add( light );
// 渲染器
renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight ); //设置尺⼨
container = ElementById( 'container' ); //div块
container.appendChild( renderer.domElement ); //把渲染器的dom元素追加进div, 基本所有案例都是这个套路,照着写就完事了    stats = new Stats(); //性能监视器
container.appendChild( stats.dom );
//
window.addEventListener( 'resize', onWindowResize, false );
//
render();
}
//官⽅相关案例⾥都给出了这个⽅法,看样⼦像是适应窗⼝的功能,照葫芦画瓢
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
controls.handleResize();
render();
}
function animate() {
requestAnimationFrame( animate );
controls.update(); //注意,调⽤了该⽅法,才有效果
}
function render() {
stats.update();
}
</script>
</body>
</html>

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。