近每個前端都會經歷大屏的開發,不管是投屏到4k顯示器還是投屏到100寸的展廳裡,都要保證頁面的自適應。這裏我實現的樣式用sass語言。
大屏自適應
全域性global.scss樣式部分直接上程式碼:
@use "sass:math"; // 預設設計稿的寬度和高度 $default-design-width: 3840px; $default-design-height: 2160px; // 根據螢幕解析度調整的寬度和高度 $designWidth: $default-design-width; $designHeight: $default-design-height; // px 轉為 vw 的函式 @function vw($px) { @return math.div($px, $designWidth) * 100vw; } // px 轉為 vh 的函式 @function vh($px) { @return math.div($px, $designHeight) * 100vh; } // 根據螢幕解析度調整設計稿尺寸 @media (max-width: 3840px) and (max-height: 2160px) { $designWidth: 3840px; $designHeight: 2160px; } @media (max-width: 2560px) and (max-height: 1440px) { $designWidth: 2560px; $designHeight: 1440px; } @media (max-width: 1920px) and (max-height: 1080px) { $designWidth: 1920px; $designHeight: 1080px; } @media (max-width: 1366px) and (max-height: 768px) { $designWidth: 1366px; $designHeight: 768px; } body{ width: 100vw; height: 100vh; background-color: #000000; box-sizing: border-box; overflow-x: hidden; font-family: "AlibabaPuHuiTi-Regular"; } ...
設計師給我的稿子是按照4k顯示屏開發的,所有的寬高都是按照3840px*2160px來計算的,所以這裏給了一個預設的寬高,然後根據螢幕的自適應等比計算。
比如:
<style scoped> .grid { display: grid; grid-template-columns: vw(320px) vw(455px); grid-template-rows: repeat(2,vh(120px)); gap: vw(15px); margin-left: vw(20px); .grid-item { width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: right; padding: vh(9px) vw(20px) ; } } ... </style>
這裏設計稿給到的寬320px高120px,這邊用vw(320px),vh(120px)
去等比計算,省去了很多麻煩,跟著設計稿畫頁面就完事了。
炫酷效果
無縫滾動
然後裡面很多動效,比如常用的表格輪博滾動,vue3-seamless-scroll
來實現,Vue3.0 無縫滾動元件,支援Vite2.0,支援服務端打包
引入地圖,城市打點標記
html頁面引入
<script src="//api.map.baidu.com/api?type=webgl&v=2.0&ak=xxxxxxxxxxxxx"></script>
業務程式碼使用
<template> <div id="mapMark"></div> </template> <script setup> import {ref,reactive, watch,onMounted} from 'vue'; const initMap = async (city,markList) => { let Bmap = window.BMapGL var b = new Bmap.Map("mapMark") b.setMapStyleV2({ styleId: '1e3322xxxxxxxxxxxxxxx287b' //這裏是百度開發平臺的樣式生成的id }); // b.centerAndZoom(new Bmap.Point(104.328743,32.917728), 6.6) // b.setTilt(40); b.enableScrollWheelZoom(true) if(markList && markList.length > 0){ markList.forEach(async (item,index)=>{ const loc = await getLocationByCityName(item + '市','中國'); const marker= addIconByCity(loc); b.addOverlay(marker); }) } const loc = await getLocationByCityName( '蘭州市','中國'); b.centerAndZoom(new Bmap.Point(loc.lng, loc.lat), 7); b.setTilt(10); } const getLocationByCityName = (city,country)=>{ return new Promise((resolve, reject) => { let location = {}; let Bmap = window.BMapGL; var b = new Bmap.Geocoder(); b.getPoint(city + country, (res) => { if (res) { location.lat = res.lat; location.lng = res.lng; resolve(location); } else { reject({}); } }); }); } const addIconByCity = (location)=>{ let Bmap = window.BMapGL; const pic = require('../images/mark.png'); var icon = new Bmap.Icon(pic, new Bmap.Size(52, 52),{ anchor: new Bmap.Size(30, 50), }); const cityPoint = new Bmap.Point(location.lng, location.lat); var marker = new Bmap.Marker(cityPoint); marker.setIcon(icon); return marker } onMounted(()=>{ const markList = ['北京','上海','無錫','廈門','成都','成都'] initMap('成都',markList); }); </script> <style scoped> .mapMark{ width: 100vw; height: 100vh; position: absolute; left: 0; top:0; z-index: 1; background-color: #000000; } </style>
echarts自適應
其它各種賊啦炫酷的圖表樣式用的是echarts,然後在js程式碼中調整自適應
const systemStaionEcharts = (data,total) => { try { const myChart = echarts.init(document.getElementById("pieEcharts")); window.addEventListener("resize", () => { myChart.resize(); }, false); const option = pieEchartsOptions(data,total); myChart.setOption(option); } catch (e) { console.error(e) } }
這裏也需要用js去動態計算echarts的細節樣式,這裏寫了一個utils.js工具函式
// 預設設計稿的寬度和高度 var defaultDesignWidth = 3840; var defaultDesignHeight = 2160; /** * 根據螢幕解析度計算調整後的寬度,保持16:9比例 * @param {number} designWidth - 設計稿的寬度 * @returns {number} 調整後的寬度 */ function calculateWidth(designWidth) { // 獲取當前螢幕的寬度 const screenWidth = window.innerWidth; const widthRatio = screenWidth / defaultDesignWidth; // 計算調整後的寬度 const scaledWidth = designWidth * widthRatio; return scaledWidth; } /** * 根據螢幕解析度計算調整後的高度,保持16:9比例 * @param {number} designHeight - 設計稿的高度 * @returns {number} 調整後的高度 */ function calculateHeight(designHeight) { // 獲取當前螢幕的寬度 const screenHeight = window.innerHeight; const heightRatio = screenHeight / defaultDesignHeight; // 計算調整後的高度 const scaledHeight = designHeight * heightRatio; return scaledHeight; } export { calculateWidth, calculateHeight }
然後在檔案中引入函式,使用calculateWidth, calculateHeight
去計算細節
import { calculateWidth, calculateHeight} from '../utils/scaleSizeToScreen'; export const pieEchartsOptions = () => { return { title: { subtext: '系統部署', textStyle: { fontSize: calculateWidth(49), }, subtextStyle: { fontSize: calculateWidth(18), }, }, ... } }
最後,大屏考慮到效能,還有很多地方做了一下最佳化,比如爲了保證頁面的穩定性,自己提前引入了一份靜態資料檔案供頁面渲染,減少介面請求的等待依賴,然後介面響應後再去動態調整。再比如實時資料用webSocket型別介面,然後多寫一些try catch
防止髒資料渲染出現問題,能夠及時定位問題所在。還有圖片格式,要跟設計師保持溝通,在不影響美觀的情況下能有多小壓縮到多小,用小體積的檔案格式等等,最後把http1.1升級帶http2就完事了。