因为canvas不是矢量图,而是像图片一样是位图模式的。如果不做Retina屏适配的话,例如二倍屏,浏览器就会以2个像素点的宽度来渲染一个像素,该canvas在Retina屏幕下相当于占据了2倍的空间,相当于图片被放大了一倍,因此图片会变模糊。

因此,要做Retina屏适配,关键是知道当前canvas的实际渲染倍率,然后将canvas放大到该倍率来绘制,最后将canvas压缩成一倍的物理大小来展示。

需要注意的是,canvas中的线条大小、文字大小等都需要乘以该倍率来进行绘制。

canvas的实际渲染倍率

在浏览器的window变量中有一个devicePixelRatio的属性,该属性表示了屏幕的设备像素比,即用几个(通常是2个)像素点宽度来渲染1个像素。

在canvas context中也存在一个 webkitBackingStorePixelRatio 的属性,该属性的值决定了浏览器在渲染canvas之前会用几个像素来来存储画布信息。在iOS6下的safari中的值是2,但是在chrome和iOS7的safari中的值却是1。在iOS6下的safari中,如果有一张100 × 100像素的图片绘制,该图片首先会在内存中生成一张200 × 200的图片,然后再浏览器渲染时会按100 × 100的图片来显示,因此不会出现模糊失真的情况。而在在chrome和iOS7的safari中就会出现模糊。

但是webkitBackingStorePixelRatio属性在各浏览器厂商的获取方式不一样,所以需要加上浏览器前缀来实现兼容。

如下:

var canvas = document.getElementById("canvas"),
        context= canvas.getContext("2d");

// 屏幕的设备像素比
var devicePixelRatio = window.devicePixelRatio || 1;

// 浏览器在渲染canvas之前存储画布信息的像素比
var backingStoreRatio = context.webkitBackingStorePixelRatio ||
                    context.mozBackingStorePixelRatio ||
                    context.msBackingStorePixelRatio ||
                    context.oBackingStorePixelRatio ||
                    context.backingStorePixelRatio || 1;

// canvas的实际渲染倍率
var ratio = devicePixelRatio / backingStoreRatio;
3.2 按实际渲染倍率来缩放canvas

先补充一个基础知识点:

要设置canvas的画布大小,使用的是canvas.width 和 canvas.height;
要设置画布的实际渲染大小,使用的style或CSS设置的 width 和height,只是简单的对画布进行缩放。
譬如:

<canvas width="640" height="800" style="width:320px; height:400px"></canvas>
canvas的实际大小的640px × 800px,但是实际渲染到页面的大小是320px × 400px,相当于缩小一倍来显示。

因此,要使canvas适配高倍屏,就是要将canvas放大到设备像素比来绘制,最后将canvas压缩成一倍的物理大小来展示。如下:

canvas.style.width = canvas.width;
canvas.style.height = canvas.height;

canvas.width = canvas.width * ratio;
canvas.height = canvas.height * ratio;

canvas中的线条大小、文字大小等都需要乘以设备像素比来进行绘制,否则高倍屏下的线条会变细几倍

