微信小程序如何橫屏
從小程序基礎(chǔ)庫(kù)版本 2.4.0 開(kāi)始,小程序在手機(jī)上支持屏幕旋轉(zhuǎn)。使小程序中的頁(yè)面支持屏幕旋轉(zhuǎn)的方法是:在 app.json
的 window
段中設(shè)置 "pageOrientation": "auto"
妆档,或在頁(yè)面 json 文件中配置 "pageOrientation": "auto"
主经。
PS:1排霉、以這種方式實(shí)現(xiàn)小程序屏幕旋轉(zhuǎn),需要用戶關(guān)閉手機(jī)上的“屏幕鎖定”選項(xiàng)
PS:2硬纤、由于開(kāi)啟橫屏需要修改json文件的配置,而這個(gè)文件我們無(wú)法在程序運(yùn)行中進(jìn)行修改碘梢,故我們無(wú)法通過(guò)點(diǎn)擊按鈕或其他操作去使手機(jī)屏幕發(fā)生旋轉(zhuǎn)咬摇,只是是設(shè)置為"pageOrientation": "auto"
用戶主動(dòng)旋轉(zhuǎn)手機(jī)觸發(fā)
PS:3、我們可以在進(jìn)入某一個(gè)頁(yè)面的時(shí)候煞躬,固定屏幕橫屏展示肛鹏,設(shè)置"pageOrientation": "landscape "
如何獲取當(dāng)前屏幕狀態(tài)
使用 selectorQuery.selectViewport可以獲取到當(dāng)前的屏幕狀態(tài)。這種方式比較麻煩恩沛,這里介紹一種使用wx.onWindowResize
進(jìn)行監(jiān)聽(tīng)的方式在扰。
onShow() {
let that = this;
wx.onWindowResize(function(res) {
if (res.deviceOrientation === 'landscape') {
that.isRotating = true;
} else {
that.isRotating = false;
}
})
}
上面代碼中,我們可以在wx.onWindowResize
函數(shù)的回調(diào)中獲取到當(dāng)前屏幕的方向雷客,并賦值給isRotating
芒珠。當(dāng)然,我們還可以在回調(diào)中拿到windowWidth
(變化后的窗口寬度搅裙,單位 px)和windowHeight
(變化后的窗口高度皱卓,單位 px)屬性裹芝。
wx.onWindowResize
函數(shù)是一個(gè)監(jiān)聽(tīng)函數(shù),類似Vue
中的watch
娜汁,我們可以把它放到onShow
中嫂易。
橫屏后出現(xiàn)的適配問(wèn)題
我們都知道,微信小程序在豎屏狀態(tài)下掐禁,寬度100%怜械,100VW的值為750rpx。但是在橫屏之后傅事,750rpx的實(shí)際寬度為手機(jī)屏幕的高缕允。如圖:
在這種情況下,我們的界面將會(huì)變大蹭越。
舉個(gè)簡(jiǎn)單例子障本,假如手機(jī)屏幕的寬高比為1:2,我們有一個(gè)按鈕大小為100rpx100rpx响鹃,那么在豎屏狀態(tài)下彼绷,顯示正常,橫屏狀態(tài)下茴迁,按鈕的顯示寬高將會(huì)變成原來(lái)的2倍寄悯,當(dāng)然他仍然是100rpx100rpx,但是顯示出來(lái)卻是變大了堕义。
橫屏后的適配方案
使用px進(jìn)行布局
我們可以看到猜旬,使用px
進(jìn)行布局時(shí),橫屏之后元素并沒(méi)有變大倦卖,所以這種方案是可行的洒擦。
但是,我們可以看到的是怕膛,375px在橫屏?xí)r并沒(méi)有占滿全屏熟嫩,也就是px
和rpx
之間并不是簡(jiǎn)單的1:2的對(duì)應(yīng)關(guān)系。
這里我們不討論個(gè)物理像素褐捻、pt掸茅、px之間復(fù)雜的關(guān)系(/ω\)
所以,使用
px
布局柠逞,也不是那么好用昧狮。
使用vmin進(jìn)行布局
先介紹下css3的兩個(gè)屬性vmax
和vmin
vmax 相對(duì)于視口的寬度或高度中較大的那個(gè)。其中最大的那個(gè)被均分為100單位的vmax
vmin 相對(duì)于視口的寬度或高度中較小的那個(gè)板壮。其中最小的那個(gè)被均分為100單位的vmin
文檔說(shuō)明
在這里我們只用到了vmin
逗鸣。
當(dāng)我們?cè)谪Q屏?xí)r候,100vmin
的取值為手機(jī)屏幕寬度,當(dāng)橫屏?xí)r候撒璧,100vmin
的取值仍然為手機(jī)屏幕寬度透葛,所以以vmin
為單位的元素,在手機(jī)屏幕發(fā)生旋轉(zhuǎn)的時(shí)候卿樱,其顯示大小并不會(huì)發(fā)生改變(畢竟不管橫屏豎屏获洲,100vmin
都等于屏幕的寬度)。
在使用rpx
進(jìn)行布局時(shí)殿如,750rpx
的取值為手機(jī)屏幕的寬度,而在使用vmin
時(shí)最爬,100vmin
的取值為手機(jī)屏幕的寬度涉馁,所以,rpx
和vmin
之間存在一個(gè)換算關(guān)系爱致,即:x rpx=( x * 100 / 750)vmin
烤送。舉個(gè)例子,75rpx
轉(zhuǎn)化為vmin
為75 * 100 / 750 = 10 vmin
糠悯。所以帮坚,我們只要將rpx
轉(zhuǎn)化成vmin
就可以愉快的碼頁(yè)面了~
使用scss進(jìn)行轉(zhuǎn)化
在實(shí)際開(kāi)發(fā)中,我們不可能去手動(dòng)計(jì)算每一個(gè)vmin
的值互艾,由于我用的是scss
试和,所以我用scss
進(jìn)行了一下預(yù)處理。這里提供兩種方式纫普,一種是css
函數(shù)阅悍,另一種是css mixin
//css函數(shù)
@function tovmin($rpx){//$rpx為需要轉(zhuǎn)換的字號(hào)
@return #{$rpx * 100 / 750}vmin;
}
//使用方式
.slideAddPanel {
width: tovmin(48);
height: tovmin(80);
background: rgba(0, 0, 0, 0.5);
box-shadow: 0 tovmin(2) tovmin(12) 0 rgba(0, 0, 0, 0.2);
line-height: tovmin(80);
border-radius: 0 tovmin(10) tovmin(10) 0;
}
//css mixin
@mixin upx2vmin($property, $values...) {
$max: length($values);//返回$values列表的長(zhǎng)度值
$pxValues: '';
$remValues: '';
@for $i from 1 through $max {
$value: nth($values, $i);
$remValues: #{$remValues + ($value * 100 / 750)}vmin;
@if $i < $max {
$remValues: #{$remValues + " "};
}
}
#{$property}: $remValues;
}
//使用方式
.slideAddPanel {
@include remCalc(width,45);
@include remCalc(margin,1,.5,2,3);
}
PS:這兩種方法均來(lái)自網(wǎng)絡(luò),我還是比較喜歡第一種~