Canvas API


  1. HTML Canvas API有兩方面優勢可以彌補:首先,不需要將所繪制圖像中的每個圖元當做對象存儲,因此執行性能非常好;其次,在其他編程語言現有的優秀二維繪圖API的基礎上實現Canvas API相對來說比較簡單。
  2. 在網頁上使用canvas元素時,它會創建一塊矩形區域。默認情況下該矩形區域寬為300像素,高為150像素,但也可以自定義具體的大小或者設置canvas元素的其他特性。
     1 <body>
     2   <div>
     3     <header>
     4       <h1>index</h1>
     5     </header>
     6     <nav>
     7       <p><a href="/">Home</a></p>
     8       <p><a href="/contact">Contact</a></p>
     9     </nav>
    10 
    11     <div>
    12       <canvas id="game"></canvas>
    13     </div>
    14 
    15     <footer>
    16      <p>&copy; Copyright  by Administrator</p>
    17     </footer>
    18   </div>
    19 </body>
  3. canvas是行內元素
     1 <!DOCTYPE HTML>
     2 <html>
     3 <head>
     4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
     5 <title>無標題文檔</title>
     6 <style>
     7 #game {
     8     background-color:#ccc;
     9     border-radius:10px;
    10     -moz-border-radius:10px;
    11     -webkit-border-radius:10px;
    12     width:500px;
    13     height:500px;
    14     margin:0 auto
    15 }
    16 </style>
    17 </head>
    18 
    19 <body>
    20 <canvas id="game"></canvas>
    21 <canvas id="game"></canvas>
    22 </body>
    23 </html>

    顯示在同一行,由此不難發現canvas是行內元素。
  4. CSS和canvas
    同大多數HTML元素一樣,canvas元素也可以通過應用CSS的方式來增加邊框,設置內邊距、外邊距等,而且一些CSS屬性還可以被canvas內的元素繼承。比如字體樣式,在canvas內添加的文字,其樣式默認同canvas元素本身是一樣的。
    此外,在canvas中為context設置屬性同樣要遵從CSS語法。例如,對context應用顏色和字體樣式,跟在任何HTML和CSS文檔中使用的語法完全一樣。
  5. 在所有瀏覽器中,只有Internet Explorer不支持HTML5 Canvas。如果需要在Internet Explorer中使用canvas,可以選擇使用名為explorercanvas的開源項目。使用explorercanvas時,需要先判斷當前瀏覽器是否是Internet Explorer,如果是則在頁面中嵌入script標簽來加載explorercanvas。寫法如下:
    1 <head>
    2 <!--[if IE]><script src="excanvas.js"></script><![endif]-->
    3 </head>
  6. 通過傳入“2d”來獲取一個二維上下文,這也是到目前為止唯一可用的上下文。提示 規范未來的某個版本中可能會增加對三維上下文的支持。
  7. 對上下文的很多操作都不會立即反映到頁面上。beginPath、moveTo以及lineTo這些函數都不會直接修改canvas的展示結果。canvas中很多用於設置樣式和外觀的函數也同樣不會直接修改顯示結果。只有當對路徑應用繪制(stroke)或填充(fill)方法時,結果才會顯示出來。
  8. 圓形繪制。調用方法:context.arc(100, 100, 50, 0, 1/2*Math.PI, true);參數依次表示:圓心x坐標,圓心y坐標,半徑,開始弧度,結束弧度,順時針還是逆時針(true表示逆時針,false表示順時針)。1/2Math.PI表示1/4圓的弧度。
  9. 變換(縮放、平移、旋轉等)
    可以像目前主流圖像編輯工具那樣支持實時圖像處理,所以API中這部分內容的復雜性是必要的。
     1 <!DOCTYPE HTML>
     2 <html lang="en">
     3 <head>
     4 <meta charset="utf-8">
     5 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
     6 <title>未命名文件</title>
     7 <script>
     8 function drawDiagonal() {
     9 var canvas = document.getElementById('diagonal');
    10 var context = canvas.getContext('2d');
    11 // 保存當前繪圖狀態
    12 context.save();
    13 // 向右下方移動繪圖上下文
    14 context.translate(70, 140);
    15 // 以原點為起點,繪制與前面相同的線段
    16 context.beginPath();
    17 context.moveTo(0, 0);
    18 context.lineTo(70, -70);
    19 context.stroke();
    20 // 恢復原有的繪圖狀態
    21 context.restore(); 
    22 } 
    23 window.addEventListener("load", drawDiagonal, true); </script>
    24 </head>
    25 
    26 <body>
    27 <canvas id="diagonal" width="200" height="200"> </canvas>
    28 </body>
    29 </html>
    30 </body>
    31 </html>

  10. closePath。這個函數的行為同lineTo很像,唯一的差別在於closePath會將路徑的起始坐標自動作為目標坐標。closePath還會通知canvas當前繪制的圖形已經閉合或者形成了完全封閉的區域,這對將來的填充和描邊都非常有用。
  11. 描邊
    1 // 加寬線條
    2 context.lineWidth = 4;
    3 // 平滑路徑的接合點
    4 context.lineJoin = 'round';
    5 // 將顏色改成棕色
    6 context.strokeStyle = '#663300';
    7 // 最后,繪制樹冠
    8 context.stroke();

    也可以把lineJoin屬性設置成bevel或者miter(相應的context.miterLimit值也需要調整)來變換拐角樣式。

    lineCap,可以把它的值設置為butt、square或者round,以此來指定線條末端的樣式。
  12. strokeRectclearRect。strokeRect的作用是基於給出的位置和坐標畫出矩形的輪廓,clearRect的作用是清除矩形區域內的所有內容並將它恢復到初始狀態,即透明色。在HTML5 Canvas API中,canvas的清除矩形功能是創建動畫和游戲的核心功能。如果希望創建運行起來比較流暢的動畫,就需要使用剪裁(clipping)功能了,有可能還需要二次緩存canvas,以便最小化由於頻繁的清除動作而導致的畫面閃爍。
  13. 繪制曲線
     1 <!DOCTYPE HTML>
     2 <html lang="en">
     3 <head>
     4 <meta charset="utf-8">
     5 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
     6 <title>未命名文件</title>
     7 <script>
     8 function drawDiagonal() {
     9 var canvas = document.getElementById('diagonal');
    10 var context = canvas.getContext('2d');
    11 // 保存canvas的狀態並繪制路徑
    12 context.save();
    13 context.translate(100,100);
    14 context.beginPath();
    15 // 第一條曲線向右上方彎曲
    16 context.moveTo(0, 0);
    17 context.quadraticCurveTo(170, -50, 260, -190);
    18 // 第二條曲線向右下方彎曲
    19 context.quadraticCurveTo(310, -250, 410,-250);
    20 // 使用棕色的粗線條來繪制路徑
    21 //context.lineTo(100,100);
    22 context.strokeStyle = '#663300';
    23 context.lineWidth = 3;
    24 context.stroke();
    25 // 恢復之前的canvas狀態
    26 context.restore();
    27 } 
    28 window.addEventListener("load", drawDiagonal, true); </script>
    29 </head>
    30 
    31 <body>
    32 <canvas id="diagonal" width="200" height="200"> </canvas>
    33 </body>
    34 </html>
    35 </body>
    36 </html>


    第二組是指曲線的終點。第一組代表控制點(control point)。所謂的控制點位於曲線的旁邊(不是曲線之上),其作用相當於對曲線產生一個拉力。通過調整控制點的位置,就可以改變曲線的曲率。HTML5 Canvas API的其他曲線功能還涉及bezierCurveTo、arcTo和arc函數。這些函數通過多種控制點(如半徑、角度等)讓曲線更具可塑性。

  14. 在canvas中插入圖片。在canvas中顯示圖片非常簡單。可以通過修正層為圖片添加印章、拉伸圖片或者修改圖片等,並且圖片通常會成為canvas上的焦點。用HTML5 Canvas API內置的幾個簡單命令可以輕松地為canvas添加圖片內容。不過,圖片增加了canvas操作的復雜度:必須等到圖片完全加載后才能對其進行操作。瀏覽器通常會在頁面腳本執行的同時異步加載圖片。如果試圖在圖片未完全加載之前就將其呈現到canvas上,那么canvas將不會顯示任何圖片。
     1 <!DOCTYPE HTML>
     2 <html lang="en">
     3 <head>
     4 <meta charset="utf-8">
     5 <title>未命名文件</title>
     6 <style>
     7 #diagonal {
     8     background-color:#ccc
     9 }
    10 </style>
    11 <script>
    12 window.onload=function(){
    13     var canvas = document.getElementById('diagonal');
    14     var context = canvas.getContext('2d');
    15     // 加載圖片bark.jpg 
    16     var bark = new Image(); 
    17     bark.src = "http://www.jsdarkhorse.com/templets/default/images/logo.jpg"; 
    18     // 圖片加載完成后,將其顯示在canvas上 
    19     bark.onload=function(){                
    20         context.drawImage(bark, 5, 50, 100, 50);
    21     }        
    22 }
    23 </script>
    24 </head>
    25 
    26 <body>
    27 <canvas id="diagonal" width="200" height="200"> </canvas>
    28 </body>
    29 </html>


    從上面的代碼中可以看到,我們為bark.jpg圖片添加了onload處理函數,以保證僅在圖像加載完成。除了圖片本身外,還指定了x、y、width和height參數。這些參數會對貼圖進行調整。我們還可以把原圖的尺寸傳進來,以便在裁切區域內對圖片進行更多控制。

  15. 漸變
    使用漸變需要三個步驟:
    (1) 創建漸變對象;
    (2) 為漸變對象設置顏色,指明過渡方式;
    (3) 在context上為填充樣式或者描邊樣式設置漸變。
    要設置顯示哪種顏色,在漸變對象上使用addColorStop函數即可。這個函數允許指定兩個參數:顏色和偏移量。顏色參數是指開發人員希望在偏移位置描邊或填充時所使用的顏色。偏移量是一個0.0到1.0之間的數值,代表沿着漸變線漸變的距離有多遠。除了可以變換成其他顏色外,還可以為顏色設置alpha值(例如透明),並且alpha值也是可以變化的。為了達到這樣的效果,需要使用顏色值的另一種表示方法,例如內置alpha組件的CSS rgba函數。
     1 <!DOCTYPE HTML>
     2 <html lang="en">
     3 <head>
     4 <meta charset="utf-8">
     5 <title>未命名文件</title>
     6 <style>
     7 #diagonal {
     8     background-color:#ccc
     9 }
    10 </style>
    11 <script>
    12 window.onload=function(){
    13     var canvas = document.getElementById('diagonal');
    14     var context = canvas.getContext('2d');
    15     context.translate(100,100);
    16     // 創建用作樹干紋理的三階水平漸變
    17     var trunkGradient = context.createLinearGradient(-5, -50, 50, -50);
    18     // 樹干的左側邊緣是一般程度的棕色
    19     trunkGradient.addColorStop(0, '#663300');
    20     // 樹干中間偏左的位置顏色要淡一些
    21     trunkGradient.addColorStop(0.4, '#996600');
    22     // 樹干右側邊緣的顏色要深一些
    23     trunkGradient.addColorStop(1, '#552200');
    24     // 使用漸變色填充樹干
    25     context.fillStyle = trunkGradient;
    26     context.fillRect(-5, -50, 50, 100);
    27     // 接下來,創建垂直漸變,以用作樹冠在樹干上投影
    28     var canopyShadow = context.createLinearGradient(0, -50, 50, 100);
    29     // 投影漸變的起點是透明度設為50%的黑色
    30     canopyShadow.addColorStop(0, 'rgba(0, 0, 0, 0.5)');
    31     // 方向垂直向下,漸變色在很短的距離內迅速漸變至完全透明,這段長度之外的樹干上沒有投影
    32     canopyShadow.addColorStop(0.2, 'rgba(0, 0, 0, 0.0)');
    33     // 在樹干上填充投影漸變
    34     context.fillStyle = canopyShadow;
    35     context.fillRect(-5, -50, 50, 100);    
    36 }
    37 </script>
    38 </head>
    39 
    40 <body>
    41 <canvas id="diagonal" width="200" height="200"> </canvas>
    42 </body>
    43 </html>

    除了我們剛才用到的線性漸變以外,HTML5 Canvas API還支持放射性漸變,所謂放射性漸變就是顏色會介於兩個指定圓間的錐形區域平滑變化。放射性漸變和線性漸變使用的顏色終止點是一樣的。
    createRadialGradient(x0, y0, r0, x1, y1, r1)

    代碼中,前三個參數代表以(x0,y0)為圓心,r0為半徑的圓,后三個參數代表以(x1,y1)為圓心,r1為半徑的另一個圓。漸變會在兩個圓中間的區域出現。

  16. 背景圖
     1 <!DOCTYPE HTML>
     2 <html lang="en">
     3 <head>
     4 <meta charset="utf-8">
     5 <title>未命名文件</title>
     6 <style>
     7 #diagonal {
     8     background:#ccc
     9 }
    10 </style>
    11 <script>
    12 window.onload=function(){
    13    var canvas = document.getElementById('diagonal');
    14    var context = canvas.getContext('2d');
    15    // 加載圖片bark.jpg 
    16    var bark = new Image(); 
    17    bark.src = "http://www.jsdarkhorse.com/templets/default/images/logo.jpg"; 
    18    // 圖片加載完成后,將其顯示在canvas上 
    19    bark.onload=function(){                       
    20        context.fillStyle = context.createPattern(bark, 'repeat');
    21        context.fillRect(5, 50, 100, 200);
    22    }        
    23 }
    24 </script>
    25 </head>
    26 
    27 <body>
    28 <canvas id="diagonal" width="200" height="200"> </canvas>
    29 </body>
    30 </html>

  17. 縮放canvas對象
    為了在新的位置畫出大一點的樹,我們將使用另一種變換方式——縮放函數context.scale
     1 <!DOCTYPE HTML>
     2 <html lang="en">
     3 <head>
     4 <meta charset="utf-8">
     5 <title>未命名文件</title>
     6 <style>
     7 #diagonal {
     8     background-color:#ccc
     9 }
    10 </style>
    11 <script>
    12 window.onload=function(){    
    13     function drawTree(context) {        
    14         // 創建用作樹干紋理的三階水平漸變
    15         var trunkGradient = context.createLinearGradient(-5, -50, 50, -50);
    16         // 樹干的左側邊緣是一般程度的棕色
    17         trunkGradient.addColorStop(0, '#663300');
    18         // 樹干中間偏左的位置顏色要淡一些
    19         trunkGradient.addColorStop(0.4, '#996600');
    20         // 樹干右側邊緣的顏色要深一些
    21         trunkGradient.addColorStop(1, '#552200');
    22         // 使用漸變色填充樹干
    23         context.fillStyle = trunkGradient;
    24         context.fillRect(-5, -50, 50, 100);
    25         // 接下來,創建垂直漸變,以用作樹冠在樹干上投影
    26         var canopyShadow = context.createLinearGradient(0, -50, 50, 100);
    27         // 投影漸變的起點是透明度設為50%的黑色
    28         canopyShadow.addColorStop(0, 'rgba(0, 0, 0, 0.5)');
    29         // 方向垂直向下,漸變色在很短的距離內迅速漸變至完全透明,這段長度之外的樹干上沒有投影
    30         canopyShadow.addColorStop(0.2, 'rgba(0, 0, 0, 0.0)');
    31         // 在樹干上填充投影漸變
    32         context.fillStyle = canopyShadow;
    33         context.fillRect(-5, -50, 50, 100);    
    34         /*createCanopyPath(context);
    35         context.lineWidth = 4;
    36         context.lineJoin = 'round';
    37         context.strokeStyle = '#663300';
    38         context.stroke();
    39         context.fillStyle = '#339900';
    40         context.fill();    */
    41     }
    42     var canvas = document.getElementById('diagonal');
    43     var context = canvas.getContext('2d');
    44     // 在(50,50)的位置繪制第一棵樹
    45     context.save();
    46     context.translate(30, 30);
    47     drawTree(context);
    48     context.restore();            
    49     // 在(100,100)的位置繪制第二棵樹
    50     context.save();
    51     context.translate(100, 100);
    52     // 將第二棵樹的寬高分別放大至原來的2倍
    53     context.scale(2, 2);
    54     drawTree(context);
    55     context.restore();
    56 }
    57 </script>
    58 </head>
    59 
    60 <body>
    61 <canvas id="diagonal" width="200" height="200"> </canvas>
    62 </body>
    63 </html>

    scale函數帶有兩個參數來分別代表在x、y兩個維度的值。每個參數在canvas顯示圖像的時候,向其傳遞在本方向軸上圖像要放大(或者縮小)的量。如果x值為2,就代表所繪制圖像中全部元素都會變成兩倍寬,如果y值為0.5,繪制出來的圖像全部元素都會變成之前的一半高。如果對一個不在原點的圖形進行旋轉變換,那么rotate變換函數會將圖形繞着原點旋轉而不是在原地旋轉。與之類似,如果進行縮放操作時沒有將圖形放置到合適的坐標上,那么所有路徑坐標都會被同時縮放。取決於縮放比例的大小,新的坐標可能會全部超出canvas范圍,進而給開發人員帶來困惑,為什么我的縮放操作會把圖像刪了?”
  18. Canvas變換
     1 <!DOCTYPE HTML>
     2 <html lang="en">
     3 <head>
     4 <meta charset="utf-8">
     5 <title>未命名文件</title>
     6 <style>
     7 #diagonal {
     8     background-color:#ccc
     9 }
    10 </style>
    11 <script>
    12 window.onload=function(){    
    13     function drawTree(context) {        
    14         // 創建用作樹干紋理的三階水平漸變
    15         var trunkGradient = context.createLinearGradient(-5, -50, 50, -50);
    16         // 樹干的左側邊緣是一般程度的棕色
    17         trunkGradient.addColorStop(0, '#663300');
    18         // 樹干中間偏左的位置顏色要淡一些
    19         trunkGradient.addColorStop(0.4, '#996600');
    20         // 樹干右側邊緣的顏色要深一些
    21         trunkGradient.addColorStop(1, '#552200');
    22         // 使用漸變色填充樹干
    23         context.fillStyle = trunkGradient;
    24         context.fillRect(-5, -50, 50, 100);
    25         // 接下來,創建垂直漸變,以用作樹冠在樹干上投影
    26         var canopyShadow = context.createLinearGradient(0, -50, 50, 100);
    27         // 投影漸變的起點是透明度設為50%的黑色
    28         canopyShadow.addColorStop(0, 'rgba(0, 0, 0, 0.5)');
    29         // 方向垂直向下,漸變色在很短的距離內迅速漸變至完全透明,這段長度之外的樹干上沒有投影
    30         canopyShadow.addColorStop(0.2, 'rgba(0, 0, 0, 0.0)');
    31         // 在樹干上填充投影漸變
    32         context.fillStyle = canopyShadow;
    33         context.fillRect(-5, -50, 50, 100);    
    34     }
    35     var canvas = document.getElementById('diagonal');
    36     var context = canvas.getContext('2d');
    37     // 在(50,50)的位置繪制第一棵樹
    38     context.save();
    39     context.translate(100,100);
    40     drawTree(context);
    41     // 從整體上前四個參數負責縮放和旋轉,后兩個參數是平移,前四個參數1,4為一組控制縮放,2,3為一組控制旋轉,1和2是x值,3和4是y值,5和6分別為x,y的平移
    42     context.transform(1, 0, -1, 1, 55, 0); 
    43     // 使用透明度為20%的黑色填充樹干
    44     context.fillStyle = 'rgba(0, 0, 0, 0.2)';
    45     context.fillRect(-5, -50, 50, 100);    
    46     // 使用已有的陰影效果重新繪制樹
    47     context.fill();
    48     // 恢復之前的canvas狀態
    49     context.restore();
    50 }
    51 </script>
    52 </head>
    53 
    54 <body>
    55 <canvas id="diagonal" width="500" height="500"> </canvas>
    56 </body>
    57 </html>

  19. Canvas文本
    操作canvas文本的方式與操作其他路徑對象的方式相同:可以描繪文本輪廓和填充文本內部;同時,所有能夠應用於其他圖形的變換和樣式都能用於文本。context對象的文本繪制功能由兩個函數組成:
    (1)fillText(text,x, y,maxwidth)
    (2)strokeText(text,x,y,maxwidth)
    兩個函數的參數完全相同,必選參數包括文本參數以及用於指定文本位置的坐標參數。maxwidth是可選參數,用於限制字體大小,它會將文本字體強制收縮到指定尺寸。此外,還有一個measureText函數可供使用,該函數會返回一個度量對象,其中包含了在當前context環境下指定文本的實際顯示寬度。
    為了保證文本在各瀏覽器下都能正常顯示,Canvas API為context提供了類似於CSS的屬性,以此來保證實際顯示效果的高度可配置。font(CSS字體字符串,例如:italic Arial,scan-serif)、textAlign(start、end、left、right、center,默認是start)、textBaseline(top、hanging、middle、alphabetic、ideographic、bottom,默認是alphabetic)。
     1 <!DOCTYPE HTML>
     2 <html lang="en">
     3 <head>
     4 <meta charset="utf-8">
     5 <title>未命名文件</title>
     6 <style>
     7 #diagonal {
     8     background-color:#ccc
     9 }
    10 </style>
    11 <script>
    12 window.onload=function(){    
    13     var canvas = document.getElementById('diagonal');
    14     var context = canvas.getContext('2d');
    15     // 字號為60px,字體為impact
    16     context.font = "60px impact";
    17     // 將文本填充為棕色
    18     context.fillStyle = '#996600';
    19     // 將文本設為居中對齊
    20     context.textAlign = 'center';
    21     context.textBaseline='middle';
    22     // 在canvas頂部中央的位置,以大字體的形式顯示文本
    23     context.fillText('Hello Jsdarkhorse!', 250, 250, 400);
    24     context.restore();
    25 }
    26 </script>
    27 </head>
    28 
    29 <body>
    30 <canvas id="diagonal" width="500" height="500"> </canvas>
    31 </body>
    32 </html>

  20. 應用陰影
    可以通過幾種全局context屬性來控制陰影。
    shadowColor任何CSS中的顏色值。可以使用透明度(alpha)
    ShadowOffsetX像素值。值為正數,向右移動陰影;值為負數,向左移動陰影
    shadowOffsetY像素值。值為正數,向下移動陰影;值為負數,向上移動陰影
    shadowBlur高斯模糊值。值越大,陰影邊緣越模糊
     1 <!DOCTYPE HTML>
     2 <html lang="en">
     3 <head>
     4 <meta charset="utf-8">
     5 <title>未命名文件</title>
     6 <style>
     7 #diagonal {
     8     background-color:#ccc
     9 }
    10 </style>
    11 <script>
    12 window.onload=function(){    
    13     var canvas = document.getElementById('diagonal');
    14     var context = canvas.getContext('2d');
    15     // 設置文字陰影的顏色為黑色,透明度為20%
    16     context.shadowColor = 'rgba(0, 0, 0, 0.2)';
    17     // 將陰影向右移動15px,向上移動10px
    18     context.shadowOffsetX = 15;
    19     context.shadowOffsetY = -10;
    20     // 輕微模糊陰影
    21     context.shadowBlur = 2;
    22     // 字號為60px,字體為impact
    23     context.font = "60px impact";
    24     // 將文本填充為棕色
    25     context.fillStyle = '#996600';
    26     // 將文本設為居中對齊
    27     context.textAlign = 'center';
    28     context.textBaseline='middle';
    29     // 在canvas頂部中央的位置,以大字體的形式顯示文本
    30     context.fillText('Hello Jsdarkhorse!', 250, 250, 400);
    31     context.restore();
    32 }
    33 </script>
    34 </head>
    35 
    36 <body>
    37 <canvas id="diagonal" width="500" height="500"> </canvas>
    38 </body>
    39 </html>

  21. 像素數據
    Canvas API最有用的特性之一是允許開發人員直接訪問canvas底層像素數據。這種數據訪問是雙向的:一方面,可以以數值數組形式獲取像素數據;另一方面,可以修改數組的值以將其應用於canvas。
    context.getImageData(sx, sy, sw, sh)。這個函數返回當前canvas狀態並以數值數組的方式顯示。具體來說,返回的對象包括三個屬性。
      width:每行有多少個像素。
      height:每列有多少個像素。
      data:一維數組,存有從canvas獲取的每個像素的RGBA值。該數組為每個像素保存了四個值——紅、綠、藍和alpha透明度。每個值都在0到255之間。因此,canvas上的每個像素在這個數組中就變成了四個整數值。
    getImageData函數有四個參數,該函數只返回這四個參數所限定的區域內的數據。只有被x、y、width和height四個參數框定的矩形區域內的canvas上的像素才會被取到,因此要想獲取所有像素數據,就需要這樣傳入參數:getImageData(0, 0, canvas.width, canvas.height)。
    因為每個像素由四個圖像數據表示,所以要計算指定的像素點對應的值是什么就有點頭疼。不要緊,下面有公式。
    在給定了width和height的canvas上,在坐標(x ,y)上的像素的構成如下。
      紅色部分:((width * y) + x) * 4
      綠色部分:((width * y) + x) * 4 + 1
      藍色部分:((width * y) + x) * 4 + 2
      透明度部分:((width * y) + x) * 4 + 3
    修改了任何像素的紅、綠、藍和alpha值之后,可以通過第二個函數來更新canvas上的顯示,那就是context.putImageData(imagedata, dx, dy)。putImageData允許開發人員傳入一組圖像數據,其格式與最初從canvas上獲取來的是一樣的。這個函數使用起來非常方便,因為可以直接用從canvas上獲取數據加以修改然后返回。一旦這個函數被調用,所有新傳入的圖像數據值就會立即在canvas上更新顯示出來。dx和dy參數可以用來指定偏移量,如果使用,則該函數就會跳到指定的canvas位置去更新顯示傳進來的像素數據。
    最后,如果想預先生成一組空的canvas數據,則可調用context.createImageData(sw, sh),這個函數可以創建一組圖像數據並綁定在canvas對象上。這組數據可以像先前那樣處理,只是在獲取canves數據時,這組圖像數據不一定會反映canvas的當前狀態。
  22. Canvas的安全機制
    上面討論了直接操縱像素數據的方法,在這里有必要重點提醒一下,大多數開發者都會合法使用像素數據操作。盡管如此,還是會有人出於某些邪惡的目的利用這種從canvas直接獲取並且修改數據的能力。出於這個原因,origin-clean canvas的概念應運而生,換句話說,如果canvas中的圖片並非來自包含它的頁面所在的域,頁面中的腳本將不能取得其中的數據。
    然而,在沒有Canvas API以前,無法使用編程的方式獲取下載圖片的像素信息。來自其他網站的私有圖片可以顯示在本地,但無法被讀取或者復制。如果允許腳本讀取本地之外的圖像數據,那么整個網絡中的用戶照片以及其他敏感的在線圖片文檔將被“無限制地共享”。
    為了避免如此,在getImageData函數被調用的時候,如果canvas中的圖像來自其他域,就會拋出安全異常。這樣的話,只要不獲取顯示着其他域中圖片的canvas的數據,那么就可以隨意呈現這些遠程圖片。在開發的過程中要注意這個限制條件,使用安全的渲染方式。


免責聲明!

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



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