引言
大家在前端开发当中,可能或多或少都遇到过图像不清晰的问题,接下来,我们来讨论一下这个问题以及应该要怎么解决。
图片尺寸
1. 原始尺寸
首先一张图片它分为两种尺寸,第一种尺寸叫做原始尺寸(自然尺寸),在HTML 5中,新增加了两个根据图片原始大小用来判断图片的宽度和高度的属性,分别为 naturalWidth 和 naturalHeight属性,表示这张图片画出来的时候,它本身自带的尺寸。
如图,以上图片的原始尺寸为200*200。
2. 样式尺寸
另一种尺寸叫做样式尺寸,就是我们设置这个图片的style的尺寸,它表示图片展现在页面上的尺寸。
如图,以上图片的样式尺寸为150*150。
问题的产生
当我们把样式尺寸调大或者把页面放大的时候,会发现图片变得模糊了,这是因为原始尺寸和样式尺寸不相等的关系吗?我们试着把它们调成一致在放大,发现还是有点模糊。
造成此现象的原因是因为我们少考虑了一个变量——缩放倍率。
在浏览器可以通过window对象里边的一个全局属性叫 devicePixelRatio 来得到目前整个界面的缩放倍率。
目前是1.25。
如何解决
那么接下来我们就要寻找原始尺寸、样式尺寸和缩放倍率之间应该保持一种什么样的关系才能够让图片保持清晰。
跳过繁琐的证明我们直接说结论,就是原始尺寸 = 样式尺寸 * 缩放倍率
只要能够保持这个等式成立,图像无论如何都是清晰的。
回到问题的产生我们会发现,哪怕保持原始尺寸和样式尺寸相等,在考虑缩放倍率后等式就会变得不相等了,这就是图片变得模糊的根本原因。
那么如何让图片保持清晰度就显而易见了,也有多种方案,假设缩放倍率是固定的放大了2倍,在原始尺寸和样式尺寸相等的情况下,我们既可以让原始尺寸提升2倍(换图片),也可以让样式尺寸缩小2倍(调整style)从而达到保持清晰度的效果。
Canvas
以上的不仅仅在图像成立,在Canvas里边也成立,大家可能一直忽略了Canvas其实也是个图片,当我们对一个Canvas元素点击右键时会有“另存图片”,这不就说明了它本质就是一个图片嘛。
对于上述的例子,一样确定缩放倍率是固定的放大了2倍,要让图片保持清晰度我们可以调整样式尺寸为100*100,也可以调整原始尺寸为400*400。
canvas{
/* 样式尺寸 */
width: 200px;
height: 200px;
}
const cvs = document.querySelector('canvas');
const ctx = cvs.getContext('2d');
function init() {
// 原始尺寸
cvs.width = 200;
cvs.height = 200;
}
init();
// canvas内容
但这样会把它写死,并不利于我们进行维护,最好的写法就是让样式尺寸乘以这个属性的缩放倍率,这样就能适配到不同的缩放情况。
const cvs = document.querySelector('canvas');
const ctx = cvs.getContext('2d');
function init() {
// 原始尺寸
cvs.width = 200 * devicePixelRatio;
cvs.height = 200 * devicePixelRatio;
}
init();
// canvas内容
如果要让Canvas的内容在放大缩小的时候也保持清晰,我们只需在画的时候对内容的半径、宽度、高度也按照放大倍率来进行缩放就可以了。