canvas小知識

huidaoli發表於2013-08-23
清單 1. 繪製 canvas 矩形
                                 
 function drawRect(){ 
 var canvas = document.getElementById('canvas'); 
 if (canvas.getContext){ 
 var ctx = canvas.getContext('2d');  // 獲取 2D 渲染上下文
                
 ctx.clearRect(0,0,300,200)  ;// 清除以(0,0)為左上座標原點,300*200 矩形區域內所有畫素
 ctx.fillStyle = '#00f';   // 設定矩形的填充屬性,#00f 代表藍色
 ctx.strokeStyle = '#f00';  // 設定矩形的線條顏色,#f00 代表紅色
 ctx.fillRect(50,25,150,80); // 使用 fillStyle 填充一個 150*80 大小的矩形
 ctx.strokeRect(45,20, 160, 90);  // 以 strokeStype 屬性為邊的顏色繪製一個無填充矩形
     } 
 } 
 
清單 2. 繪製 canvas 路徑
                                 
 function draw(){ 
 var canvas = document.getElementById('canvas'); 
         if (canvas.getContext){ 
                 var ctx = canvas.getContext('2d'); 
 ctx.fillStyle = '#00f'; 
                 ctx.strokeStyle = '#f00'; 
                 ctx.beginPath(); 
 ctx.arc(75,75,30,0,Math.PI, false);  // 繪製一條半圓弧線
 ctx.closePath();    // 自動繪製一條直線來關閉弧線。若不呼叫此方法,將僅僅顯示一條半圓弧
 ctx.fill();      // 可以嘗試註釋掉 fill 或者 stroke 函式,觀察圖形的變化
 ctx.stroke();  
         } 
 }  
清單 3. 使用平移 / 旋轉變形方法繪製複雜點陣圖
                                 
 function drawPointCircle(){  
 var canvas = document.getElementById('canvas');  
         if (canvas.getContext){ 
                 var ctx = canvas.getContext('2d');  
 ctx.translate(150,150);   // 將 canvas 的原點從 (0,0) 平移至(150,150)
 for (i=1;i<=2;i++){        // 繪製內外 2 層
 if ((i % 2) == 1) {ctx.fillStyle = '#00f';} 
 else{ ctx.fillStyle = '#f00'; } 
 ctx.save();             // 保持開始繪製每一層時的狀態一致
 for (j=0;j<=i*6;j++){   // 每層生成點的數量
 ctx.rotate(Math.PI/(3*i));  // 繞當前原點將座標系順時針旋轉 Math.Pi/(3*i) 度
                                 ctx.beginPath(); 
                                 ctx.arc(0,20*i,5,0,Math.PI*2,true); 
 ctx.fill();         // 使用 fillType 值填充每個點
 } 
 ctx.restore();   
                 } 
         } 
 } 
 
清單 4. 實現簡單濾鏡效果
                                 
 function revertImage(){ 
 var canvas = document.getElementById('canvas'); 
 if (canvas.getContext){ 
 var context = canvas.getContext('2d'); 
 // 從指定的矩形區域獲取 canvas 畫素陣列
 var imgdata = context.getImageData(100, 100, 100, 100); 
 var pixels = imgdata.data; 

 // 遍歷每個畫素並對 RGB 值進行取反
 for (var i=0, n=pixels.length; i<n; i+= 4){ 
      pixels[i] = 255-pixels[i]; 
       pixels[i+1] = 255-pixels[i+1]; 
       pixels[i+2] = 255-pixels[i+2]; 
 } 
 // 在指定位置進行畫素重繪
 context.putImageData(imgdata, 100, 100); 
         } 
 } 
 
清單 5. 實現小彈力球動畫
                                 
 <script type="text/javascript"> 
 var x=0,y=0,dx=2,dy=3,context2D;   // 小球從(0,0)開始移動,橫向步長為 2,縱向步長為 3 

 function draw(){ 
 context2D.clearRect(0, 0, canvas.width, canvas.height);   // 清除整個 canvas 畫面
 drawCircle(x, y);         // 使用自定義的畫圓方法,在當前(x,y)座標出畫一個圓
        
 // 判斷邊界值,調整 dx/dy 以改變 x/y 座標變化方向。
 if (x + dx > canvas.width || x + dx < 0) dx = -dx; 
 if (y + dy > canvas.height || y + dy < 0) dy = -dy; 
 x += dx; 
 y += dy; 
 } 

 window.onload = function (){ 
 var canvas = document.getElementById('canvas'); 
 context2D = canvas.getContext('2d'); 
 setInterval(draw, 20);     // 設定繪圖週期為 20 毫秒
 } 
 </script> 
 
清單 6. 實現 canvas 對方向鍵和滑鼠點選事件的響應
                                 
 <script type="text/javascript"> 
 var g_x,g_y;    // 滑鼠當前的座標
 var g_pointx, g_pointy;   // 藍色小球當前的座標
         var canvas; 
        
 function drawCircle(x,y){    // 以滑鼠當前位置為原點繪製一個藍色小球
 var ctx = canvas.getContext('2d'); 
                 ctx.clearRect(0,0,300,300); 
                 ctx.fillStyle = '#00f'; 
                 ctx.beginPath(); 
                 ctx.arc(x,y,20,0,Math.PI*2,true); 
                 ctx.fill(); 
                        
 g_pointx = x; 
                 g_pointy = y 
 } 
        
         function onMouseMove(evt) { 
 // 獲取滑鼠在 canvas 中的座標位置
 if (evt.layerX || evt.layerX == 0) { // FireFox 
 g_x = evt.layerX; 
 g_y = evt.layerY; 
 } 
                 document.getElementById("xinfo").innerHTML = g_x; 
                 document.getElementById("yinfo").innerHTML = g_y; 
         } 

         function onKeyPress(evt) { 
 var dx = 3;  // 橫向平移步長
                 var kbinfo = document.getElementById("kbinfo"); 
                
 if (evt.keyCode == 39){   
                         kbinfo.innerHTML="right"; 
 if (g_x<300-dx) drawCircle(g_pointx+dx,g_pointy); 
 document.getElementById("xinfo").innerHTML = g_pointx; 
                 }else if (evt.keyCode == 37){ 
 kbinfo.innerHTML = "left"; 
                         if (g_x>dx) drawCircle(g_pointx-dx,g_pointy); 
 document.getElementById("xinfo").innerHTML = g_pointx; 
 } 
 } 
                        
 window.onload = function(){ 
 canvas = document.getElementById('canvas'); 
 // 增加 canvas 節點對滑鼠單擊,移動以及鍵盤事件的響應函式
 canvas.addEventListener('click', function(evt){drawCircle(g_x, g_y);} , false);
 canvas.addEventListener('mousemove', onMouseMove, false); 
 canvas.addEventListener('keypress', onKeyPress, false); 
 canvas.focus();  // 獲得焦點之後,才能夠對鍵盤事件進行捕獲
 } 
 </script>