转:关于canvas在retina屏下绘制文字或图像模糊的解决方案

一、问题描述

最近在鼓捣canvas的时候,发现绘制在canvas上的文字(或图片)在retina屏幕上会出现显示模糊的问题,感觉很不爽,于是就Google了一番,还真发现了一个解决方案。有兴趣的同学可以去读一下原文,我在这里简单的记录一下。

先看一下Deom页面,对比一下前后两个效果,请务必在配有retina屏幕的设备上浏览(iOS6下的safari除外)。否则是看不到效果的。

二、问题分析

熟悉retina屏的同学应该都知道,在浏览器的window变量中有一个devicePixelRatio的属性,该属性决定了浏览器会用几个(通常是2个)像素点来渲染1个像素,举例来说,假设devicePixelRatio的值为2,一张100x100像素大小的图片,在retina屏幕下,会用2个像素点的宽度去渲染图片的1个像素点,因此该图片在retina屏幕上实际会占据200x200像素的空间,相当于图片被放大了一倍,因此图片会变得模糊。

知道了这一点,关于canvas的问题也就容易理解了。我们可以把canvas当成是一张图片,当浏览器去渲染canvas的时候,他会用2个像素点的宽度去渲染canvas,因此在大多数retina设备的浏览器中会出现绘制的图片或文字变模糊的情况。

请注意,我说的是大多数,难道还有例外?

没错,在iOS6下的safari会正常显示。

看来,我们需要再往深了刨。

在window中有一个devicePixelRatio的属性,类似的,在canvas context中也存在一个webkitBackingStorePixelRatio的属性(仅safari和chrome),该属性的值决定了浏览器在渲染canvas之前会用几个像素来来存储画布信息。在iOS6下的safari中的值是2,因此,如果将一张100x100像素的图片绘制到safari中,该图片首先会在内存中生成一张200x200的图片,然后浏览器渲染的时候,会按100x100的图片来渲染,因此就变成了200x200,正好和内存中的图片大小一致,因此在iOS的safari中不会出现失真的问题。但是在chrome和iOS7的safari中却出现了失真,其原因是,chrome和iOS7中的safari的webkitBackingStorePixelRatio值都是1。值得一提的是在iOS7中,苹果把webkitBackingStorePixelRatio的值置为了1,目的是处于性能的考虑,这一点在WWDC 2013中找到,感兴趣的同学可以异步What’s New in Safari and WebKit for Web Developers,搜索关键字‘backing’。

三、如何解决

扯了半天,还没有说怎么解决呢。其实方案很简单,也很容易明白。我们可以创建一个两倍于实际大小的canvas,然后用css样式把canvas限定在实际的大小。具体实现方法可以参看我Demo中的代码,或者直接使用github上的这个polyfill

转:devicePixelRatio和webkitBackingStorePixelRatio的更多相关文章

  1. devicePixelRatio 那些事儿

    devicePixelRatio 那些事儿 设备像素比 window.devicePixelRatio 是设备上物理像素和设备独立像素的比例,即公式表示为:window.devicePixelRati ...

  2. 设备像素比devicePixelRatio简单介绍

    本文所说devicePixelRatio其实指的是window.devicePixelRatio, 被所有WebKit浏览器以及Opera所支持,随着显示器的发展,这个属性也慢慢登上了前端技术的舞台. ...

  3. TypeError: The CanvasRenderingContext2D.webkitBackingStorePixelRatio getter can only be used on instances of CanvasRenderingContext2D

    ios10: CanvasRenderingContext2D.prototype.webkitBackingStorePixelRatio 报异常

  4. 深入理解移动web开发之PPI,Pixel,DevicePixelRatio(转)

    如果你是一个开始接触移动Web开发的前端工程师,那么你或许也遇到了和我曾经遇到的过问题:有太多新的概念需要掌握,太多相似的概念需要区分.没关系,我将用两篇文章的篇幅来解决这些问题.上篇文章关于解释和区 ...

  5. devicePixelRatio

    devicePixelRatio window.devicePixelRatio是设备上物理像素和逻辑像素的比例.公式表示就是:window.devicePixelRatio = 物理像素 / 逻辑像 ...

  6. 常见手机的设备分辨率、viewport和devicePixelRatio

    常见手机的设备分辨率和viewport分辨率,及其1rem的大小(以vmin为单位) 常见的devicePixelRatio是1, 1.325, 1.5, 2, 2.4, 3.  (具体见下面的表格, ...

  7. web移动端,需要清楚设备像素比devicePixelRatio的应用

    我们这里所说的devicePixelRatio其实指的是window.devicePixelRatio, 被所有WebKit浏览器以及Opera所支持. 概念 devicePixelRatio ,它是 ...

  8. devicePixelRatio手机图片模糊的原因

    一.移动设备图片模糊问题 手机上图片模糊问题原因就是一个像素在电脑上和手机上代表的实际像素的不同. 我们在样式表中使用的px(独立像素)单位其实并不一定代表着实际的一个像素(物理像素),这还要看硬件的 ...

  9. 移动前端开发之viewport,devicePixelRatio的深入理解

    移动前端开发之viewport的深入理解 在移动设备上进行网页的重构或开发,首先得搞明白的就是移动设备上的viewport了,只有明白了viewport的概念以及弄清楚了跟viewport有关的met ...

随机推荐

  1. List与数组的相互转换

    1.从string[]转List<string> string[] str={“1”,”2”}; List <string> list=new List<string&g ...

  2. Java中的正则表达式Pattern与Matcher

    一般来说比起功能有限的String类,我们更愿意构造功能强大的正则表达式.我们可以通过Pattern 与 Matcher 来构建功能强大的正则表达式 import java.io.File; impo ...

  3. Codeforces Round #303 (Div. 2)E. Paths and Trees 最短路

    E. Paths and Trees time limit per test 3 seconds memory limit per test 256 megabytes input standard ...

  4. c++ 在指定长度的数组或者容器中,统计元素出现的次数(count)

    #include <iostream> // cout #include <algorithm> // count #include <vector> // vec ...

  5. bootstrap3显示5列的方法

    bootstrap是个12栅格的系统,显示5列比较麻烦,今天用到到网上找了找方法,尝试成功,记录一下,以后好用. 需要自己再添加几个 css class样式: <style> .col-l ...

  6. C#快速生成数据数组

    需求:生成一个数组,数组里面的值为1-100实现方式:拿到这个需求很多朋友可能会想到一个快速实现的方式如下: ]; ;i<=;i++){ arr[i]=i; } 但是C#提供了一个快速生成的方式 ...

  7. spring boot 启动报错(spring-boot-devtools热部署后):The elements [spring.resources.cache-period] were left unbound. Update your application's configuration

    详细错误代码: *************************** APPLICATION FAILED TO START *************************** Descript ...

  8. [转] jquery $.ajax/$(document).ready is not a function的问题

    下午完成了一个模块功能的开发,本来测试好的jquery表单验证怎么也出不来了.打开firebug,看到控制台里赫然提示:$(document).ready is not a function.感觉怪怪 ...

  9. mysql--------大数据量分页sql语句优化

    分页程序原理很简单,这里就不多说了,本篇文章主要说的是在数据表记录量比较大的情况下,如何将分页SQL做到更优化,让MySQL执行的更快的方法. 一般的情况下,我们的分页SQL语句是这样的: ,; 以上 ...

  10. js获取表格视图所选行号的ids

    实例化数组 遍历所选行push到数组中 将数组join转换为以,分割的字符串 /*获取指定id的datagrid的表格视图的选择的ids*/ function getDataGridSelectRow ...