我的家園

          我的家園

          HTML5 canvas 元素詳細(xì)教程三

          Posted on 2012-04-15 16:37 zljpp 閱讀(260) 評(píng)論(0)  編輯  收藏
          HTML5 Canvas 可以引入圖像,用于圖片合成或者制作背景等。但目前僅可以在圖像中加入文字(標(biāo)準(zhǔn)說(shuō)明中并沒(méi)有包含繪制文字的功能)。只要是 Gecko 支持的圖像(如 PNG,GIF,JPEG等)都可以引入到 canvas 中,而且其它的 canvas 元素也可以作為圖像的來(lái)源。

          引入圖像

          HTML5 Canvas引入圖像只需要簡(jiǎn)單的兩步:1、首先當(dāng)然是來(lái)源圖片,不是簡(jiǎn)單的 URL 路徑,但可以是一個(gè) JavaScript 的 Image 對(duì)象引用,又或者其它的 canvas 元素,2、用 drawImage 方法將圖像插入到 canvas 中。

          先來(lái)看看第1步,基本上有四種可選方式:

          引用頁(yè)面內(nèi)的圖片

          這可以通過(guò) document.images 集合和document.getElementsByTagName 方法又或者 document.getElementById 方法來(lái)獲取頁(yè)面內(nèi)的圖片(如果已知圖片元素的 ID)。

          使用其它 canvas 元素 Using other canvas elements

          和引用頁(yè)面內(nèi)的圖片類(lèi)似地,用 document.getElementsByTagName 或 document.getElementById 方法來(lái)獲取其它 canvas 元素。但你引入的應(yīng)該是已經(jīng)準(zhǔn)備好的 canvas。

          由零開(kāi)始創(chuàng)建圖像

          另外,我們可以用腳本創(chuàng)建一個(gè)新的 Image 對(duì)象,但這種方法的主要缺點(diǎn)是如果不希望腳本因?yàn)榈却龍D片裝置而暫停,還得需要突破預(yù)裝載。

          我們可以通過(guò)下面簡(jiǎn)單的方法來(lái)創(chuàng)建圖片:

          		var img = new Image();   // Create new Image object
          img.src = 'myImage.png'; // Set source path
          

          當(dāng)腳本執(zhí)行后,圖片開(kāi)始裝載。若調(diào)用 drawImage 時(shí),圖片沒(méi)裝載完,腳本會(huì)等待直至裝載完畢。如果不希望這樣,可以使用 onload 事件:

          		var img = new Image();   // Create new Image object
          img.onload = function(){
            // execute drawImage statements here
          }
          img.src = 'myImage.png'; // Set source path
          

          如果你只用到一張圖片的話,這已經(jīng)夠了。但一旦需要不止一張圖片,那就需要更加復(fù)雜的處理方法,但圖片預(yù)裝載策略超出本教程的范圍,感興趣的話可以參考JavaScript Image Preloader。

          通過(guò) data: url 方式嵌入圖像

          我們還可以通“Data:_URL”方式來(lái)引用圖像。Data urls 允許用一串 Base64 編碼的字符串的方式來(lái)定義一個(gè)圖片。其優(yōu)點(diǎn)就是圖片內(nèi)容即時(shí)可用,無(wú)須再到服務(wù)器兜一圈。(還有一個(gè)優(yōu)點(diǎn)是,可以將 CSS,JavaScript,HTML 和 圖片全部封裝在一起,遷移起來(lái)十分方便。)缺點(diǎn)就是圖像沒(méi)法緩存,圖片大的話內(nèi)嵌的 url 數(shù)據(jù)會(huì)相當(dāng)?shù)拈L(zhǎng):

          		var img_src = 'data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw==';

          drawImage

          一旦獲得了源圖對(duì)象,我們就可以使用 drawImage 方法將它渲染到 canvas 里。drawImage 方法有三種形態(tài),下面是最基礎(chǔ)的一種。

          drawImage(image, x, y)

          其中 image 是 image 或者 canvas 對(duì)象,x 和 y 是其在目標(biāo) canvas 里的起始坐標(biāo)。

          drawImage 示例 1

          \" src=下面一個(gè)例子我用一個(gè)外部圖像作為一線性圖的背景。用背景圖我們就不需要繪制負(fù)責(zé)的背景,省下不少代碼。這里只用到一個(gè) image 對(duì)象,于是就在它的 onload 事件響應(yīng)函數(shù)中觸發(fā)繪制動(dòng)作。drawImage 方法將背景圖放置在 canvas 的左上角(0,0) 處。

          		function draw() {
              var ctx = document.getElementById('canvas').getContext('2d');
              var img = new Image();
              img.onload = function(){
                ctx.drawImage(img,0,0);
                ctx.beginPath();
                ctx.moveTo(30,96);
                ctx.lineTo(70,66);
                ctx.lineTo(103,76);
                ctx.lineTo(170,15);
                ctx.stroke();
              }
              img.src = 'images/backdrop.png';
            }
          
          

          縮放

          drawImage 方法的又一變種是增加了兩個(gè)用于控制圖像在 canvas 中縮放的參數(shù)。

          drawImage(image, x, y, width, height)

          Where width and height is the image's size on the target canvas. 當(dāng)中 width 和 height 分別是圖像在 canvas 中顯示大小。

          drawImage 示例 2

          在這個(gè)例子里,我會(huì)用一張圖片像背景一樣在 canvas 中以重復(fù)平鋪開(kāi)來(lái)。實(shí)現(xiàn)起來(lái)也很簡(jiǎn)單,只需要循環(huán)鋪開(kāi)經(jīng)過(guò)縮放的圖片即可。見(jiàn)下面的代碼,第一層 for 循環(huán)是做行重復(fù),第二層是做列重復(fù)的。圖像大小被縮放至原來(lái)的三分之一,50x38 px。這種方法可以用來(lái)很好的達(dá)到背景圖案的效果,在下面的教程中會(huì)看到。

          注意:圖像可能會(huì)因?yàn)榇蠓鹊目s放而變得起雜點(diǎn)或者模糊。如果您的圖像里面有文字,那么最好還是不要進(jìn)行縮放,因?yàn)槟菢犹幚碇蠛芸赡軋D像里的文字就會(huì)變得無(wú)法辨認(rèn)了。\" src=

          		function draw() {
              var ctx = document.getElementById('canvas').getContext('2d');
              var img = new Image();
              img.onload = function(){
                for (i=0;i<4;i++){
                  for (j=0;j<3;j++){
                    ctx.drawImage(img,j*50,i*38,50,38);
                  }
                }
              }
              img.src = 'images/rhino.jpg';
            }

          切片 Slicing

          drawImage 方法的第三個(gè)也是最后一個(gè)變種有8個(gè)新參數(shù),用于控制做切片顯示的。

          drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)

          \" src=

          第一個(gè)參數(shù)和其它的是相同的,都是一個(gè)圖像或者另一個(gè) canvas 的引用。其它8個(gè)參數(shù)最好是參照右邊的圖解,前4個(gè)是定義圖像源的切片位置和大小,后4個(gè)則是定義切片的目標(biāo)顯示位置和大小。

          切片是個(gè)做圖像合成的強(qiáng)大工具。假設(shè)有一張包含了所有元素的圖像,那么你可以用這個(gè)方法來(lái)合成一個(gè)完整圖像。例如,你想畫(huà)一張圖表,而手上有一個(gè)包含所有必需的文字的 PNG 文件,那么你可以很輕易的根據(jù)實(shí)際數(shù)據(jù)的需要來(lái)改變最終顯示的圖表。這方法的另一個(gè)好處就是你不需要單獨(dú)裝載每一個(gè)圖像。

          drawImage 示例 3

          \" src=在這個(gè)例子里面我用到上面已經(jīng)用過(guò)的犀牛圖像,不過(guò)這次我要給犀牛頭做個(gè)切片特寫(xiě),然后合成到一個(gè)相框里面去。相框帶有陰影效果,是一個(gè)以 24-bit PNG 格式保存的圖像。因?yàn)?24-bit PNG 圖像帶有一個(gè)完整的 8-bit alpha 通道,與 GIF 和 8-bit PNG 不同,我可以將它放成背景而不必?fù)?dān)心底色的問(wèn)題。

          我用一個(gè)與上面用到的不同的方法來(lái)裝載圖像,直接將圖像插入到 HTML 里面,然后通過(guò) CSS 隱藏(display:none)它。兩個(gè)圖像我都賦了 id ,方便后面使用。看下面的腳本,相當(dāng)簡(jiǎn)單,首先對(duì)犀牛頭做好切片(第一個(gè) drawImage )放在 canvas 上,然后再上面套個(gè)相框(第二個(gè) drawImage )。Source image

          		function draw() {
            var canvas = document.getElementById('canvas');
            var ctx = canvas.getContext('2d');
          
            // Draw slice
            ctx.drawImage(document.getElementById('source'),
                          33,71,104,124,21,20,87,104);
          
            // Draw frame
            ctx.drawImage(document.getElementById('frame'),0,0);
          }

          示例:畫(huà)廊 Art gallery example\" src=

          我這一章最后的示例是弄一個(gè)小畫(huà)廊。畫(huà)廊由掛著幾張畫(huà)作的格子組成。當(dāng)頁(yè)面裝載好之后,為每張畫(huà)創(chuàng)建一個(gè) canvas 元素并用加上畫(huà)框然后插入到畫(huà)廊中去。

          在我這個(gè)例子里面,所有“畫(huà)”都是固定寬高的,畫(huà)框也是。你可以做些改進(jìn),通過(guò)腳本用畫(huà)的寬高來(lái)準(zhǔn)確控制圍繞它的畫(huà)框的大小。

          下面的代碼應(yīng)該是蠻自我解釋的了。就是遍歷圖像對(duì)象數(shù)組,依次創(chuàng)建新的 canvas 元素并添加進(jìn)去。可能唯一需要注意的,對(duì)于那些并不熟悉 DOM 的朋友來(lái)說(shuō),是 insertBefore 方法的用法。insertBefore 是父節(jié)點(diǎn)(單元格)的方法,用于將新節(jié)點(diǎn)(canvas 元素)插入到我們想要插入的節(jié)點(diǎn)之前。

          	function draw() {
          
            // Loop through all images
            for (i=0;i<document.images.length;i++){
          
              // Don't add a canvas for the frame image
              if (document.images[i].getAttribute('id')!='frame'){
          
                // Create canvas element
                canvas = document.createElement('CANVAS');
                canvas.setAttribute('width',132);
                canvas.setAttribute('height',150);
          
                // Insert before the image
                document.images[i].parentNode.insertBefore(canvas,document.images[i]);
          
                ctx = canvas.getContext('2d');
          
                // Draw image to canvas
                ctx.drawImage(document.images[i],15,20);
          
                // Add frame
                ctx.drawImage(document.getElementById('frame'),0,0);
              }
            }
          }

          控制圖像的縮放行為

          Introduced in Gecko 1.9.2

          (Firefox 3.6 / Thunderbird 3.1 / Fennec 1.0)

          Gecko 1.9.2 引入了 mozImageSmoothingEnabled 屬性,值為 false 時(shí),圖像不會(huì)平滑地縮放。默認(rèn)是 true 。

          	cx.mozImageSmoothingEnabled = false;

          HTML5 canvas 元素詳細(xì)教程三之應(yīng)用圖像,希望對(duì)大家有用。


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 灵丘县| 田林县| 青河县| 大化| 共和县| 新巴尔虎右旗| 乃东县| 青铜峡市| 金秀| 牡丹江市| 仙桃市| 随州市| 崇阳县| 南安市| 南木林县| 交城县| 鄂尔多斯市| 都匀市| 京山县| 金湖县| 洪洞县| 宾阳县| 河源市| 武陟县| 彭泽县| 汾西县| 岗巴县| 呼和浩特市| 同德县| 绥滨县| 赤水市| 白城市| 郓城县| 泾阳县| 平凉市| 金门县| 全南县| 长岛县| 凤山县| 正阳县| 金溪县|