方法一 創建兩個THREE對象分層控制
兩個DIV,創建兩個THREE對象,完全弄出兩套
<div id="divBG"></div>
<div id="divZT"></div>
divBG,綁定創建THREE對象1,在場景中添加背景圖片,設置controls的自動旋轉,關鍵代碼如下:
initScene () {
// 場景作爲一個容器
scene = new THREE.Scene()
let urls = ['dark-s_px.jpg', 'dark-s_nx.jpg', 'dark-s_py.jpg', 'dark-s_ny.jpg', 'dark-s_pz.jpg', 'dark-s_nz.jpg']
let loader = new THREE.CubeTextureLoader()
loader.setPath('/static/three/MilkyWay/')
let background = loader.load(urls)
scene.background = background
},
initControls () {
controls = new OrbitControls(camera, renderer.domElement)
controls.autoRotate = true // 是否自動旋轉
controls.autoRotateSpeed = 1.0 // 自動旋轉的速度,默認值是 2.0,即渲染滿60幀的情況下30秒旋轉360度。
},
注意camera、renderer等綁定的是divBG對應的dom。
divZT,綁定創建THREE對象2,場景不要設置背景,直接加載主體不需要轉動的部分。
在此不贅述,重點在方法二。
方法二 場景旋轉主體逆向旋轉
全部綁定在一個DIV上實現,創建一個THREE對象,給其最外層場景設置背景,同時設置controls.autoRotate的自動旋轉。此時,整個場景裏的對象都會旋轉起來,爲了讓主體部分保持不動,只需設置主體部分進行逆向旋轉即可。
關鍵步驟如下:
1、創建DIV
<div id="divOne"></div>
divOne = document.getElementById('divOne')
2、創建外層場景並添加背景圖片,創建子場景放置不旋轉的對象
// 場景
initScene () {
scene = new THREE.Scene()
// 給當前場景容器添加背景圖片
let urls = ['dark-s_px.jpg', 'dark-s_nx.jpg', 'dark-s_py.jpg', 'dark-s_ny.jpg', 'dark-s_pz.jpg', 'dark-s_nz.jpg']
let loader = new THREE.CubeTextureLoader()
loader.setPath('/static/three/MilkyWay/')
let background = loader.load(urls)
scene.background = background
// 創建一個groupNoRotate不隨着場景旋轉而旋轉
groupNoRotate = new THREE.Group()
scene.add(groupNoRotate)
},
3、添加燈光至外層場景,跟隨背景旋轉
// 燈光
initLight () {
let ambientLight = new THREE.AmbientLight(0xffffff) // 環境光
let directionalLight = new THREE.DirectionalLight(0xffffff, 0.1) // 平行光
directionalLight.position.set(5, 10, 5)
let pointLight = new THREE.PointLight(0xffffff) // 點光源
pointLight.position.set(30, 10, 10)
// 將光源加入場景 因爲加入scene而不是groupNoRotate 所以光源也會自動轉動
scene.add(ambientLight)
scene.add(directionalLight)
scene.add(pointLight)
},
4、設置控制器的自動旋轉及自動旋轉速度
// 控制器
initControls () {
controls = new OrbitControls(camera, renderer.domElement)
……
controls.autoRotate = true // 是否自動旋轉
controls.autoRotateSpeed = 1.0 // 自動旋轉的速度,默認值是 2.0,即渲染滿60幀的情況下30秒旋轉360度。
……
},
5、加載模型至內層場景groupNoRotate
// 模型加載
initModel () {
// 實例化加載器
let loader = new GLTFLoader()
loader.load('/static/three/model/line.glb', function (obj) {
if (groupNoRotate !== null) {
groupNoRotate.add(obj.scene) // 此處需將模型加載到groupNoRotate中一同控制groupNoRotate逆旋轉
}
console.log('loaded')
}, function (xhr) {
console.log(xhr.loaded, 'loading')
}, function (error) {
console.error(error, 'load error!')
})
},
6、場景動畫,將內層場景y軸旋轉設置爲逆向旋轉
// 場景動畫
animate () {
// 控制groupNoRotate裏面的所有對象一起逆向旋轉,場景在自動旋轉,所以表現爲不旋轉
if (groupNoRotate !== null) {
groupNoRotate.rotation.y = groupNoRotate.rotation.y - Math.PI / (30 * 60)
}
controls.update()
renderer.render(scene, camera)
stop = requestAnimationFrame(this.animate)
},
關鍵點
自動旋轉的速度controls.autoRotateSpeed要和逆向旋轉的角度groupNoRotate.rotation.y相抵消!!!
controls.autoRotateSpeed = 1.0 // 自動旋轉的速度,默認值是 2.0,即渲染滿60幀的情況下30秒旋轉360度。
groupNoRotate.rotation.y = groupNoRotate.rotation.y - Math.PI / (30 * 60)
經測試發現,groupNoRotate.rotation.y每次的減幅應該是Math.PI / (30 * 60) * autoRotateSpeed。
即
controls.autoRotateSpeed = k
groupNoRotate.rotation.y = groupNoRotate.rotation.y - Math.PI * k / (30 * 60)
爲什麼呢?我不知道瞎蒙的試了幾次中了,求解…………
效果截圖
明顯能看出背景在轉動,而主體部分(藍色線)保持不動。