three.js實(shí)現(xiàn)3D模型展示的示例代碼
由于項(xiàng)目需要展示3d模型,所以對(duì)three做了點(diǎn)研究,分享出來(lái) 希望能幫到大家
先看看效果:
three.js整體來(lái)說(shuō) 不是很難 只要你靜下心來(lái)研究研究 很快就會(huì)上手的
首先我們?cè)陧?yè)面上需要?jiǎng)?chuàng)建一個(gè)能夠放置3D模型的畫布 也可以說(shuō)是初始化 Three
var WIDTH,HEIGHT; var renderer; function initThree() { WIDTH = document.documentElement.clientWidth/2; <!--{foreach from=$recommended_goods item=rgoods}--> <!-- {/foreach} --> HEIGHT = document.documentElement.clientHeight/2; /* 渲染器 */ renderer = new THREE.WebGLRenderer(); renderer.setSize(WIDTH , HEIGHT); renderer.setClearColor(new THREE.Color(0x66666)); renderer.gammaInput = true; renderer.gammaOutput = true; document.body.appendChild(renderer.domElement); }
通過(guò)上面的代碼不難看出 我們?cè)O(shè)置了 在body里追加了一塊畫布 寬高是 client的一半顏色為 0x66666 這里要注意的是 renderer = new THREE.WebGLRenderer(); 因?yàn)槲覀兯械脑O(shè)置都是以renderer為對(duì)象設(shè)置
下來(lái) 我們需要調(diào)整攝像頭 即視覺角度
/* 攝像頭 */ var camera; function initCamera() { var VIEW_ANGLE = 45, ASPECT = WIDTH / HEIGHT, NEAR = 0.1, FAR = 10000; camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR); camera.position.set(20, 0, 0); //設(shè)置視野的中心坐標(biāo) camera.lookAt(scene.position); }
以上代碼主要是控制視覺角度 數(shù)值可以在后期根據(jù)自己的需求去調(diào)整
加載場(chǎng)景:
/* 場(chǎng)景 */ var scene; function initScene() { scene = new THREE.Scene(); }
加載燈光效果
/* 燈光 */ var light,light2,light3; function initLight() { //平行光 light = new THREE.DirectionalLight(0xFFFFFF); light.position.set(0, 99, 0).normalize(); scene.add(light); //環(huán)境光 light2 = new THREE.AmbientLight(0x999999); scene.add(light2); //點(diǎn)光源 light3 = new THREE.PointLight(0x00FF00); light3.position.set(300, 0, 0); scene.add(light3); }
顯示模型對(duì)象:
/* 顯示對(duì)象 */ var cube; function initObject(){ // ASCII file var loader = new THREE.STLLoader(); loader.addEventListener( 'load', function ( event ) { var loading = document.getElementById("Loading"); loading.parentNode.removeChild(loading); var geometry = event.content; //磚紅色 var material = new THREE.MeshPhongMaterial( { ambient: 0xff5533, color: 0xff5533, specular: 0x111111, shininess: 200 } ); //純黑色 // var material = new THREE.MeshBasicMaterial( { envMap: THREE.ImageUtils.loadTexture( 'http://localhost:8080/textures/metal.jpg', new THREE.SphericalReflectionMapping() ), overdraw: true } ) ; //粉色 帶陰影 // var material = new THREE.MeshLambertMaterial( { color:0xff5533, side: THREE.DoubleSide } ); //灰色 // var material = new THREE.MeshLambertMaterial({color: 000000}); //材質(zhì)設(shè)定 (顏色) var mesh = new THREE.Mesh( geometry, material ); var center = THREE.GeometryUtils.center(geometry); var boundbox=geometry.boundingBox; var vector3 = boundbox.size(null); var vector3 = boundbox.size(null); console.log(vector3); var scale = vector3.length(); camera.position.set(scale, 0, 0); camera.lookAt(scene.position); scene.add(camera); //利用一個(gè)軸對(duì)象以可視化的3軸以簡(jiǎn)單的方式。X軸是紅色的。Y軸是綠色的。Z軸是藍(lán)色的。這有助于理解在空間的所有三個(gè)軸的方向。 var axisHelper = new THREE.AxisHelper(800); scene.add(axisHelper); //周圍邊框 bboxHelper = new THREE.BoxHelper(); bboxHelper.visible = true; var meshMaterial = material; mainModel = new THREE.Mesh(geometry, meshMaterial); bboxHelper.update(mainModel); bboxHelper.geometry.computeBoundingBox(); scene.add(bboxHelper); //地板網(wǎng)格 // var gridHelper = new THREE.GridHelper(500, 40); // 500 is grid size, 20 is grid step // gridHelper.position = new THREE.Vector3(0, 0, 0); // gridHelper.rotation = new THREE.Euler(0, 0, 0); // scene.add(gridHelper); // var gridHelper2 = gridHelper.clone(); // gridHelper2.rotation = new THREE.Euler(Math.PI / 2, 0, 0); // scene.add(gridHelper2); // var gridHelper3 = gridHelper.clone(); // gridHelper3.rotation = new THREE.Euler(Math.PI / 2, 0, Math.PI / 2); // scene.add(gridHelper3); // // var grid = new THREE.GridHelper(300, 40, 25, [0, 0, 1], 0x000055, 0.2, true, "#FFFFFF", "left"); // scene.add(grid); var x = (boundbox.max.x - boundbox.min.x).toFixed(2); var y = (boundbox.max.y - boundbox.min.y).toFixed(2); var z = (boundbox.max.z - boundbox.min.z).toFixed(2); console.log(x); console.log(y); console.log(z); console.log(boundbox); mesh.position.set(0,0,0); // mesh.position.x = scene.position.x; // mesh.position.y = scene.position.y ; // mesh.position.z = scene.position.z; scene.add(mesh); renderer.clear(); renderer.render(scene, camera); } ); loader.load( '3dfile/莫比烏斯環(huán).STL' ); }
這里根據(jù)文件類型選擇相對(duì)應(yīng)的js引入即可 我加載的是STL模型 所以我引入的是 STLLoader.js
<script src="js/STLLoader.js"></script>
如果需要顯示網(wǎng)格標(biāo)尺 將 網(wǎng)格部分代碼 去掉注釋即可
下來(lái)是控制方法 (雖然我沒有在顯示代碼里面寫根據(jù)鍵盤按鍵放大縮小 但還是提供給大家 參考)
//控制 var effect; var controls; function initControl(){ effect = new THREE.AsciiEffect( renderer ); effect.setSize( WIDTH, HEIGHT ); controls = new THREE.TrackballControls( camera,renderer.domElement); }
最后就是一個(gè)初始調(diào)用了
function animate() { requestAnimationFrame( animate ); controls.update(); effect.render( scene, camera ); } function threeStart() { initThree(); initScene(); initCamera(); initLight(); initObject(); initControl(); animate(); }
附上完整代碼
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>WebGL</title> <script type="text/javascript" charset="utf-8" src="js/three.js"></script> <script src="js/STLLoader.js"></script> <script src="js/TrackballControls.js"></script> <script src="js/AsciiEffect.js"></script> <style>body{overflow:hidden;background:#eee}</style> </head> <script> var WIDTH,HEIGHT; var renderer; function initThree() { WIDTH = document.documentElement.clientWidth/2; <!--{foreach from=$recommended_goods item=rgoods}--> <!-- {/foreach} --> HEIGHT = document.documentElement.clientHeight/2; /* 渲染器 */ renderer = new THREE.WebGLRenderer(); renderer.setSize(WIDTH , HEIGHT); renderer.setClearColor(new THREE.Color(0x66666)); renderer.gammaInput = true; renderer.gammaOutput = true; document.body.appendChild(renderer.domElement); } /* 攝像頭 */ var camera; function initCamera() { var VIEW_ANGLE = 45, ASPECT = WIDTH / HEIGHT, NEAR = 0.1, FAR = 10000; camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR); camera.position.set(20, 0, 0); //設(shè)置視野的中心坐標(biāo) camera.lookAt(scene.position); } /* 場(chǎng)景 */ var scene; function initScene() { scene = new THREE.Scene(); } /* 燈光 */ var light,light2,light3; function initLight() { //平行光 light = new THREE.DirectionalLight(0xFFFFFF); light.position.set(0, 99, 0).normalize(); scene.add(light); //環(huán)境光 light2 = new THREE.AmbientLight(0x999999); scene.add(light2); //點(diǎn)光源 light3 = new THREE.PointLight(0x00FF00); light3.position.set(300, 0, 0); scene.add(light3); } /* 顯示對(duì)象 */ var cube; function initObject(){ // ASCII file var loader = new THREE.STLLoader(); loader.addEventListener( 'load', function ( event ) { var loading = document.getElementById("Loading"); loading.parentNode.removeChild(loading); var geometry = event.content; //磚紅色 var material = new THREE.MeshPhongMaterial( { ambient: 0xff5533, color: 0xff5533, specular: 0x111111, shininess: 200 } ); //純黑色 // var material = new THREE.MeshBasicMaterial( { envMap: THREE.ImageUtils.loadTexture( 'http://localhost:8080/textures/metal.jpg', new THREE.SphericalReflectionMapping() ), overdraw: true } ) ; //粉色 帶陰影 // var material = new THREE.MeshLambertMaterial( { color:0xff5533, side: THREE.DoubleSide } ); //灰色 // var material = new THREE.MeshLambertMaterial({color: 000000}); //材質(zhì)設(shè)定 (顏色) var mesh = new THREE.Mesh( geometry, material ); var center = THREE.GeometryUtils.center(geometry); var boundbox=geometry.boundingBox; var vector3 = boundbox.size(null); var vector3 = boundbox.size(null); console.log(vector3); var scale = vector3.length(); camera.position.set(scale, 0, 0); camera.lookAt(scene.position); scene.add(camera); //利用一個(gè)軸對(duì)象以可視化的3軸以簡(jiǎn)單的方式。X軸是紅色的。Y軸是綠色的。Z軸是藍(lán)色的。這有助于理解在空間的所有三個(gè)軸的方向。 var axisHelper = new THREE.AxisHelper(800); scene.add(axisHelper); //周圍邊框 bboxHelper = new THREE.BoxHelper(); bboxHelper.visible = true; var meshMaterial = material; mainModel = new THREE.Mesh(geometry, meshMaterial); bboxHelper.update(mainModel); bboxHelper.geometry.computeBoundingBox(); scene.add(bboxHelper); //地板網(wǎng)格 // var gridHelper = new THREE.GridHelper(500, 40); // 500 is grid size, 20 is grid step // gridHelper.position = new THREE.Vector3(0, 0, 0); // gridHelper.rotation = new THREE.Euler(0, 0, 0); // scene.add(gridHelper); // var gridHelper2 = gridHelper.clone(); // gridHelper2.rotation = new THREE.Euler(Math.PI / 2, 0, 0); // scene.add(gridHelper2); // var gridHelper3 = gridHelper.clone(); // gridHelper3.rotation = new THREE.Euler(Math.PI / 2, 0, Math.PI / 2); // scene.add(gridHelper3); // // var grid = new THREE.GridHelper(300, 40, 25, [0, 0, 1], 0x000055, 0.2, true, "#FFFFFF", "left"); // scene.add(grid); var x = (boundbox.max.x - boundbox.min.x).toFixed(2); var y = (boundbox.max.y - boundbox.min.y).toFixed(2); var z = (boundbox.max.z - boundbox.min.z).toFixed(2); console.log(x); console.log(y); console.log(z); console.log(boundbox); mesh.position.set(0,0,0); // mesh.position.x = scene.position.x; // mesh.position.y = scene.position.y ; // mesh.position.z = scene.position.z; scene.add(mesh); renderer.clear(); renderer.render(scene, camera); } ); loader.load( '3dfile/莫比烏斯環(huán).STL' ); } //控制 var effect; var controls; function initControl(){ effect = new THREE.AsciiEffect( renderer ); effect.setSize( WIDTH, HEIGHT ); controls = new THREE.TrackballControls( camera,renderer.domElement); } function animate() { requestAnimationFrame( animate ); controls.update(); effect.render( scene, camera ); } function threeStart() { initThree(); initScene(); initCamera(); initLight(); initObject(); initControl(); animate(); } </script> <body onload="threeStart()"> <div id="Loading" style="color:#fff">Loading...</div> </body> </html>
哦 我的文件結(jié)構(gòu)
如果想要所有文件的小伙伴 給我留言即可
補(bǔ)充一點(diǎn),由于在顯示模型的方法里我加入了 bboxHelper = new THREE.BoxHelper() 所以我們可以獲取到模型的 X Y Z三軸的尺寸 也可以當(dāng)作 模型的長(zhǎng)寬高
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript數(shù)據(jù)類型學(xué)習(xí)筆記分享
這篇文章主要為大家分享了JavaScript數(shù)據(jù)類型學(xué)習(xí)筆記,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09JS實(shí)現(xiàn)表格響應(yīng)式布局技巧
這篇文章主要為大家介紹了JS實(shí)現(xiàn)表格響應(yīng)式布局技巧示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07js實(shí)時(shí)監(jiān)控文本框輸入字?jǐn)?shù)的實(shí)例代碼
下面小編就為大家分享一篇實(shí)時(shí)監(jiān)控文本框輸入字?jǐn)?shù)的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01JS+CSS實(shí)現(xiàn)下拉列表框美化效果(3款)
這篇文章主要介紹了JS+CSS實(shí)現(xiàn)美化的下拉列表框效果,涉及javascript針對(duì)下拉列表框樣式的相關(guān)操作技巧,三款下拉菜單簡(jiǎn)單大方,需要的朋友可以參考下2015-08-08js手機(jī)號(hào)4位顯示空格,銀行卡每4位顯示空格效果
這篇文章主要介紹了js手機(jī)號(hào)4位顯示空格,銀行卡每4位顯示空格效果,手機(jī)號(hào)和銀行卡號(hào),按照每4位顯示一個(gè)空格的需求,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。2017-03-03ES6 Map結(jié)構(gòu)的應(yīng)用實(shí)例分析
這篇文章主要介紹了ES6 Map結(jié)構(gòu)的應(yīng)用,結(jié)合實(shí)例形式分析了ES6中map鍵值對(duì)hash結(jié)構(gòu)相關(guān)定義、獲取、輸出、遍歷等相關(guān)操作技巧,需要的朋友可以參考下2019-06-06JS按字節(jié)截取字符長(zhǎng)度實(shí)例
這篇文章主要介紹了JS按字節(jié)截取字符長(zhǎng)度實(shí)例,有需要的朋友可以參考一下2013-11-11