使用Canvas繪制背景圖


原文  http://www.imququ.com/post/use-canvas-as-background-image.html

最近iCloud Web的Beta版換了UI,整體風格變得和iOS7一致了。首頁圖標下方漂浮着若干大小不一的泡泡,十分夢幻。大家可以訪問 beta.icloud.com 體驗下,如果覺得泡泡不夠多,還可以加上 crazyAwesome 參數讓泡泡變得更加瘋狂。

上面提到的泡泡效果,有許多種實現方案。本文要討論的是iCloud使用的Canvas繪制背景圖方案。這樣做的好處是,用代碼繪制背景圖,相比圖片更靈活,也更省流量。另外,不知道大家有沒留意到iCloud Web中的日歷圖標是根據當前日期和星期幾動態生成的,下面Demo中有這個圖標的實現。

canvas.toDataURL

大家知道,一般我們可以用圖片、SVG和顏色漸變來做為元素的背景圖(background-image屬性)。在Canvas中,可以通過 toDataURL() 方法,把圖像導出為 data類型的URL ,這個URL可以直接用做背景圖。下面有個簡單的例子:

<div style="width:200px;height:200px;" id="cloud">紅心是我的背景圖!</div>    
<canvas style="display:none;" id="can" width="200" height="200"></canvas>
<script>
(function() {
    var canvas = document.getElementById('can'), context;

    if(!canvas.getContext) {
        alert('你的瀏覽器不支持canvas!');
        return;
    }

    context = canvas.getContext('2d');
    context.fillStyle = 'red';
    context.beginPath();
    context.moveTo(75,40);
    context.bezierCurveTo(75,37,70,25,50,25);
    context.bezierCurveTo(20,25,20,62.5,20,62.5);
    context.bezierCurveTo(20,80,40,102,75,120);
    context.bezierCurveTo(110,102,130,80,130,62.5);
    context.bezierCurveTo(130,62.5,130,25,100,25);
    context.bezierCurveTo(85,25,75,37,75,40);
    context.fill();

    document.getElementById('cloud').style.backgroundImage = 'url("' + context.canvas.toDataURL() + '")';
})();
</script>

這是使用本方案實現的 iCloud日歷圖標 ,支持Canvas的瀏覽器都可以正常顯示。

用Canvas繪制背景圖,將Canvas強大的繪圖能力與靈活的CSS背景圖很好的結合起來,強大但不完美。例如多個元素使用同一個Canvas背景時,無論是分開設置背景圖,還是創建臨時Style,都很麻煩。如果想把一個Canvas動畫作為元素背景,需要不斷獲取DataURL再賦給元素,更加不方便。

有沒有更好的辦法可以把一個或多個html元素與Canvas綁定起來,在Canvas內容改變時自動更新html元素呢?答案是肯定的。

-webkit-canvas

對於上面的問題,Webkit提出了一個自己的實現方案:-webkit-canvas。Safari4+、Chrome4+的background-image都支持這個屬性值( caniuse ),可以方便的使用CSS Canvas作為元素的背景圖,類似這樣:

#icon1 {
    background-image: -webkit-canvas(identifier);
}

區別於在Canvas元素上繪圖,-webkit-canvas方案需要用下面的方法獲取繪圖的Context:

var context = document.getCSSCanvasContext("2d", "identifier", width, height);

創建CSS Canvas時需要指定一個標識,用它的html元素在CSS中指定這個標識就可以了。瀏覽器會自動將CSS Canvas的改變同步到所有指定了這個標識的元素上,這樣就成功解決了上面提出的問題。

具體效果可以繼續 看我寫的Demo ,Webkit Only。這里還有一個使用-webkit-canvas將Canvas動畫作為背景圖的例子, 請自備梯子查看 。

-moz-element

Mozilla有個類似的方案,叫 -moz-element 。可以指定任何元素作為另外元素的背景圖(實際上,一個元素不能指定父元素作為自己的背景,為什么自己想),Firefox4+開始支持它作為background-image的屬性值。下面是它的用法:

<button id='elementID'>this is a element.</button>
<div style='background-image:-moz-element(#elementID);width:300px;height:200px;'></div>

於是,上面的Demo在Firefox下可以改由-moz-element來實現了, 點擊查看 。由於本方案支持任何元素作為背景,所以 也可以這么玩 ,純CSS的有趣效果,Firefox Only。

最后

個人感覺Mozilla的方案略微誇張了點,相比之下Webkit的CSS Canvas更有可能成為標准。另外,iCloud對於不支持-webkit-canvas的瀏覽器使用的是DataURL方案,並沒有使用firefox的-moz-element,具體什么原因就不得而知了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM