关于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 相关文章推荐
基于CSS3实现的几个小loading效果
Sep 27 HTML / CSS
css3隔行变换色实现示例
Feb 19 HTML / CSS
纯CSS3实现8组超炫酷鼠标滑过图片动画
Mar 16 HTML / CSS
CSS3制作缩略图的详细过程
Jul 08 HTML / CSS
CSS3中animation实现流光按钮效果
Dec 21 HTML / CSS
详解HTML5表单新增属性
Dec 21 HTML / CSS
HTML5中Localstorage的使用教程
Jul 09 HTML / CSS
移动端HTML5实现文件上传功能【附代码】
Mar 25 HTML / CSS
html5唤醒APP小记
Mar 27 HTML / CSS
AmazeUI图片轮播效果的示例代码
Aug 20 HTML / CSS
使用CSS实现小三角边框原理解析
Nov 07 HTML / CSS
css之clearfix的用法深入理解(必看篇)
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
openPNE常用方法分享
2011/11/29 PHP
PHP面向对象之工作单元(实例讲解)
2017/06/26 PHP
PHP的RSA加密解密方法以及开发接口使用
2018/02/11 PHP
解决tp5在nginx下修改配置访问的问题
2019/10/16 PHP
javascript中的delete使用详解
2013/04/11 Javascript
JS实现超精简的链接列表在固定区域内滚动效果代码
2015/11/04 Javascript
js实现下拉列表选中某个值的方法(3种方法)
2015/12/17 Javascript
微信小程序 LOL 英雄介绍开发实例
2016/09/30 Javascript
原生Javascript和jQuery做轮播图简单例子
2016/10/11 Javascript
Vue源码学习之初始化模块init.js解析
2017/11/02 Javascript
react-native使用leanclound消息推送的方法
2018/08/06 Javascript
基于JavaScript实现每日签到打卡轨迹功能
2018/11/29 Javascript
echarts实现词云自定义形状的示例代码
2019/02/20 Javascript
详解Vue底部导航栏组件
2019/05/02 Javascript
vue的列表交错过渡实现代码示例
2019/05/05 Javascript
JS回调函数 callback的理解与使用案例分析
2019/09/09 Javascript
vue基本使用--refs获取组件或元素的实例
2019/11/07 Javascript
vue.js实现h5机器人聊天(测试版)
2020/07/16 Javascript
基于python时间处理方法(详解)
2017/08/14 Python
浅谈python日志的配置文件路径问题
2018/04/28 Python
python顺序的读取文件夹下名称有序的文件方法
2018/07/11 Python
Python实现的建造者模式示例
2018/08/06 Python
Python爬虫之正则表达式的使用教程详解
2018/10/25 Python
在python中以相同顺序shuffle两个list的方法
2018/12/13 Python
python3+selenium实现qq邮箱登陆并发送邮件功能
2019/01/23 Python
Python实现数据结构线性链表(单链表)算法示例
2019/05/04 Python
解决Keyerror ''acc'' KeyError: ''val_acc''问题
2020/06/18 Python
高品质和独特的产品世界:Creations and Collections
2018/01/07 全球购物
德国户外商店:eXXpozed
2020/07/25 全球购物
能否解释一下XSS cookie盗窃是什么意思
2012/06/02 面试题
爱护公共设施演讲稿
2014/09/13 职场文书
一般党员对照检查材料
2014/09/24 职场文书
幼儿园大班见习报告
2014/10/31 职场文书
2016关于预防职务犯罪的心得体会
2016/01/21 职场文书
CSS预处理框架——Stylus
2021/04/21 HTML / CSS
面试分析分布式架构Redis热点key大Value解决方案
2022/03/13 Redis