在網頁中控制三維物件「Three.js人機交互」

先一睹為快。

這篇文章至關重要。它讓你的作品不僅限於展示你的意圖,還可以讓用戶和你的作品進行互動,置身其中,圖像可以因為每個人的交互方式而不同,也更有趣味。

這篇文章也涉及到更多的知識。會談及鍵盤和滑鼠事件的監聽,並如何在Three.js中使用這些監聽事件的返回值。

如果你耐心讀完這篇以及之前的文章,那麼我相信你已經對Three.js的知識框架已經比較熟悉了,剩下的知識細節需要慢慢填充。

本文的主要內容如下:

一、介紹常用事件

二、讓物件可交互

三、讓物件可選中

一、介紹常用事件

用戶在瀏覽網頁時,主要通過頁面上的圖形圖像、聲音等形式來接受信息,且通過滑鼠和鍵盤來向頁面輸入信息和反饋。自然地,鍵盤和滑鼠作為獲得用戶信息的兩大主要硬體設備,瀏覽器都有相應的事件來捕獲。當然還有其他獲得用戶信息的方式,比如攝像頭、錄音軟體等等,但是這些硬體設備不常用,所以,我們回到鍵盤和滑鼠的討論上:

  • 滑鼠事件

滑鼠你肯定非常熟悉了,但這些事件你是否清楚呢?點擊左鍵、點擊右鍵、雙擊左鍵、長按、移動滑鼠、在元素上停留、移入元素、移出元素、滑動滾輪等等,瀏覽器都為你做好了相應的事件去捕獲用戶的信息,你需要做的就是根據事件的返回值去做相應的事情。

  • 鍵盤事件

鍵盤事件就相對簡單得多,按下、鬆開、長按,連按等等。事件類型雖然簡單,但鍵盤上的字元種類可是超級多的,我們可以通過捕獲相應的事件,來得知用戶按下了什麼鍵,然後根據不同的按鍵值,去渲染不同的畫面。

二、讓物件可交互

我們就以之前實現的一個小目標為例,將它改造為可交互的物件。

這是在第一篇文章實現的靜止的立方體,現在,我們把它改造為能夠響應滑鼠和鍵盤事件的可交互物件。首先,要了解一下響應事件:

  • onmousemove

document.onmousemove = function(e) {n console.log("X: " + e.x + ", Y: " + e.y);n};n

簡單解釋一下,我們給document指定了當滑鼠移動的時候需要執行的函數,在執行這個函數的時候,我們會收到一個包含滑鼠信息的對象,我把它命名為"e","event"的縮寫,在這個函數內部,我就可以隨意取用這些信息了,在瀏覽器中執行這段函數,可以在console中看到列印的相關信息:

其他的事件調用方法和它類似,都會返回一個包含相關信息的對象,下面不展開介紹了。

  • onmousewheel

document.onmousewheel = function(e) {n console.log("X: " + e.deltaX + ", Y: " + e.deltaY);n};n

  • onclick

document.onclick = function() {n console.log("window width: ", window.innerWidth);n console.log("window height: ", window.innerHeight);n};n

  • onkeydown

document.onkeydown = function(e) {nswitch (e.key) {ncase "w":n console.log("w");n break;n case "s":n console.log("s");n break;n case "a":n console.log("a");n break;n case "d":n console.log("d");n break;n case "ArrowUp":n console.log("ArrowUp");n break;n case "ArrowDown":n console.log("ArrowDown");n break;n case "ArrowLeft":n console.log("ArrowLeft");n break;n case "ArrowRight":n console.log("ArrowRight");n break;n default:nbreak;n }n};n

三、讓物件可選中

如果從常規方法來思考,讓物體可選中並不容易,因為這些物件並不是DOM(Document Object Model,文檔對象模型簡稱DOM)。在Three.js中選中物體,需要請Raycaster登場:

var raycaster = new THREE.Raycaster();n

具體思路是:創造一條由滑鼠和相機確定的射線,獲取這條射線與相交的物件中的第一個,就是我們選中的物件。

var mouse = new THREE.Vector2();nndocument.onmousemove = function(e) {nn mouse.x = ( e.clientX / window.innerWidth ) * 2 - 1;n mouse.y = - ( e.clientY / window.innerHeight ) * 2 + 1;nn raycaster.setFromCamera( mouse, camera );n var intersects = raycaster.intersectObjects( scene.children );nn if ( intersects.length > 0 ) {n if ( INTERSECTED != intersects[ 0 ].object ) {n material.setValues({color: "purple"});n if ( INTERSECTED ) {material.setValues({color: "yellow"});};n INTERSECTED = intersects[ 0 ].object;n }n } else {n if ( INTERSECTED ) {material.setValues({color: "yellow"});};n INTERSECTED = null;n }nn};n

這是改造後的:可交互立方體

上一章:《Three.js面材質》

下一章:《Three.js著色材質(ShaderMaterial)》


推薦閱讀:

國外有哪些優秀的交互設計網站?
MIT的黑科技:隔著屏幕,也能和男神互動了
原型測試(Prototype testing)的方法之Think aloud

TAG:前端开发 | 人机交互 | threejs |