解决 canvas 绘图在高清屏中的模糊问题
解决 canvas 绘图在高清屏中的模糊问题
为什么模糊
CSS 像素是一个抽象单位(1 px),浏览器根据某种规则将 css 像素转化为屏幕需要的实际像素值。
在高清屏之前,屏幕上显示一个像素点需要 1 x 1 个 css 像素。在高清屏,同样大小的屏幕上要显示一个点,就需要 n x 1 个 css 像素。这里的 n 就是设备像素比 devicePixelRatio >= 2.
也就是说,同样大小的区域,高清屏需要更多的 css 像素:css 像素不够,则会放大内容——变得模糊;css 像素足够,则会缩小内容——变得清晰。放大、缩小的比例由 devicePixelRatio 决定。
比如说 iPhone 4s,它的 devicePixelRatio 为 2,假设屏幕上有块区域大小为 100px x 100px,上面有张 100px x 100px大小的图片,那么这张图片会被放大 2 倍后再渲染到这块区域,所以看起来就模糊了。
canvas 绘图在高清屏中模糊
canvas 属于位图,绘制在它上面的文字、图片、线条也属于位图,经放大后就失真、显得模糊了。要解决这个问题,我们就需要 canvas 拥有更多的 css 像素,即让 canvas 足够大。多大才够呢?太大会不会浪费资源/性能?我们需要因地制宜,根据 devicePixelRatio 来决定画布的大小。
function setupCanvas(canvas) {
var dpr = window.devicePixelRatio || 1
var rect = canvas.getBoundingClientRect()
canvas.width = rect.width * dpr
canvas.height = rect.height * dpr
var ctx = canvas.getContext('2d')
ctx.scale(dpr, dpr)
return ctx
}
// 现在我们只需要根据 UI 设计图绘制需要的内容
// 由于使用了 setupCanvas,绘制的内容在各种高清屏中表现清晰、一致
var ctx = setupCanvas(document.querySelector('.my-canvas'));
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.lineTo(200, 200);
ctx.stroke();
在 setupCanvas 函数中,我们根据屏幕的 devicePixelRatio 对 canvas 画布本身进行放大,然后使用 ctx.scale() 放大 canvas 单位,这样在 ctx 上下文绘制的内容就会被放大,使得最后生成的图片清晰的显示在对应的屏幕上。
实际上,我们还要兼顾不同大小、不同分辨率的屏幕。一般设计师会给我们宽度为 375px 的设计图,这需要我们根据屏幕大小进行缩放:
function setupCanvas(canvas) {
const UI_WIDTH = 375
const DOC_WIDTH = document.documentElement.clientWidth
const DPR = window.devicePixelRatio || 1
let scale = (DPR * DOC_WIDTH / UI_WIDTH).toFIxed(2)
//let rect = canvas.getBoundingClientRect()
canvas.width = canvas.width * scale
canvas.height = canvas.height * scale
let ctx = canvas.getContext('2d')
ctx.scale(scale, scale)
return ctx
}
术语
device pixel
设备像素(又称物理像素、屏幕像素)是显示屏的最小物理单元,是我们在屏幕上能看到的最小点。
device-independent pixel
设备无关像素(又称密度无关像素,DIP)是一个抽象单位,表示计算机中的一个虚拟点,由系统转为一个设备像素点。
devicePixelRatio
设备像素比,它的值等于设备像素/设备无关像素,devicePixelRatio = DP/DIP
css pixel
css 像素是浏览器使用的抽象单位,属于设备无关像素(DIP)。我们看到的内容,是浏览器将 css 像素转化为设备像素后的结果。
矢量图
矢量图是根据几何特性来绘制图形,矢量可以是一个点或一条线,矢量图只能靠软件生成,文件占用内在空间较小,因为这种类型的图像文件包含独立的分离图像,可以自由无限制的重新组合。它的特点是放大后图像不会失真。
位图
位图图像(bitmap),亦称为点阵图像或绘制图像,是由称作像素(图片元素)的单个点组成的。当放大位图时,图像就失真、模糊了。
引用
解决 canvas 绘图在高清屏中的模糊问题的更多相关文章
- 【转】解决 canvas 在高清屏中绘制模糊的问题
来源: http://www.css88.com/archives/9297 使用 canvas 绘制图片或者是文字在 Retina 屏中会非常模糊.如图: 因为 canvas 不是矢量图,而是像图片 ...
- 【Canvas】311- 解决 canvas 在高清屏中绘制模糊的问题
点击上方"前端自习课"关注,学习起来~ 一.问题分析 使用 canvas 绘制图片或者是文字在 Retina 屏中会非常模糊.如图: 因为 canvas 不是矢量图,而是像图片一样 ...
- 解决 canvas 在高清屏中绘制模糊的问题
主要代码部分: <canvas id="my_canvas" width="540" heihgt="180"></can ...
- ArcGIS 在高清屏中主界面界面字体和图标显示过小,如何解决?
作者:安日链接:https://www.zhihu.com/question/40658050/answer/132382971来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...
- 高清屏下canvas重置尺寸引发的问题
我们知道,清空canvas画布内容有以下两个方法. 第一种方法是cearRect函数: context.cearRect(0,0,canvas.width,canvas.height) 第二种方法就是 ...
- Cocos2D瓦块地图高清屏(retina)显示比例问题的解决
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 在Cocos2D的游戏编程里,常用到瓦块地图.而cocos2D ...
- 移动端,多屏幕尺寸高清屏retina屏适配的解决方案
移动端高清.多屏适配方案 背景 开发移动端H5页面 面对不同分辨率的手机 面对不同屏幕尺寸的手机 视觉稿 在前端开发之前,视觉MM会给我们一个psd文件,称之为视觉稿. 对于移动端开发而言,为了做到页 ...
- Cocos2D iOS之旅:如何写一个敲地鼠游戏(一):高清屏显示和UIKit
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...
- 怎么在高清屏上画一条0.5px的边
怎么在高清屏上画一条0.5px的边呢?0.5px相当于高清屏物理像素的1px.这样的目的是在高清屏上看起来会更细一点,效果会更好一点,例如更细的分隔线. 理论上px的最小单位是1,但是会有几个特例,高 ...
随机推荐
- python学习 day6 (3月7日)
#__author : 'liuyang' #date : 2019/3/7 0007 a = ['a' , 'b' , 'c'] b = [] print(a is b ) # 空元组 可以 空列表 ...
- 2019.01.21 NOIP训练 ak树(点分治)
传送门 题意简述:给一棵带权树,问在上面随机选两个点距离是4的倍数的概率. 思路: 由于总方案数为定值n2n^2n2,所以只用求总方案数. 这个跟聪聪可可差不多,可以用类似树形dpdpdp的方法边点分 ...
- boost-使用format和lexical_cast实现数字和字符串之间的转换
使用boost的format可以实现数字到string的格式化转换,boost的lexical_cast可以实现string到数值的转换,eg: #include "boost/format ...
- 无法重启oracle数据库监听
一.报错 TNS-12541: TNS:no listener TNS-12560: TNS:protocol adapter error TNS-00511: No listener Linu ...
- python3 print函数的用法
1. 输出字符串 >>> strHello = 'Hello World' >>> print (strHello) Hello World 2. 格式化输出整数 ...
- ROM的一种写法
module mr_rom_pll_valuemask_8bpc #( , , , , // 6*7 // alt_clogb2(42) ) ( input wire clock, :] addr_p ...
- referraluserid推广ID号跟踪JS处理A标签
网站推广ID号跟踪 xxx.html?referraluserid=123 referraluserid.js JS源文件 referraluserid的参数会自动绑定页面A标签 有时是Post 表单 ...
- js实现百度搜索框滑动固定顶部
现在很多主流系统例如百度.有道.爱奇艺等的搜索框都有一个特点,滑动到刚好看不到搜索框时,固定搜索框到顶部,这也算是一个对用户友好型的操 作. 在看了百度的js和css后自己摸索出来实现效果,还是学艺不 ...
- C#的math类的全部运算方法
Abs 返回指定数字的绝对值.Acos 返回余弦值为指定数字的角度.Asin 返回正弦值为指定数字的角度.Atan 返回正切值为指定数字的角度.Atan2 返回正切值为两个指定数字的商的角度.BigM ...
- LoadIcon
1.LoadIcon(HINSTANCE hInstance,LPCSTR lpIconName);该函数从与 hInstance 模块相关联的可执行文件中装入lpIconName指定的图标资源,仅当 ...