1. 程式人生 > 前端設計 >從零開始初嘗Three.js(大量案例、簡單入手)

從零開始初嘗Three.js(大量案例、簡單入手)

不經意間看到了某個官網的動態效果~
實在是太帥啦!十分地友好
查了查實現該效果地技術 —— 原來是Three.js
那就讓我來從零初嘗Three.js動態3D效果吧✨
✨有大量案例和找尋原始碼的方法噢✨


背景

隨著當今時期前端地愈來愈普及,頁面實現的效果真的是越來越棒!
隨著數字影象處理、人工智慧技術的發展
展示給使用者的視覺效果便不侷限於平面的2D視覺效果
開始注重於全方位的3D立體展示效果
力求對於商品的361度地無死角供使用者認識瞭解
今天~就跟著大大初嘗一下優秀的三維引擎 Three.js


瞭解

Three.js是基於原生WebGL封裝執行的三維引擎,在所有WebGL引擎中,Three.js是國內文資料最多、使用最廣泛的三維引擎。

Threejs是一款WebGL三維引擎,它可以用來做什麼許多許多地場景應用

下面我來介紹一下官方執行的經典案例吧

應用場景

物聯網3D視覺化

隨著物聯網的發展,工業、建築等各個領域與物聯網相關Web專案網頁互動介面都會呈現出
3D化的趨勢
3D的方式更為直觀,當然開發成本也比較大
而Three.js可以將開發成本大大降低
物聯網糧倉3D視覺化案例

產品720線上預覽

隨著WebGL技術的持續推廣,5G技術的持續推廣,各種產品線上3D展示將會變得越來越普及
比如一家汽車公司的新款轎車可以在官網上線上預覽
也許有一天一些電商平臺會通過3D模型取代2D圖片
現在你朋友推薦推薦給你一款新衣服,你會說發一張圖片看看
也許將來你會說發來一個3D模型連結看看


沙發線上預覽
服裝線上預覽
洗衣機線上互動預覽

資料視覺化

與webgl相關的資料視覺化主要是兩方面
一方面是海量超大資料的視覺化,另一方面是與3D相關的資料視覺化。
對於超大的海量資料而言
基於canvas、svg等方式進行web視覺化,沒有基於WebGL技術實現效能更好
對於3D相關的資料視覺化基於WebGL技術
藉助3D引擎Threejs可以很好的實現
解析GeoJOSN資料中國GDP資料視覺化
3D直方圖

H5/微信小遊戲

非常火的微信小遊戲跳一跳就是使用Three.js引擎開發的
開發3D類的H5小遊戲或者微信小遊戲,Three.js引擎是非常好的選擇噢 無需下載,方便傳播,目前的生態非常和小遊戲開發。

科教領域

在科教領域通過3D方式展示特定的知識相比較影象更為直觀。
科研平臺-蛋白質結構視覺化案例
化學相關——分子結構視覺化
地理天文相關——太陽系3D預覽

機械領域

Onshape是一款機械領域的三維建模軟體
如果熟悉Solidworks、UG等CAD軟體,那麼你可以把Onshape理解為雲Solidworks。 機械模型線上預覽demo

更多

Three.js還有很多的精巧的應用場景噢
在這裡就不一一列舉了
感幸福的小夥伴可以到Three.js的官網案例看一看噢
戳戳這裡看更多噢


認識

Three.js資源

首先看看Three.js的資源噢

github連結
Three.js官網
Three.js中文文件

下載Three.js包

可以直接從github中拉取master分支到本地噢

因為有幾十M的大小,github下載threejs比較慢
所以作者在網盤放了一份,方便大家下載噢
網盤資源


初嘗

首先跟著官網來熟悉一下Three.js的本地案例吧

本地初始化專案

初始化目錄結構

建立ThreeJs資料夾 建立index.html檔案
建立js資料夾
將下載的three.js包放入js資料夾中

案例一: 第一個3D場景

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>第一個three.js檔案_WebGL三維場景</title>
  <style>
    body {
      margin: 0;
      overflow: hidden;
      /* 隱藏body視窗區域滾動條 */
    }
  </style>
  <!--引入three.js三維引擎-->
  <!-- <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js"></script>-->
  <script src="js/three/build/three.js"></script>
  <!-- <script src="http://www.yanhuangxueyuan.com/threejs/build/three.js"></script> -->
