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上的這個polyfill。chrome