方案一:rem 單位+動態(tài)設(shè)置 html 的 font-size
動態(tài)設(shè)置 html 根字體的大小和 body 字體大小(使用 lib_flexible.js)
-
將設(shè)計稿的寬(1920)平均分成 24 等份,每一份 80px;
-
html 根字體大小就設(shè)置為 80px,即 1rem = 80px,24rem = 1920px(移動端推薦分為 10 份);
-
將 body 字體大小設(shè)置為 16px;
-
最后需要使用插件或者其他方式將 px 轉(zhuǎn)為 rem 單位:手動、less/scss 函數(shù)、cssrem 插件、webpack 插件、Vite 插件等。
lib_flexible.js 代碼參考
(function flexible(window, document) {
var docEl = document.documentElement;
var dpr = window.devicePixelRatio || 1;
// adjust body font size
function setBodyFontSize() {
if (document.body) {
// body 字體大小默認(rèn)為 16px
document.body.style.fontSize = 16 * dpr + 'px';
} else {
document.addEventListener('DOMContentLoaded', setBodyFontSize);
}
}
setBodyFontSize();
// 這里默認(rèn)平均分成 10 等分(適用移動端)
// set 1rem = viewWidth / 24 ;(使用pc端)
function setRemUnit() {
var rem = docEl.clientWidth / 24; // 1920 / 24 = 80
docEl.style.fontSize = rem + 'px'; // 設(shè)置 html字體的大小 80px
}
setRemUnit();
// reset rem unit on page resize
window.addEventListener('resize', setRemUnit);
window.addEventListener('pageshow', function (e) {
if (e.persisted) {
setRemUnit();
}
});
// detect 0.5px supports
if (dpr >= 2) {
var fakeBody = document.createElement('body');
var testElement = document.createElement('div');
testElement.style.border = '.5px solid transparent';
fakeBody.appendChild(testElement);
docEl.appendChild(fakeBody);
if (testElement.offsetHeight === 1) {
docEl.classList.add('hairlines');
}
docEl.removeChild(fakeBody);
}
})(window, document);
方案二:vw 單位
直接使用 vw 單位,屏幕的寬默認(rèn)為 100vw,那么100vw = 1920px, 1vw = 19.2px 。
安裝 cssrem 插件, body 的寬高(1920px * 1080px)直接把 px 單位轉(zhuǎn) vw 單位
其他 px 轉(zhuǎn) vw 方式:手動、less/scss 函數(shù)、cssrem 插件、webpack 插件、Vite 插件
方案三:scale 等比例縮放(推薦)
CSS 函數(shù) scale() 用于修改元素的大小。可以通過向量形式定義的縮放值來放大或縮小元素,同時可以在不同的方向設(shè)置不同的縮放值。
使用 CSS3 中的 scale 函數(shù)來縮放網(wǎng)頁,我們可以使用兩種方案來實現(xiàn):
方案一:直接根據(jù)寬度的比率進行縮放。(寬度比率 = 網(wǎng)頁當(dāng)前寬 / 設(shè)計稿寬)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body,
ul {
margin: 0;
padding: 0;
}
body {
width: 1920px;
height: 1080px;
box-sizing: border-box;
border: 3px solid red;
/* 指定縮放的原點在左上角 */
transform-origin: left top;
}
ul {
width: 100%;
height: 100%;
list-style: none;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
li {
width: 33.333%;
height: 50%;
box-sizing: border-box;
border: 2px solid green;
font-size: 30px;
}
</style>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<script>
// 設(shè)計稿: 1920 * 1080
// 目標(biāo)適配: 1920 * 1080 3840 * 2160 ( 2 * 2 ) ; 7680 * 2160( 4 * 2)
// 1.設(shè)計稿的尺寸
let targetX = 1920;
// let targetY = 1080
// let targetRatio = 16 / 9 // 寬高比率
// 2.拿到當(dāng)前設(shè)備(瀏覽器)的寬度
let currentX = document.documentElement.clientWidth || document.body.clientWidth;
// 1920 * 1080 -> 3840 * 2160
// 3.計算縮放比例 (當(dāng)前設(shè)備的寬度 / 設(shè)計稿的寬度)
let scaleRatio = currentX / targetX; // 參照寬度進行縮放
// 4.開始縮放網(wǎng)頁 (縮放的原點在左上角)
document.body.style = `transform: scale(${scaleRatio})`;
</script>
</body>
</html>
方案二:動態(tài)計算網(wǎng)頁寬高比,決定是是否按照寬度的比率進行縮放。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body,
ul {
margin: 0;
padding: 0;
}
body {
position: relative;
width: 1920px;
height: 1080px;
box-sizing: border-box;
border: 3px solid red;
/* 指定縮放的原點在左上角 */
transform-origin: left top;
}
ul {
width: 100%;
height: 100%;
list-style: none;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
li {
width: 33.333%;
height: 50%;
box-sizing: border-box;
border: 2px solid green;
font-size: 30px;
}
</style>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<script>
// 設(shè)計稿: 1920 * 1080
// 目標(biāo)適配: 1920 * 1080 3840 * 2160 ( 2 * 2 ) ; 7680 * 2160( 4 * 2)
// 1.設(shè)計稿的尺寸
let targetX = 1920;
let targetY = 1080;
let targetRatio = 16 / 9; // 寬高比率
// 2.拿到當(dāng)前設(shè)備(瀏覽器)的寬度
let currentX = document.documentElement.clientWidth || document.body.clientWidth;
let currentY = document.documentElement.clientHeight || document.body.clientHeight;
// 1920 * 1080 -> 3840 * 2160
// 3.計算縮放比例
let scaleRatio = currentX / targetX; // 參照寬度進行縮放 ( 默認(rèn)情況 )
let currentRatio = currentX / currentY; // 寬高比率
// 超寬屏
if (currentRatio > targetRatio) {
// 如果當(dāng)前設(shè)備的寬高比率大于設(shè)計稿的寬高比率,那么就以高度為參照進行縮放,并且居中顯示
scaleRatio = currentY / targetY;
document.body.style = `width:${targetX}px; height:${targetY}px;transform: scale(${scaleRatio}) translateX(-50%); left: 50%`;
} else {
// 4.開始縮放網(wǎng)頁
document.body.style = `width:${targetX}px; height:${targetY}px; transform: scale(${scaleRatio})`;
}
</script>
</body>
</html>
三種適配放案對比
vw 相比 rem 的優(yōu)勢
優(yōu)勢一:不需要去計算html的font-size大小,不需要給html設(shè)置font-size,也不需要設(shè)置body的font-size,防止繼承;
優(yōu)勢二:因為不依賴font-size的尺寸,所以不用擔(dān)心某些原因html的font-size尺寸被篡改,頁面尺寸混亂;
優(yōu)勢三:vw相比rem更加語義化。1vw是1/100的viewport大小(即將屏幕分成100份);并且具備rem之前所有的優(yōu)點。
vw 和 rem 存在的問題
如果使用rem活vw單位時,在 js 中添加樣式時,單位需要手動設(shè)置rem或vw。
第三方庫(Element、Echarts等)的字體一般默認(rèn)都是px單位,因此通常需要層疊第三方庫的樣式。
當(dāng)大屏比例更大時,有些字體還需要相應(yīng)的調(diào)整字號。
scale相比vw和rem的優(yōu)勢
優(yōu)勢一:相比于vw和rem,使用起來更簡單,不需要對單位進行換算
優(yōu)勢二:因為不需要對單位進行換算,在使用第三方庫時,不需要考慮單位轉(zhuǎn)換問題
優(yōu)勢三:由于瀏覽器的字體默認(rèn)最小是不能超過12px,導(dǎo)致rem或vw無法設(shè)置小于12px的字體,scale縮放沒有這個問題。
大屏開發(fā)注意事項
1.字體大小設(shè)置問題(如上對比,scale不需要考慮這個問題)
2.圖片模糊問題
-
切圖時切1倍圖、2倍圖、大屏用大圖,小屏用小圖;
-
建議都使用 svg 矢量圖,保證放大和縮小不會失真。
3.Echarts 渲染引擎的選擇
推薦使用 SVG 渲染引擎,SVG 圖擴展性更好,適合一些定制化操作。
4.動畫卡頓優(yōu)化
-
創(chuàng)建新的渲染層:減少回流
-
有明確的定位屬性(relative、fixed、sticky、absolute)
-
透明度(opacity 小于 1)
-
有 CSS transform 屬性(不為 none)
-
當(dāng)前有對于 opacity、transform、fliter、backdrop-filter 應(yīng)用動畫
-
backface-visibility 屬性為 hidden
-
-
啟動GPU加速:創(chuàng)建合成層,合成層會開始GPU加速頁面渲染,但不能濫用,過多渲染層會以消耗內(nèi)存為代價
-
對 opacity、transform、fliter、backdropfilter應(yīng)用了animation或transition(需要是active的animation或者 transition)
-
有 3D transform 函數(shù):比如: translate3d、 translateZ、 scale3d 、 rotate3d ...
-
will-change 設(shè)置為 opacity、transform、top、left、bottom、right,比如:will-change: opacity , transform;其中 top、left等需要設(shè)置明確的定位屬性,如 relative 等文章來源:http://www.zghlxwxcb.cn/news/detail-671419.html
-
-
少用漸變和高斯模糊,當(dāng)不需要動畫時,及時關(guān)閉動畫。文章來源地址http://www.zghlxwxcb.cn/news/detail-671419.html
到了這里,關(guān)于【前端可視化】前端大屏適配方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!