Three.js筆記(九)尺寸調(diào)整

簡述

前面的畫布具有個固定的尺寸,尺寸為800x600,雖然沒必要讓W(xué)ebGL適配整個屏幕,但是為了更好的體驗,適配屏幕大小是必須的。

首先,期望畫布占用所有可用空間。然后,我們需要確保如果用戶調(diào)整其窗口大小,它仍然適配。最后,我們需要為用戶提供一種以全屏方式體驗的方法。

設(shè)置

初始內(nèi)容(私信索取)包含之前完成的內(nèi)容。立方體位于中心,并且可以通過拖拽操作來移動相機。

適配視口

要使畫布適配視口,而非使用sizes變量中的固定數(shù)字,使用window.innerWidth和window.innerHeight

// ...

// 尺寸

const sizes = {

? ? width: window.innerWidth,

? ? height: window.innerHeight

}

// ...


此時可以看到畫布的大小等同于視口大小。但不幸的是,外圍有白色的邊框和一個滾動條。

這是因為瀏覽器有默認樣式,比如重要的標題、帶下劃線的鏈接、段落之間的空白以及頁面上的填充。有很多方法可以解決這個問題,這取決于網(wǎng)頁所使用的框架。如果頁面上有其他內(nèi)容,請在執(zhí)行操作時盡量不影響其他內(nèi)容。

這里使用CSS來解決這個問題。

在模版中,已經(jīng)在src/style.css文件中鏈接了一個CSS。如果不常使用Webpack,代碼看上去會很奇怪,但CSS文件確實是在script.js的第一行引入。

import './style.css'

CSS文件中可以直接寫CSS代碼,頁面會自動重載

首先要做的一件事就是使用通配符*移除margin和padding類型的元素

*

{

? ? margin: 0;

? ? padding: 0;

}

然后,使用class選擇webgl畫布,并調(diào)整畫布對齊左上角

.webgl

{

? ? position: fixed;

? ? top: 0;

? ? left: 0;

}

這樣就不用再指定畫布的寬和高,因為Three.js在調(diào)用renderer.setSize()方法時,完成了調(diào)整。

另一個問題,拖拽操作時畫布會有一個藍色的輪廓,這主要發(fā)生在Chrome上。要解決這個問題,只需要在.webgl上添加outline: none;

.webgl

{

? ? position: fixed;

? ? top: 0;

? ? left: 0;

? ? outline: none;

}

如果想刪除滾動條,可以在html和body上添加overflow: hidden

html,

body

{

? ? overflow: hidden;

}

但是這樣并不會在窗口大小發(fā)生變化時,重新調(diào)整畫布大小。

句柄調(diào)整大小

要想調(diào)整畫布大小,首先需要知道窗口何時調(diào)整大小,所以應(yīng)在窗口監(jiān)聽resize事件。

在sizes變量后添加resize監(jiān)聽器

window.addEventListener('resize', () =>

{

? ? console.log('window has been resized')

})

此時,在調(diào)整窗口大小時會觸發(fā)一個函數(shù),并顯示在控制臺。

可以通過這個更新值。

首先,更新變量sizes

window.addEventListener('resize', () =>

{

? ? //更新sizes

? ? sizes.width = window.innerWidth

? ? sizes.height = window.innerHeight

})

然后通過更新aspect屬性,修改相機寬高比

window.addEventListener('resize', () =>

{

? ? // ...

? ? // 更新相機

? ? camera.aspect = sizes.width / sizes.height

})

當修改相機屬性時,比如修改aspect時,也需要使用camera.updateProjectionMatrix()更新投影矩陣.

window.addEventListener('resize', () =>

{

? ? // ...

? ? camera.updateProjectionMatrix()

})

最后,需要更新renderer。更新renderer也會自動更新畫布的寬和高。

window.addEventListener('resize', () =>

{

? ? // ...

? ? // 更新 renderer

? ? renderer.setSize(sizes.width, sizes.height)

})

綜上

window.addEventListener('resize', () =>

{

? ? //更新sizes

? ? sizes.width = window.innerWidth

? ? sizes.height = window.innerHeight

? ? // 更新相機

? ? camera.aspect = sizes.width / sizes.height

? ? camera.updateProjectionMatrix()

? ? //更新renderer

? ? renderer.setSize(sizes.width, sizes.height)

})

此時可以根據(jù)需要調(diào)整窗口大小,且畫布完美覆蓋視口,不會有寬邊和滾動條。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容