</head>

<body>
  <script>
    /**
     * 建立場景物件Scene
     */
    var scene = new THREE.Scene();
    /**
     * 建立網格模型
     */
    // var geometry = new THREE.SphereGeometry(60,40,40); //建立一個球體幾何物件
    var geometry = new THREE.BoxGeometry(100,100,100); //建立一個立方體幾何物件Geometry
    var material = new THREE.MeshLambertMaterial({
      color: 0x0000ff
    }); //材質物件Material
    var mesh = new THREE.Mesh(geometry,material); //網格模型物件Mesh
    scene.add(mesh); //網格模型新增到場景中
    /**
     * 光源設定
     */
    //點光源
    var point = new THREE.PointLight(0xffffff);
    point.position.set(400,200,300); //點光源位置
    scene.add(point); //點光源新增到場景中
    //環境光
    var ambient = new THREE.AmbientLight(0x444444);
    scene.add(ambient);
    // console.log(scene)
    // console.log(scene.children)
    /**
     * 相機設定
     */
    var width = window.innerWidth; //視窗寬度
    var height = window.innerHeight; //視窗高度
    var k = width / height; //視窗寬高比
    var s = 200; //三維場景顯示範圍控制係數,係數越大,顯示的範圍越大
    //建立相機物件
    var camera = new THREE.OrthographicCamera(-s * k,s * k,s,-s,1,1000);
    camera.position.set(200,300,200); //設定相機位置
    camera.lookAt(scene.position); //設定相機方向(指向的場景物件)
    /**
     * 建立渲染器物件
     */
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(width,height);//設定渲染區域尺寸
    renderer.setClearColor(0xb9d3ff,1); //設定背景顏色
    document.body.appendChild(renderer.domElement); //body元素中插入canvas物件
    //執行渲染操作   指定場景、相機作為引數
    renderer.render(scene,camera);
  </script>
</body>
</html>
複製程式碼

效果:


整個程式的結構:

案例二: 旋轉動畫、週期渲染

在案例一,已經做出了一個3D立方體的模型
在此基礎上,我們嘗試地把它旋轉起來

週期渲染

每執行一次渲染器物件WebGLRenderer的渲染方法.render() 瀏覽器就會渲染出一幀影象並顯示在Web頁面上,這就是說你按照一定的週期不停地呼叫渲染方法.render()就可以不停地生成新的影象覆蓋原來的影象。 這也就是說只要一邊旋轉立方體,一邊執行渲染方法.render()重新渲染,就可以實現立方體的旋轉效果。

所以我們可以利用js中的定時器+render()來將3D立方體動起來

將程式碼:

renderer.render(scene,camera);
複製程式碼

替換為:si

// 渲染函式
function render() {
    renderer.render(scene,camera);//執行渲染操作
    mesh.rotateY(0.01);//每次繞y軸旋轉0.01弧度
}
//間隔20ms週期性呼叫函式fun,20ms也就是重新整理頻率是50FPS(1s/20ms),每秒渲染50次
setInterval(render,20);
複製程式碼

這裡官方說呼叫渲染方法.render()進行渲染的渲染頻率不能太低

//設定呼叫render函式的週期為200ms,重新整理頻率相當於5你能明顯的感受到卡頓
setInterval("render()",200);
複製程式碼

函式requestAnimationFrame()

實際開發中,為了更好的利用瀏覽器渲染 可以使用函式requestAnimationFrame()代替setInterval()函式

requestAnimationFrame()引數是將要被呼叫函式的函式名,requestAnimationFrame()呼叫一個函式不是立即呼叫而是向瀏覽器發起一個執行某函式的請求, 什麼時候會執行由瀏覽器決定,一般預設保持60FPS的頻率,大約每16.7ms呼叫一次requestAnimationFrame()方法指定的函式,60FPS是理想的情況下,如果渲染的場景比較複雜或者說硬體效能有限可能會低於這個頻率。可以檢視文章《requestAnimationFrame()》瞭解更多requestAnimationFrame()函式的知識。

function render() {
        renderer.render(scene,camera);//執行渲染操作
        mesh.rotateY(0.01);//每次繞y軸旋轉0.01弧度
        requestAnimationFrame(render);//請求再次執行渲染函式render
    }
render();
複製程式碼

案例三: 滑鼠操作三維場景

程式碼實現

