自适应不成功的表现:
作为一个css相对单位,其相对计算的对象不固定(并不是所有元素都相对于父元素宽高),会造成计算的复杂性
按照占据视宽(高)比例设计
vw/vh缺陷
一些图表的自适应方式需要特别处理
css 相对单位,相对于根元素的 font-size 值的大小
将设计稿的单位转化为rem单位就可以实现等比例的自适应缩放
随窗口变化响应地调整根元素font size
;(function () {
let docEle = document.documentElement
let screenRatioByDesign = 16/9 // 相当于同时给出了宽高
function setHtmlFontSize() {
var screenRatio = docEle.clientWidth / docEle.clientHeight;
var fontSize = (
// 针对比例不对产生白边的优化
screenRatio > screenRatioByDesign
? (screenRatioByDesign / screenRatio)
: 1
) * docEle.clientWidth / 10; // 数值可根据实际换算比例调整
docEle.style.fontSize = fontSize.toFixed(3) + "px";
}
setHtmlFontSize()
window.addEventListener('resize', setHtmlFontSize)
})();
px自动转化为rem:
rem 局限性
将根元素 fontsize 作为基准,属于一种hack行为;
rem的方案对于1920及以上分辨率屏幕来说基本适用,但当切换到1366*768等小分辨率时,由于浏览器默认最小字体为12px,所以会导致文字比理想效果更大, 而echarts生成的canvas图中单位是以固定px写死的,也会出现超出画布的问题
因此衍生另一种方案: scale缩放
通过缩放可以保证字体和canvas一并完成缩放
// index.html
;(function(win){
var bodyStyle = document.createElement('style')
bodyStyle.innerHTML=`body{width:1920px; height:1080px!important;}`
document.documentElement.firstElementChild.appendChild(bodyStyle)
function refreshScale(){
let docWidth = document.documentElement.clientWidth;
let docHeight = document.documentElement.clientHeight;
var designWidth = 1920,
designHeight = 1080,
widthRatio = docWidth / designWidth,
heightRatio = docHeight / designHeight; // 缩放比例
document.body.style = `transform:scale(${widthRatio},${heightRatio});transform-origin:left top;`;
// 应对浏览器 全屏切换前后 窗口因短暂滚动条问题出现未占满情况
setTimeout(function(){
var lateWidth= document.documentElement.clientWidth,
lateHeight = document.documentElement.clientHeight;
if(lateWidth===docWidth) return;
widthRatio = lateWidth/ designWidth
heightRatio = lateHeight/ designHeight
document.body.style = "transform:scale(" + widthRatio + "," + heightRatio + ");transform-origin:left top;"
},0)
}
refreshScale()
win.addEventListener("pageshow", function (e) {
if (e.persisted) { // 浏览器后退的时候重新计算
refreshScale()
}
}, false);
win.addEventListener("resize", refreshScale, false);
})(window)
自己封装 Vue 组件
第三方 Vue 组件 v-scale-screen
scale() 的弊端:在比例不对的情况下,画面可能会被压缩
postcss-px-to-viewport -- vw
postcss-px-to-viewport -- rem
dpr 物理像素 与 设备像素比
rem + vw(网易移动端做法)
vw表示根元素font size, 随后采用rem
lib-flexible 前淘宝做法 viewport被广泛支持后此法已被放弃
echarts 可封装 fontSize 来转换数据
function fontSize(res) {
let docEl = document.documentElement,
clientWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
if (!clientWidth) return
let fontSize = clientWidth / 1920 // 此处 1920 为设计稿的宽度
return res * fontSize
}
使用 fontSize() 包裹 echarts 各种尺寸的原数据