设备像素比+图片高清显示+移动适配
程序员文章站
2022-06-30 15:06:07
一、设备像素比 dpr (devicePixelRatio) 首先进行概念的一些解释: 1、物理像素(又称硬件像素)(physical pixel) 一个物理像素是显示器上最小的物理显示单元,每一个像素都有自己的颜色值和亮度。 同一个设备,它的物理像素是固定的,即一个设备的分辨率是固定的。 //计算 ......
一、设备像素比 dpr (devicePixelRatio)
首先进行概念的一些解释:
1、物理像素(又称硬件像素)(physical pixel)
一个物理像素是显示器上最小的物理显示单元,每一个像素都有自己的颜色值和亮度。
同一个设备,它的物理像素是固定的,即一个设备的分辨率是固定的。
//计算公式:
//物理像素 = 逻辑像素 × 设备像素比
2、逻辑像素 dpi (又称css像素、设备独立像素)(density-independent pixel)
逻辑像素是指css样式中使用的逻辑像素,也可以说是设备的宽高。
iphone4之前的手机逻辑像素数和逻辑像素数是相等的,但是由于视网膜设备(Retina屏)的出现,逻辑像素与物理像素之间有了不同的倍数对等关系。
//获取方法
document.documentElement.clientWidth //iphone6 => 320
document.documentElement.clientHeight //iphone6 => 667
3、设备像素比 dpr (devicePixelRatio)
设备像素比 = 物理像素 / 逻辑像素
//js获取方法
window.devicePixelRadio //iphone6 =>2
注意点:
(1)在fireFox及ie中不支持window.devicePixelRatio
(2)在同一设备不同浏览器中,window.devicePixelRatio值可能不同,这是由于不同的浏览器中css像素数不同
4、像素密度 ppi (pixels per inch)
每英寸中显示的像素数,通常使用ppi来作为像素密度的单位;计算公式: 对角线像素个数 / 屏幕尺寸
对角线像素个数计算:(物理像素长² + 物理像素宽²)开根
不同手机物理像素、逻辑像素及像素比:
手机名称
|
像素分辨率(px)
|
倍率
|
逻辑分辨率(pt)
|
物理尺寸(英寸)
|
屏幕密度(ppi)
|
DPI
|
i6 plus
|
1242*2208
|
@3x
|
414*736
|
5.5
|
401
|
154
|
I6
|
750*1334
|
@2x
|
375*667
|
4.7
|
330
|
163
|
I5s
|
640*1136
|
@2x
|
320*568
|
4
|
330
|
163
|
I5
|
640*1136
|
@2x
|
320*568
|
4
|
330
|
163
|
I4
|
640*960
|
@2x
|
320*480
|
3.5
|
330
|
163
|
I3GS
|
320*480
|
@1x
|
320*480
|
3.5
|
163
|
|
android
|
240*320
|
@0.75
|
320*420
|
120
|
||
android
|
320*480
|
@1x
|
320*480
|
160
|
||
android
|
480*800
|
@1.5x
|
360*500
|
240
|
||
android
|
640*960
|
@2x
|
320*480
|
320
|
||
android
|
540*960
|
@1.5x
|
360*640
|
360
|
||
android
|
720*1280
|
@2x
|
360*640
|
360
|
||
android
|
1080*1920
|
@3x
|
360*640
|
360
|
|
|
综合以上几个概念,以Iphone6举例说明:设备宽高(即逻辑像素)为:375×667 ,dpr为2,物理像素为 750×1334
//css样式
width:1px;
height:1px;
相同尺寸下,普通屏幕 VS Retina 屏,css像素所呈现的物理尺寸(大小)是一致的,不同的是一个css像素所对应的物理像素的个数不一致:
普通屏幕:css像素:物理像素 = 1:1
retina屏: css像素:物理像素 = 1:4
即4个物理像素显示一个css像素;
二、图片高清显示
首先了解一下图片的显示规则:
位图像素:一个位图像素是栅格图像最小的数据单元。每个位图像素都包含自身的显示信息,如色值,透明度等
理论上,当位图像素对应物理像素时,图片才能清晰展示。
例如:img标签,css像素为200*300,普通屏幕下对应物理像素为200*300,retina屏幕对应物理像素为400*600:
(1)当在retina屏中,使用200*300@1x图片时,由于每个单位的位图像素不可分割,只能就近取色,从而导致retina屏图片模糊;使用两倍图片@2x,如200*300的img标签,使用400*600的图片,这样retina屏幕下,物理像素:位图像素 = 1:1,图片清晰
(2)如果在普通屏下使用@2x图片,一个物理像素对应4个位图像素,它的取色需要一定的算法,显示结果就只有原图像素总数的4分之一(这个过程叫downsampling),图片虽然不会模糊,但是会少一些锐利度或者色差;同样会造成资源浪费
最好的解决方案:不同的dpr下,使用不同尺寸的图片。
(1)可以通过媒体查询或者js进行控制,拼接不同的url
(2)img标签,设置srcset属性
//srcrest以最合适的src去匹配不同屏幕(高分屏低分屏如Retina;大屏小屏)
// 2x、3x 表示目标屏幕的像素密度
<img src="source.jpg" srcset="source_2x.jpg 2x, source_3x.jpg 3x">
//400w、600w表示目标浏览器的宽度的限度,如浏览器宽度550w时,匹配600w的src
<img src="source.jpg" width="100%" srcset="source_400.jpg 400w, source_600.jpg 600w, source_1280.jpg 1280w">
二、移动端适配之rem
适配前提:
<meta name="viewport" content="initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width">
设配原理:使用rem单位进行移动端布局适配,原理是针对不同手机屏幕尺寸和dpr动态的改变根节点html的font-size大小
1、js方法实现
(1)引入flexible.js,改变根元素font-size
;(function(win, lib) {
var doc = win.document;
var docEl = doc.documentElement;
var metaEl = doc.querySelector('meta[name="viewport"]');
var flexibleEl = doc.querySelector('meta[name="flexible"]');
var dpr = 0;
var scale = 0;
var tid;
var flexible = lib.flexible || (lib.flexible = {});
if (metaEl) {
console.warn('将根据已有的meta标签来设置缩放比例');
var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
if (match) {
scale = parseFloat(match[1]);
dpr = parseInt(1 / scale);
}
} else if (flexibleEl) {
var content = flexibleEl.getAttribute('content');
if (content) {
var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
if (initialDpr) {
dpr = parseFloat(initialDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
if (maximumDpr) {
dpr = parseFloat(maximumDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
}
}
if (!dpr && !scale) {
var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他设备下,仍旧使用1倍的方案
dpr = 1;
}
scale = 1 / dpr;
}
docEl.setAttribute('data-dpr', dpr);
window.dpr = dpr;
if (!metaEl) {
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(metaEl);
} else
赞 (0)
打赏
微信扫一扫
相关文章:
-
-
Mysql-ALTER TABLE命令学习[20180503]
学习ALTER TABLE删除、添加和修改字段和类型 CREATE TABLE alter_tab01( id int, col01 char(20... [阅读全文] -
数据库的操作 a) 创建数据库:create database 库名[库选项]; b) 查看数据库:show databases... [阅读全文]
-
博主使用为activiti5.22的版本。 1、创建maven工程。 2、在pom文件中引入所需要的包,如:activiti包、数据库包。 这是我引... [阅读全文]
-
一、MySQL简介 1、什么是数据库 ? 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今六十多年前,随着信息技术... [阅读全文]
-
文章目录: 1,授权认证与微服务架构;2,“授权\认证\资源”独立服务的OAuth2.0架构;3,PWMIS OAuth2.0 方案;4,PWMIS... [阅读全文]
-
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论