function render() {
  renderer.render(scene,camera);//執行渲染操作
}
render();
var controls = new THREE.OrbitControls(camera,renderer.domElement);//建立控制元件物件
controls.addEventListener('change',render);//監聽滑鼠、鍵盤事件
複製程式碼

OrbitControls.js控制元件提供了一個建構函式THREE.OrbitControls(),把一個相機物件作為引數的時候,執行程式碼new THREE.OrbitControls(camera,renderer.domElement),瀏覽器會自動檢測滑鼠鍵盤的變化, 並根據滑鼠和鍵盤的變化更新相機物件的引數,比如你拖動滑鼠左鍵,瀏覽器會檢測到滑鼠事件,把滑鼠平移的距離按照一定演算法轉化為相機的的旋轉角度,你可以聯絡生活中相機拍照,即使景物沒有變化,你的相機拍攝角度發生了變化,自然渲染器渲染出的結果就變化了,通過定義監聽事件controls.addEventListener('change',render),如果你連續操作滑鼠,相機的引數不停的變化,同時會不停的呼叫渲染函式render()進行渲染,這樣threejs就會使用相機新的位置或角度資料進行渲染。
執行建構函式THREE.OrbitControls()瀏覽器會同時幹兩件事,一是給瀏覽器定義了一個滑鼠、鍵盤事件,自動檢測滑鼠鍵盤的變化,如果變化了就會自動更新相機的資料, 執行該建構函式同時會返回一個物件,可以給該物件新增一個監聽事件,只要滑鼠或鍵盤發生了變化,就會觸發渲染函式。

場景操作

  • 縮放:滾動—滑鼠中鍵
  • 旋轉:拖動—滑鼠左鍵
  • 平移:拖動—滑鼠右鍵

requestAnimationFrame()使用情況

如果threejs程式碼中通過requestAnimationFrame()實現渲染器渲染方法render()的週期性呼叫
當通過OrbitControls操作改變相機狀態的時候
沒必要在通過controls.addEventListener('change',render)監聽滑鼠事件呼叫渲染函式
因為requestAnimationFrame()就會不停的呼叫渲染函式。

function render() {
  renderer.render(scene,camera);//執行渲染操作
  // mesh.rotateY(0.01);//每次繞y軸旋轉0.01弧度
  requestAnimationFrame(render);//請求再次執行渲染函式render
}
render();
var controls = new THREE.OrbitControls(camera);//建立控制元件物件
// 已經通過requestAnimationFrame(render);週期性執行render函式,沒必要再通過監聽滑鼠事件執行render函式
// controls.addEventListener('change',render)
複製程式碼

效果:

注意官方的衝突事項

注意開發中不要同時使用requestAnimationFrame()或controls.addEventListener('change',render)呼叫同一個函式,這樣會衝突。

本次初嘗Three.js案例就到這裡噢~相信感興趣的小夥伴們對此也有一點認識啦 接下來的學習,就靠各位小夥伴們自行摸索啦!

Three.js官網教程


官方案例

是不是初次嘗試Three.js只"品味"了這幾個案例不過癮呀!
沒關係!讓我們一起看看官網優秀的案例
並且找到他們的原始碼吧!

Three.js官網優秀案例

展示

我來安利當中幾個特別不錯的安利吧

  • gpgpu_birds

  • geometry_minecraft

  • effects_anaglyph

  • animation_skinning_morph

  • buffergeometry_drawrange

以上安利只是我自己覺得有趣的安利噢~ 官網中有將近上百個案例 還在等待什麼!趕緊去體驗下Three.js的絕妙效果吧~

原始碼

到官網中發現了很多優秀的案例~
那該怎麼獲取到它的原始碼呢

我整理了兩種方法查詢到它的原始碼噢

  1. 在官網的右下角有一個按鈕

點選按鈕即可進入github中的案例原始碼


  1. 所有官網案例都可以在tree資料夾下找到

tree > examples > [案例名].html

這樣咱們就初次嚐到了Tree.js的滋味啦 不得不說!這可真"鮮美"


尾言

很開心能與你們分享部落格文章哦~ 部落格原文章✨

要是這篇文章對您有那麼一丟丟的幫助 點一個贊? 吧
(悄悄說~ 點了? 的你會更加幸運de !)

小屋隨時歡迎你們到來噢~ 也歡迎各位小確幸們的批評和指正~