转:devicePixelRatio和webkitBackingStorePixelRatio

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

1、问题描述

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

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

2、问题分析

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

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

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

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

看来,咱们须要再往深了刨。github

在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’。web

3、如何解决

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

相关文章
相关标签/搜索