最近工作任务主要是移动端内嵌 H5 页面, 一次与原生进行像素交互下, 发现了这个天坑, 再次做个记录
天坑如下:
H5 页面中的 "像素" 与移动端设备的 "像素" 系统不一致, 对于刚接触这块的我, 曾经几时在还没有遇到过这样的情况下, 去看相关的文章一点体会也没有, 这次碰上了, 然后又重新看了一遍, 对这块的理解也能比较有感受了
先上总结: 如果有不到位的, 请告知修正:-P
理清几个概念
注意文中的英文表达, 可以帮助我们更好的理解, 因为同样的英文表达可以被翻译成不同的汉文, 这会妨碍我们再查阅资料的时候混淆名词概念
物理像素( physical pixel)
是什么?
一个物理像素是移动设备屏幕上最小的物理显示单元, 通常在设备的配置信心文件中可以查看, 例如某手机的配置信息如下:
可以得知, 该设备的物理像素为 1920x1080
屏幕像素密度(pixels per inch)
是什么?
每英寸有多少像素点, 简称 ppi. 根据上图可以知道改设备的 ppi = 401, 其实, 这个值是可以推算出来的
如何推算?
根据 ppi 公式:
套算: 这个设备的 ppi = 根号(1920^2 + 1080^2)/ 5.5 = 401ppi
设备像素比(device pixel ratio)
是什么?
定义了物理像素和设备独立像素的对应关系. 看着这个概念似乎很凌乱, 设备独立像素是啥? 对应什么关系? 在理解这个概念之前, 必要的是了解移动端的 viewPort, 在了解 viewport 之前我们需要了解三种视口
三种视口
1. 视觉视口(visual viewport)
是什么?
如何获取布局视口的宽高?
Windows.innerWidth/innerHeigt
2. 布局视口(layout viewport)
是什么?
H5 开发关注的视口, 将要再多大的视觉视口 (visual viewport) 中渲染, 不同设备的 visual viewport 不一样, 可以通过 <meta name="viewport" content="width=device-width">来设置 layout viewport 等于 visual viewport
如何获取 layout viewport 的宽高?
- document.body.clientWidth
- document.documentElement.clientHeight/clientWidth
2. 理想视口(ideal viewport)
理清了三种视口之后, 我们就可以理解 viewport 了
viewport
工作原理: 将所有 DOM 节点按照原始 CSS 逻辑像素 (平常我们写代码的 CSS 的像素大小) 会在 layout viewport 中按照 visual viewport 进行等比缩放, 避免了 DOM 重绘导致的页面凌乱问题
了解了 viewport 之后, 我们返回到的设备像素比之前了解一个名词
设备独立像素(density-independent pixel)
是什么?
设备独立像素 (也叫做密度无关像素), 简称 DIP/DP 可以认为是计算机坐标系统中的一个点, 这个点代表一个可以由程序使用的虚拟像素(比如 CSS 逻辑像素), 然后由相关系统(比如移动端的 webview) 转换为物理像素, 这就是为什么我们总是能够在移动设备上看的和我们 H5 的页面相同的展示效果, 当然, 这个转换, 设备系统会帮我们处理好的, 我们只是了解一下其中的原理, 方便理解
理解了设备独立像素之后, 我们再回过头来看设备像素比, 这里有一个公式:
设备像素比 = 物理像素 / 设备独立像素 // 在某一方向上, x 方向或者 y 方向
根据这个公式, 我们就找到了设备独立像素 DIP 和物理像素和设备像素比 DPR 之间的关联
在 H5 页面中获得到的 DPR 和移动设备或得到的 DPR 是一致的, 那么 H5 怎么获取呢?
- Windows.devicePixelRatio
- or
- -webkit-device-pixel-ratio
- -webkit-min-device-pixel-ratio
- -webkit-max-device-pixel-ratio
- // 上面两种方法取出的 dpr 的单位是 ddpx
- ddpx
是什么?
每个像素的点数
缺点:
IE 不支持 DDPX
如何解决?
使用 dpi 表示
如何?
1inch = 96px , 1ddpx = dpr * 96 = 192dpi
最后, 举个例子应用一下我们所知道的关系
某手机的物理像素为 750X1334, 其设备像素比为 2
根据公式 dpr = pp/ dip(dp)
推算出, 这台手机的设备独立像素 dp/dip = 375x 667 (750/2 x 1334/2)
用图可以这么表示
可以得出: 一个逻辑点(logic point)/ 逻辑像素需要一个或者多个的物理像素来展示, 着取决于 dpr
参考资料:
- https://github.com/kaola-fed/blog/issues/133
- https://juejin.im/post/5bc7fb9ef265da0acd20ebeb
- https://www.jianshu.com/p/76130f4d7cf9
关于转载:
文中可能有错误, 欢迎指点.
来源: https://www.cnblogs.com/timetimetime/p/10870315.html