关于canvas绘制模糊问题的解决方法


Posted in HTML / CSS onSeptember 24, 2019

模糊原因

首先,需要理解canvas的展示机制。

<canvas id="map" width="375" height="667"></canvas>

我绘制了一张375px的canvas,iphone6的宽度也是375px,ok,canvas铺满了整个屏幕。

那么canvas的大小就是375px,canvas类似于图片,一张375px的图片,我们就把它当做是图片来看就好了。我,尖沙咀段坤说的。

如果遇到了屏幕宽度400px的手机,那么图片会 拉伸,canvas也会拉伸,拉伸则必然会模糊。

那么iphone6确实是375px宽度的手机,还是会出现模糊问题,为什么呢?手机端会存在高清屏的问题。也就是我们说的2倍屏或者3倍屏,也叫作屏幕的DPI。高清屏在绘制界面时,会把2px的宽度渲染成1px,也就达到了高清的效果。也就是说,我们在高清屏下看到的375px其实是750个像素点绘制出来的,canvas其实是375px被拉伸到了750px再展示出来的,拉伸则必然会模糊。

好了,模糊的原因知道了,其实就是高清屏所带来的麻烦,怎么解决呢?

解决方法

如果是2倍屏,我们把设计图上375px的canvas画成750px不就解决了?

设置canvas样式

这里我们不写width和height,而直接写style。把它看成是图片,我们先不管图片原宽高是多少,不管拉伸还是压缩,直接让他铺满整个屏幕。style里写的宽高不是图片的原宽高,也就是style里写的宽高并不是canvas的真实宽高

<canvas id="map" style="width: 375px;height:330px;"></canvas>

设置canvas宽高

上面的style并不是canvas的真实宽高,那么我们如何设置它的宽高呢?

普通屏,2倍屏,3倍屏如果分别适配?

<canvas id="map" style="width: 375px;height:330px;"></canvas>

<script>
let canvas = document.querySelector('#map');
// 获取到屏幕倒是是几倍屏。
let getPixelRatio = function(context) {
  var backingStore = context.backingStorePixelRatio ||
    context.webkitBackingStorePixelRatio ||
    context.mozBackingStorePixelRatio ||
    context.msBackingStorePixelRatio ||
    context.oBackingStorePixelRatio ||
    context.backingStorePixelRatio || 1;
   return (window.devicePixelRatio || 1) / backingStore;
};
 // iphone6下得到是2 
const pixelRatio = getPixelRatio(canvas);
// 设置canvas的真实宽高
canvas.width = pixelRatio * canvas.offsetWidth; // 想当于 2 * 375 = 750 
canvas.height = pixelRatio * canvas.offsetHeight;
</script>

那么canvas的宽高就变成了下图这样,750宽度的canvas,如果你是2倍屏我就刚好能够适应!!!

关于canvas绘制模糊问题的解决方法

设置后的宽高

开始画点

比如,375的设计图上,有一个半径为2px的圆点,点的位置是x:100,y:100。

那么我们现在canvas的宽度是750,宽高变成了之前的2倍。为了视觉上位置保持不变,我们画点的位置就应该是x:100*pixelRatio,y:100*pixelRatio。

完整代码如下:

<canvas id="map" style="width: 375px;height:330px;"></canvas>

<script>
let canvas = document.querySelector('#map');
// 获取到屏幕倒是是几倍屏。
let getPixelRatio = function(context) {
  var backingStore = context.backingStorePixelRatio ||
    context.webkitBackingStorePixelRatio ||
    context.mozBackingStorePixelRatio ||
    context.msBackingStorePixelRatio ||
    context.oBackingStorePixelRatio ||
    context.backingStorePixelRatio || 1;
   return (window.devicePixelRatio || 1) / backingStore;
};
 // iphone6下得到是2 
const pixelRatio = getPixelRatio(canvas);
// 设置canvas的真实宽高
canvas.width = pixelRatio * canvas.offsetWidth; // 想当于 2 * 375 = 750 
canvas.height = pixelRatio * canvas.offsetHeight;

// 开始画点
let ctx = canvas.getContext("2d");
ctx.beginPath();
 // 375设计图上的位置和尺寸都应该*pixelRatio 因为我们现在的canvas是750
ctx.arc(100*pixelRatio, 100*pixelRatio, 2*pixelRatio, 0, 2 * Math.PI);
ctx.fillStyle = "#fff";
ctx.fill();
ctx.closePath();

