目的
首先要先搞明白 大屏适配的最终的效果是什么样子的,即我们根据设计稿,按标准写出来页面后,不管是多高多宽的屏幕 都能像我们的设计稿一样的完美显示,当然这是比较理想的状态,其中有很多的问题,
分析
这里是对业务的简单的分析,首先,我们的问题应当是,我们有一张设计图,并且理所当然我们是知道设计图的尺寸的,这里就如标注的一样,宽为1920,高为1080,是常见的尺寸,我们现在准备要适配的是右侧的小窗口,暂且,将其理解为客户的小电脑,或者其他的显示设备,这里标注的宽为960,高为540,这是不是客户告诉我们的,也不是我们规定好的,而是我们通过代码得到的,相信,在js中拿到当前设备的宽高不是难事,那么,我们就很容易得到客户的设备宽高,就像我标注960,540那么简单,
现在我们的设计图中有一个需要我们绘制的盒子,当然在设计稿中的所有元素,我们都是可以拿到并且可以知道他的宽高的,所以,我暂且假设,当前的设计稿中有一个宽200,高两百的盒子需要绘制,如下图所示;
图二中 右侧绿色盒子应当是我们理想中需要绘制的具有自适应属性的盒子,
那么他的宽和高,如何得到?
我们先来分析一下我们已知的条件,
- 1:设计稿的宽 —(1920)
- 2:设计稿的高 —(1080)
- 3:设计稿中盒子的宽 —(200)
- 4:设计稿中盒子的高 —(200)
- 5:当前用户的屏幕的高 --(960)
- 6:当前用户的屏幕的宽 --(540)
在分析一下需要求算的数值: - 1:当前用户屏幕中盒子的高???
- 2:当前用户屏幕中盒子的宽???
就光从一直条件的数量,和未知条件数量的对比来看,没有道理是求不出来的:
开始实现
要想保持 屏幕中元素不变形,不错位,就是保持盒子的固有的宽高比例,其他也包括外边距 内边距的长度比例的变换 还有定位时的距离缩放,至于这期间的缩放的比例,在第三张图中就给出了答案,通过简单的计算,我们知道,1920 的宽 出于960的宽 他们之间的比例是2,那么同样的在,1920的屏幕下,存在的宽200的盒子的宽度,在960屏幕下显示,也应当像当前屏幕和设计稿宽度之间的比例一样 进行缩放,即在当前条件下,960屏幕下的盒子的宽度也应该是200的一半,即宽度为100,同样的当前屏幕下盒子的高度也是设计稿盒子的一半,也是高度为100.
这样我们就得到了我们在当前用户下的盒子的尺寸。
生成方法
通过上面的步骤,我们可以得到对应设计稿中元素在当前屏幕中的尺寸大小。那么如何通过代码实现呢,(完整代码,贴在最后)
- 1:首先拿到当前用户的宽高
// 获取窗口的宽度和高度
var w = document.documentElement.clientWidth;
var h = document.documentElement.clientHeight;
- 2:定义设计稿的宽高
// -设定 设计稿的尺寸
const baseWidth = 3840
const baseHeight = 2160
- 3:定义屏幕尺寸监听事件
- 拿到当前屏幕的宽度和设计稿的宽的比例 scalew(即为缩放的宽度)
- 拿到当前屏幕的高度和设计稿的高的比例h scaleh(即为缩放的高度)
window.addEventListener("resize", watchWindowSize);
watchWindowSize()
function watchWindowSize() {
// 获取窗口的宽度和高度
var w = document.documentElement.clientWidth;
var h = document.documentElement.clientHeight;
// -拿到可视窗口的宽度 和设计稿宽度的比例
let scaleW = w / baseWidth
// -拿到可视窗口的高度 和设计稿高度的比例
let scaleH = h / baseHeight
}
在css中使用缩放比例
:root {
--scaleWidth: 1,
--scaleHeight:1,
}
在css中如何才能使用到我们在js中得到的高的缩放比例,宽的缩放比例,这是其中比较重要的,如果没有这一步的话,前面的工作可以说白费力气,首先我们在css中定义了两个全局的变量,一个是缩放的高度,scaleWidth,一个是缩放的宽度:scaleHeight,这个两个值默认下是1,即不进行缩放,
.weather {
width: calc(200px * var(--scaleWidth));
height: calc(200px * var(--scaleHeight));
display: inline-block;
position: absolute;
right: calc(20px * var(--scaleWidth));
top: calc(20px * var(--scaleHeight));
bottom:calc(20px * var(--scaleHeight));
left:cale(20px * var(--scaleWidth));
}
上面是一个案例,是在css样式中使用,声明的全局样式,进行属性值的计算,其中的高200,宽200,都是设计稿中的尺寸,这个方法的优点在于,我们不需要再进行单位和尺寸的转换,完全可以按照设计稿的尺寸走,这能省下不少事情;
光是这样也不能完成适配,还需要一步,因为现在的–scaleWidth,–scaleHeight 是一个固定的值,如果我们将他设置成我们在js中得到的缩放比例的值,那么我们不就可以完成适配了嘛,
所以我们还需要再js中获取到 --scaleWidth --scaleHeight,
// -拿到全局css变量
var root = document.querySelector(":root")
// var width = getComputedStyle(root).getPropertyValue("--scaleWidth")
// var height = getComputedStyle(root).getPropertyValue("--scaleHeight")
//设置
root.style.setProperty("--scaleWidth", scaleW)
root.style.setProperty("--scaleHeight", scaleH)
将得到的scaleW,赋值给 --scaleWidth
将得到的scaleH,赋值给 --scaleHeight
结束:
至此,通过这样的方法 ,就可以完成屏幕的适配
// -屏幕自适应 --html部分
// -设定 设计稿的尺寸
const baseWidth = 3840
const baseHeight = 2160
// -监听窗口的变化 进行适应
window.addEventListener("resize", watchWindowSize);
watchWindowSize()
function watchWindowSize() {
// 获取窗口的宽度和高度
var w = document.documentElement.clientWidth;
var h = document.documentElement.clientHeight;
// -拿到可视窗口的宽度 和设计稿宽度的比例
let scaleW = w / baseWidth
// -拿到可视窗口的高度 和设计稿高度的比例
let scaleH = h / baseHeight
// -拿到全局css变量
var root = document.querySelector(":root")
// var width = getComputedStyle(root).getPropertyValue("--scaleWidth")
// var height = getComputedStyle(root).getPropertyValue("--scaleHeight")
//设置
root.style.setProperty("--scaleWidth", scaleW)
root.style.setProperty("--scaleHeight", scaleH)
}
//css部分
:root {
--scaleWidth: 1,
--scaleHeight:1,
}