Three.js官方案例原始碼解析----TrackballControls控制器進行3D圖片檢視

馬大頭發表於2017-09-29


官方案例地址及原始碼



官方及網上對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;
				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="http://threejs.org" 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.rotateSpeed = 1.0;	 //按住滑鼠左鍵後拖動檢視時的旋轉速度
				controls.zoomSpeed = 1.2; 	//用滾輪調整大小(遠近)時候的速度
				controls.panSpeed = 0.8; 	//按住滑鼠右鍵後的平移速度
				controls.noZoom = false;	//如果設定為true, 則禁用 滑鼠滾輪調整大小(遠近)的功能
				controls.noPan = false;		//如設定為true, 則禁用 按下滑鼠右鍵平移的功能
				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 = document.getElementById( '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() {
				renderer.render( scene, camera );
				stats.update();
			}
		</script>

	</body>
</html>





相關文章