// ...你的其他代码
</script>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
分享一个页面平滑滚动小技巧(推荐)
Oct 23 HTML / CSS
Html5内唤醒百度、高德APP的实现示例
May 20 HTML / CSS
Html5 语法与规则简要概述
Jul 29 HTML / CSS
HTML5中meta属性的使用方法
Feb 29 HTML / CSS
详解HTML5 Canvas绘制不规则图形时的非零环绕原则
Mar 21 HTML / CSS
html5 input输入实时检测以及延时优化
Jul 18 HTML / CSS
Html5 Canvas动画基础碰撞检测的实现
Dec 06 HTML / CSS
three.js模拟实现太阳系行星体系功能
Sep 03 HTML / CSS
video实现有声音自动播放的实现方法
May 20 HTML / CSS
使用HTML和CSS实现的标签云效果(附demo)
Feb 03 HTML / CSS
详解CSS3.0(Cascading Style Sheet) 层叠级联样式表
Jul 16 HTML / CSS
浅谈css清除浮动(clearfix和clear)的用法
May 21 HTML / CSS
html svg生成环形进度条的实现方法
Sep 23 #HTML / CSS
html2 canvas生成清晰的图片实现打印功能
Sep 23 #HTML / CSS
将SVG图引入到HTML页面的实现
Sep 20 #HTML / CSS
解析浏览器的一些“滚动”行为鉴赏
Sep 16 #HTML / CSS
html5移动端价格输入键盘的实现
Sep 16 #HTML / CSS
canvas生成带二维码海报的踩坑记录
Sep 11 #HTML / CSS
html5写一个BUI折叠菜单插件的实现方法
Sep 11 #HTML / CSS
You might like
PHP+JS+rsa数据加密传输实现代码
2011/03/23 PHP
Yii使用ajax验证显示错误messagebox的解决方法
2014/12/03 PHP
PHP邮件群发机实现代码
2016/02/16 PHP
JS与C#编码解码
2013/12/03 Javascript
javascript 动态创建表格
2015/01/08 Javascript
JavaScript操作HTML DOM节点的基础教程
2016/03/11 Javascript
JavaScript实现in-place思想的快速排序方法
2016/08/07 Javascript
微信小程序  网络请求API详解
2016/10/25 Javascript
利用JS实现简单的瀑布流加载图片效果
2017/04/22 Javascript
javaScript 逻辑运算符使用技巧整理
2017/05/03 Javascript
JavaScript中变量、指针和引用功能与操作示例
2018/08/04 Javascript
Mint UI实现A-Z字母排序的城市选择列表
2018/12/28 Javascript
解决layer.open后laydate失效的问题
2019/09/06 Javascript
VSCode插件安装完成后的配置(常用配置)
2020/08/24 Javascript
vue离开当前页面触发的函数代码
2020/09/01 Javascript
微信小程序实现电影App导航和轮播
2020/11/30 Javascript
Python实现控制台输入密码的方法
2015/05/29 Python
Python登录并获取CSDN博客所有文章列表代码实例
2017/12/28 Python
通过cmd进入python的实例操作
2019/06/26 Python
Django实现发送邮件找回密码功能
2019/08/12 Python
Python loguru日志库之高效输出控制台日志和日志记录
2020/03/07 Python
jupyter notebook 使用过程中python莫名崩溃的原因及解决方式
2020/04/10 Python
Python实现手绘图效果实例分享
2020/07/22 Python
Python urllib库如何添加headers过程解析
2020/10/05 Python
法国体育用品商店:GO Sport
2019/10/23 全球购物
会计岗位职责
2013/11/08 职场文书
竞选班干部演讲稿300字
2014/08/20 职场文书
2015年档案管理工作总结
2015/04/08 职场文书
毕业论文答辩开场白
2015/05/27 职场文书
堂吉诃德读书笔记
2015/06/30 职场文书
大学生自我鉴定怎么写
2019/05/07 职场文书
JS数组的常用方法整理
2021/03/31 Javascript
redis限流的实际应用
2021/04/24 Redis
分析MySQL抛出异常的几种常见解决方式
2021/05/18 MySQL
Python爬虫框架之Scrapy中Spider的用法
2021/06/28 Python
JavaScript数组 几个常用方法总结
2021/11/11 Javascript