canvas在高倍屏下变模糊的处理办法的更多相关文章

  1. img transform:scale 放大在ios下变模糊

    /*img标签放大再缩小*/ img { width: 400%; transform: translate3d(-50%, -50%, 0) scale(0.25, 0.25); -webkit-t ...

  2. Chrome浏览器在Windows8/8.1下显示模糊的解决办法

    刚刚换了一台新电脑,安装完Windows 8.1,屏幕分辨率被自动设置为1920 X 1080,打开Chrome浏览器却发现内容显示非常模糊,不论如何改变Chrome的设置均没有效果,开启或关闭Chr ...

  3. 【Canvas】311- 解决 canvas 在高清屏中绘制模糊的问题

    点击上方"前端自习课"关注,学习起来~ 一.问题分析 使用 canvas 绘制图片或者是文字在 Retina 屏中会非常模糊.如图: 因为 canvas 不是矢量图,而是像图片一样 ...

  4. 【转】解决 canvas 在高清屏中绘制模糊的问题

    来源: http://www.css88.com/archives/9297 使用 canvas 绘制图片或者是文字在 Retina 屏中会非常模糊.如图: 因为 canvas 不是矢量图,而是像图片 ...

  5. canvas压缩图片变模糊问题

    canvas 画图图片变模糊问题 问题描述 在使用 canvas 对图片进行编辑导出图片之后发现图片和原图相比变得模糊了 canvas 画图线条变粗 问题产生原因 该问题在 PC 下面并不会产生,原因 ...

  6. 解决 canvas 绘图在高清屏中的模糊问题

    解决 canvas 绘图在高清屏中的模糊问题 为什么模糊 CSS 像素是一个抽象单位(1 px),浏览器根据某种规则将 css 像素转化为屏幕需要的实际像素值. 在高清屏之前,屏幕上显示一个像素点需要 ...

  7. 高清屏下canvas重置尺寸引发的问题

    我们知道,清空canvas画布内容有以下两个方法. 第一种方法是cearRect函数: context.cearRect(0,0,canvas.width,canvas.height) 第二种方法就是 ...

  8. html5 Canvas画图3:1px线条模糊问题

    点击查看原文地址: html5 Canvas画图3:1px线条模糊问题 本文属于<html5 Canvas画图系列教程> 接上一篇canvas画线条教程 上次我们讲到,canvas有时候会 ...

  9. iBeacon在iPhone锁屏下有几率扫描不到蓝牙设备以及折中解决方案

    前言: 这个问题的确困扰了很久,查了国内外各种论坛.社区,都没找到一个有效的解决办法. 所幸后来用一种折中的办法解决了,但也不是从技术根本上解决的,所以有解决的兄弟还望指导下. 正文如下: 一.需求描 ...

随机推荐

  1. 四、日志输出Reporter.log

    一.Reporter.log import org.testng.Reporter; public class TestLog { public static void main(String[] a ...

  2. Linux_RHEL_设置网络

    目录 目录 Selinux Iptable NetworkManager 基本网络配置 编辑网卡子接口 ip指令 ifconfig指令 修改主机名 服务端口 Selinux 是Linux的一种权限管理 ...

  3. 十九:jinja2之set和with语句定义变量

    set jinja2模板内部可以用set定义变量,只要定义了这个变量,在后面的代码中都可以使用此变量 with 如果想让定义的变量只在部分作用域内有效,则不嫩更实用set,需使用with定义,with ...

  4. Jmeter+Ant+Jenkins接口自动化持续集成环境搭建(Linux)

    一.安装说明 系统环境:CentOS release 6.4 JDK版本:jdk1.8.0_181 Jmeter版本:apache-jmeter-3.0 Ant版本:apache-ant-1.9.13 ...

  5. 【ABAP系列】SAP ABAP 关于FUNCTION-POOL的理解

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP 关于FUNCT ...

  6. cocos2dx[3.2](5) 屏幕适配

    1.两个分辨率 1.1.窗口分辨率 在AppDelegate.cpp中有个设置窗口分辨率的函数.该函数是设置了我们预想设备的屏幕大小,也就是应用程序窗口的大小. // glView->setFr ...

  7. [转帖]站点部署,IIS配置优化指南

    站点部署,IIS配置优化指南 https://www.cnblogs.com/heyuquan/p/deploy-iis-set-performance-guide.html 挺值得学习的 毕竟之前很 ...

  8. node项目自动化部署--基于Jenkins,Docker,Github(2)配置节点

    上一篇文章中准备工作已经完成的差不多了 这一篇主要讲解 Jenkins 上面的相关配置 为了让代码部署到所有的子节点上 所以我们首先需要在 Jenkins 中添加我们希望代码部署到的节点 配置节点 首 ...

  9. Android事件监听(二)——点击鼠标事件

    Button.ImageButton事件监听(setOnClickListener) 方法一:通过匿名内部类实现 代码如下: package com.note.demo2; import androi ...

  10. mysql分表规则(转)

    author:skatetime:2013/05/14 Mysql分表准则 在大量使用mysql时,数据量大.高访问时,为了提高性能需要分表处理,简介下mysql分表的标准,后续会继续补充 环境:业务 ...