咱們知道canvas、svg等是2D繪圖的,那麼若是想要使用js進行3D繪圖,能夠嗎? 答案是確定的!實際上主流的3D開發使用的是c++,可是隨着技術的發展,JavaScript目前已是無孔不入了,包括web(vue/react)、移動端(RN/weex)、客戶端(electron/nw)、後端(nw)、人工智能(tensorflow.js),而three.js就是使用JavaScript進行3d繪圖的框架了,而three.js是對webgl進行封裝的,因此,實際上webgl是3D繪圖的基礎,但咱們使用three.js開發會更加高效。遺憾的是,目前僅有部分主流瀏覽器支持webgl,但仍是值得咱們探索和在合適的場景下使用的。而three.js也是很是容易從字面理解的,three就是3d,js就是JavaScript,因此three.js就是使用JavaScript進行3d開發。html
在github上能夠找到three.js,能夠看到,three.js目前star數已經達到了4萬之多,足以說明其流行程度。 下面是three.js的github目錄:vue
能夠看到,three.js更新很是頻繁,這裏主要介紹一下各個目錄。 build目錄是生成的咱們直接引用的three.js和three.min.js文件;docs目錄中羅列了three.js相關文檔;editor目錄是一些簡單編輯程序;example目錄是three.js實現的一些例子; src目錄是該項目的源代碼;test目錄是項目的測試代碼;utils目錄存放一些腳本。react
使用很是簡單,首先咱們進入build目錄中的three.min.js,而後點擊raw按鈕,就能夠獲得一個url(https://raw.githubusercontent.com/mrdoob/three.js/dev/build/three.min.js),最後咱們在html文件中引入這個js文件便可,注意:github連接較慢,咱們能夠複製js代碼到本地,而後引入,以下所示:c++
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>three.js</title> <script src="./three.js"></script> </head> <body> </body> </html>
接着,咱們在chrome瀏覽器中打開F12,在console控制檯中輸入THREE,而後回車,能夠獲得下面的結果:git
即THREE是three.js暴露出來的一個對象,其中有不少屬性和方法能夠調用。github
在three.js中,核心的即是場景(scene)、相機(camera)、渲染器(renderer),有了這三者,才能使用相機將場景渲染到網頁上去。web
描述3D使用的就是場景,使用THREE.Scene()構造,注意,THREE是對象,而Scene是構造函數,因此首字母都是大寫的。chrome
相機就像咱們的眼睛,從不一樣的角度看,那麼看到的場景也就不同。另外,場景是同樣的,而相機有多種拍照方式,因此,須要咱們根據須要調整。而最經常使用的就是透視相機,即THREE.PerspectiveCamera(),一樣的,THREE是對象,PerspectiveCamera是構造函數,首字母大寫,且是駝峯式命名方法。canvas
即在網頁上顯示什麼元素,都是須要渲染出來的,使用THREE.WebGLRenderer,且在使用過程當中,須要使用domElement掛載到頁面上,後面的例子會講解。 後端
而對於這三者,咱們能夠認爲場景是一個容器,能夠將一些物體如cube放在這個容器中;而相機的做用就是對這個選擇合適的角度容器拍攝獲得一張照片;渲染器的做用是把相機拍到的照片放到瀏覽器中顯示,以下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>three.js</title> <style> * { margin: 0; padding: 0; } </style> <script src="./three.js"></script> </head> <body> <script> var scene = new THREE.Scene(); var axes = new THREE.AxesHelper(100); scene.add(axes); var camera = new THREE.PerspectiveCamera(50, window.innerWidth/window.innerHeight, 1, 1000); camera.position.x = 100; camera.position.y = 100; camera.position.z = 100; camera.lookAt(scene.position); var renderer = new THREE.WebGLRenderer(); renderer.setClearColor(0x111111); renderer.setSize(window.innerWidth, window.innerHeight); var geometry = new THREE.CubeGeometry(10, 10, 10); var material = new THREE.MeshBasicMaterial({color: 0xff0000}); var cube = new THREE.Mesh(geometry, material); cube.position.x = 0; cube.position.y = 0; cube.position.z = 0; scene.add(cube); document.body.append(renderer.domElement); renderer.render(scene, camera); </script> </body> </html>
因而,咱們能夠看到,使用three.js仍是很簡單的,就是場景、座標軸、相機、渲染引擎、事物、掛載。最後結果以下:
如上所示是靜態的,若是須要時動態的,就須要用到渲染循環了,主要用到的函數是requestAnimationFrame,以下,僅僅替換了極少的代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>three.js</title> <style> * { margin: 0; padding: 0; } </style> <script src="./three.js"></script> </head> <body> <script> var scene = new THREE.Scene(); var axes = new THREE.AxesHelper(100); scene.add(axes); var camera = new THREE.PerspectiveCamera(50, window.innerWidth/window.innerHeight, 1, 1000); camera.position.x = 100; camera.position.y = 100; camera.position.z = 100; camera.lookAt(scene.position); var renderer = new THREE.WebGLRenderer(); renderer.setClearColor(0x111111); renderer.setSize(window.innerWidth, window.innerHeight); var geometry = new THREE.CubeGeometry(10, 10, 10); var material = new THREE.MeshBasicMaterial({color: 0xff0000}); var cube = new THREE.Mesh(geometry, material); cube.position.x = 0; cube.position.y = 0; cube.position.z = 0; requestAnimationFrame(function () { cube.position.x++; }); scene.add(cube); document.body.append(renderer.domElement); function render() { cube.rotation.x += 0.1; cube.rotation.y += 0.1; renderer.render(scene, camera); requestAnimationFrame(render); } render(); </script> </body> </html>
以下所示,經過requestAnimationFrame在配合cude的rotation屬性使用,就可讓這個cube旋轉起來了。
另外,對於相機的設置,咱們還能夠設置up屬性,即camera.up.x = 0; camera.up.y = 0; camera.up.z = 0;即camera的position屬性能夠肯定相機位置,lookAt能夠肯定看的方向,可是相機拍攝是咱們這樣豎着拍攝仍是橫着拍攝呢,這就取決於你設置camera的上方了,使用camera.up屬性來設置。