作展現類項目的時候,一般要實現一些圓形選擇的效果。這個藉助css
的rotate
就能夠實現.可是!要實現一個3D
的帶圖片的旋轉球體該怎麼作呢?讓咱們開始吧。css
完整代碼codesandbox
完整代碼gitee
預覽地址
備用預覽地址
將場景藉助three.js來進行顯示,咱們須要如下幾個對象:場景、相機和渲染器,這樣咱們就能透過攝像機渲染出場景。git
let camera, scene, renderer; // scene scene = new THREE.Scene(); // camera camera = new THREE.PerspectiveCamera( 10, window.innerWidth / window.innerHeight, 0.1, 200 ); camera.position.set(30, 5, 20); //renderer renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement);
咱們花一點點時間來解釋一下這裏發生了什麼。咱們如今創建了場景、相機和渲染器。canvas
three.js裏有幾種不一樣的相機,在這裏,咱們使用的是PerspectiveCamera
(透視攝像機)。api
第一個參數是視野角度(FOV)。視野角度就是不管在何時,你所能在顯示器上看到的場景的範圍,數值越大越遠。瀏覽器
第二個參數是長寬比(aspect ratio)。 也就是你用一個物體的寬除以它的高的值。好比說,當你在一個寬屏電視上播放老電影時,能夠看到圖像彷彿是被壓扁的。app
接下來的兩個參數是近截面(near)和遠截面(far)。 當物體某些部分比攝像機的遠截面遠或者比近截面近的時候,該這些部分將不會被渲染到場景中。或許如今你不用擔憂這個值的影響,但將來爲了得到更好的渲染性能,你將能夠在你的應用程序裏去設置它。dom
接下來是渲染器。這裏是施展魔法的地方。除了咱們在這裏用到的WebGLRenderer
渲染器以外,Three.js
同時提供了其餘幾種渲染器,當用戶所使用的瀏覽器過於老舊,或者因爲其餘緣由不支持WebGL
時,可使用這幾種渲染器進行降級。函數
除了建立一個渲染器的實例以外,咱們還須要在咱們的應用程序裏設置一個渲染器的尺寸。好比說,咱們可使用所須要的渲染區域的寬高,來讓渲染器渲染出的場景填充滿咱們的應用程序。所以,咱們能夠將渲染器寬高設置爲瀏覽器窗口寬高。對於性能比較敏感的應用程序來講,你可使用setSize
傳入一個較小的值,例如window.innerWidth/2
和window.innerHeight/2
,這將使得應用程序在渲染時,以一半的長寬尺寸渲染場景。工具
若是你但願保持你的應用程序的尺寸,可是以較低的分辨率來渲染,你能夠在調用setSize
時,將updateStyle
(第三個參數)設爲false
。例如,假設你的<canvas>
標籤如今已經具備了100%的寬和高,調用setSize(window.innerWidth/2, window.innerHeight/2, false)
將使得你的應用程序以一半的分辨率來進行渲染。
最後一步很重要,咱們將renderer
(渲染器)的dom
元素(renderer.domElement)添加到咱們的HTML
文檔中。這就是渲染器用來顯示場景給咱們看的<canvas>
元素。
「嗯,看起來很不錯,那你說的那個球體在哪兒?」接下來,咱們就來添加球體。
let earth; const earthGeometry = new THREE.SphereGeometry(2, 16, 16); const earthMaterial = new THREE.MeshBasicMaterial({ specular: 0x333333, shininess: 5, map: textureLoader.load("./img/earth_atmos_2048.jpg"), specularMap: textureLoader.load("./img/earth_specular_2048.jpg"), normalMap: textureLoader.load("./img/earth_normal_2048.jpg"), normalScale: new THREE.Vector2(0.85, 0.85), }); earth = new THREE.Mesh(earthGeometry, earthMaterial); scene.add(earth); // controls const controls = new THREE.OrbitControls(camera, renderer.domElement); controls.minDistance = 5; controls.maxDistance = 100; controls.enablePan = false;
要建立一個球體,咱們須要一個SphereGeometry(球緩衝幾何體)對象. 這個對象該幾何體是經過掃描並計算圍繞着Y軸(水平掃描)和X軸(垂直掃描)的頂點來建立的
接下來,對於這個球體,咱們須要給它一個材質,並加入圖片。Three.js自帶了幾種材質,在這裏咱們使用的是MeshBasicMaterial。若是須要一些光照和物理材質可使用MeshPhysicalMaterial
第三步,咱們須要一個Mesh(網格)。 網格包含一個幾何體以及做用在此幾何體上的材質,咱們能夠直接將網格對象放入到咱們的場景中,並讓它在場景中自由移動。
第四步,加入控制器,以便咱們能夠拖動選擇球體
如今,若是將以前寫好的代碼複製到HTML文件中,你不會在頁面中看到任何東西。這是由於咱們尚未對它進行真正的渲染。爲此,咱們須要使用一個被叫作「渲染循環」(render loop)或者「動畫循環」(animate loop)的東西
function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); }
在開始以前,若是你已經將上面的代碼寫入到了你所建立的文件中,你能夠看到一個地球。讓咱們來作一些更加有趣的事 —— 讓它旋轉起來。
將下列代碼添加到animate()
函數中renderer.render
調用的上方:
earth.rotation.x += 0.001; earth.rotation.y += 0.001;
這段代碼每幀都會執行(正常狀況下是60次/秒),這就讓球體有了一個看起來很不錯的旋轉動畫。基本上來講,當應用程序運行時,若是你想要移動或者改變任何場景中的東西,都必需要通過這個動畫循環。固然,你能夠在這個動畫循環裏調用別的函數,這樣你就不會寫出有上百行代碼的animate函數。
//加載背景紋理 var texture = textureLoader.load("./img/eQ9y7xBeY4.jpg"); scene.background = texture;
這樣咱們就實現了一個基於圖片覆蓋的旋轉球體
完整代碼codesandbox
完整代碼gitee
預覽地址
備用預覽地址