1.第一個Canvas程序 javascript
看的是HTML5移動開發即學即用這本書,首先學習Canvas基礎,廢話很少說,直接看第一個例子。css
效果圖爲:html
代碼以下:html5
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <style type="text/css"> 6 canvas { 7 border-width: 5px; 8 border-style: dashed; 9 border-color: rgba(20, 126, 239, 0.50) 10 } 11 </style> 12 13 </head> 14 <body> 15 hello HTML5! 16 <canvas id="c1" width="300" height="300" ></canvas> 17 </body> 18 <script type="text/javascript"> 19 //canvas對象的取得 20 var canvas=document.getElementById("c1"); 21 //取得繪圖用的上下文對象 22 var ctx=canvas.getContext("2d"); 23 //繪圖處理 24 ctx.fillStyle="rgb(255,0,0)"; 25 ctx.fillRect(50,50,200,200); 26 ctx.fillStyle="rgba(0,0,255,0.5)"; 27 ctx.fillRect(100,100,200,200); 28 <!--alert("hello");--> 29 </script> 30 </html>
知識點:java
Canvas 的基本用法正則表達式
1)取得Canvas對象canvas
2)從Canvas對象中獲取繪圖用的上下文數組
3)使用上下文中的方法與屬性進行繪圖瀏覽器
顏色的指定方法app
1)ctx.fillStyle="#FF0000";
2)ctx.fillStyle="rgb(255,0,0)";
3)ctx.fillStyle="rgba(0,0,255,0.5)"; 最後這個指透明度的。。。
2.路徑
繪製一個簡單的三角形,效果:
代碼以下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <style type="text/css"> 6 canvas { 7 border-width: 5px; 8 border-style: dashed; 9 border-color: rgba(20, 126, 239, 0.50) 10 } 11 </style> 12 13 </head> 14 <body> 15 hello HTML5! 16 <canvas id="c1" width="300" height="300" ></canvas> 17 </body> 18 <script type="text/javascript"> 19 //canvas對象的取得 20 var canvas=document.getElementById("c1"); 21 //取得繪圖用的上下文對象 22 var ctx=canvas.getContext("2d"); 23 //路徑繪製開始 24 ctx.beginPath(); 25 //路徑的繪製 26 ctx.moveTo(0,0); 27 ctx.lineTo(0,290); 28 ctx.lineTo(290,290); 29 //路徑繪製結束 30 ctx.closePath(); 31 //進行繪圖處理 32 ctx.fillStyle="rgb(200,0,0)" 33 ctx.fill(); 34 <!--alert("hello");--> 35 </script> 36 </html>
知識點:
控制路徑時使用的方法:
1) beginPath() 重置路徑的開始
2) closePath() 關閉到如今爲止的路徑
3) moveTo() 指定繪圖開始時的基點(x,y)
4) lineTo() 繪製從前一次繪圖位置到(x,y)的直線
繪製路徑時使用的方法:
1)stroke() 繪製路徑
2)fill()填充路徑
指定繪圖樣式時使用的屬性
1)fillStyle 指定填充時使用的顏色與樣式
2)strokeStyle 指定路徑的線顏色與樣式
3)lineWidth 指定路徑線的粗細
下面製做一個當用戶觸摸屏幕時在觸摸位置繪製三角形的實例程序 (書上的是用戶觸摸屏幕時繪製,如今改一下,鼠標移動時在移動的位置繪製三角形)效果:
代碼以下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <meta name="viewport" content="width=320,user-scalable=no" /> 6 <style type="text/css"> 7 canvas { 8 border-width: 5px; 9 border-style: dashed; 10 border-color: rgba(20, 126, 239, 0.50) 11 } 12 </style> 13 14 </head> 15 <body> 16 hello HTML5! 17 <canvas id="c1" width="300" height="300" ></canvas> 18 </body> 19 20 <script type="text/javascript"> 21 22 function getPointOnCanvas(canvas, x, y) { 23 var bbox = canvas.getBoundingClientRect(); 24 return { x: x - bbox.left * (canvas.width / bbox.width), 25 y: y - bbox.top * (canvas.height / bbox.height)}; 26 } 27 //canvas對象的取得 28 var canvas=document.getElementById("c1"); 29 //取得繪圖用的上下文對象 30 var ctx=canvas.getContext("2d"); 31 //設置Canvas的onmouse事件 32 canvas.onmousemove=function(event) 33 { 34 //取得鼠標移動處的座標 35 var x=event.pageX; 36 var y=event.pageY; 37 var canvas=event.target; 38 var loc=getPointOnCanvas(canvas,x,y); 39 console.log("mouse down at point(x:"+loc.x+",y:"+loc.y+")"); 40 41 var r=Math.random()*10+25; 42 //路徑指定 43 44 ctx.beginPath(); 45 ctx.moveTo(loc.x,loc.y); 46 ctx.lineTo(loc.x,loc.y+r); 47 ctx.lineTo(loc.x+r,loc.y+r); 48 ctx.lineTo(loc.x,loc.y); 49 50 //繪圖 51 ctx.strokeStyle="red"; 52 ctx.stroke(); 53 }; 54 </script> 55 </html>
遇到的問題,剛開始取不到鼠標移動處的座標,借鑑了http://www.jb51.net/html5/89807.html 這裏面的方法,把效果作出來了,注意console.log()的運用,看下代碼運行時的效果:
3.顏色定義
這一小節感受書上分得不太合理,我實現如下這個程序是爲了熟練下JS代碼
效果:
代碼以下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <meta name="viewport" content="width=320,user-scalable=no" /> 6 <style type="text/css"> 7 canvas { 8 border-width: 5px; 9 border-style: dashed; 10 border-color: rgba(20, 126, 239, 0.50) 11 } 12 </style> 13 <script> 14 (function(){ 15 window.addEventListener("load",function(){ 16 var ctx=document.getElementById("c1").getContext("2d"); 17 //圓1 18 ctx.beginPath(); 19 ctx.arc(150,45,35,0,Math.PI*2,false); 20 ctx.fillStyle='rgba(192,80,77,0.7)'; 21 ctx.fill(); 22 ctx.strokeStyle='rgba(192,80,77,1)'; 23 ctx.stroke(); 24 25 //圓2 26 ctx.beginPath(); 27 ctx.arc(125,95,35,0,Math.PI*2,false); 28 ctx.fillStyle='rgba(155,187,89,0.7)'; 29 ctx.fill(); 30 ctx.strokeStyle='rgba(155,187,89,1)'; 31 ctx.stroke(); 32 33 //圓3 34 ctx.beginPath(); 35 ctx.arc(175,95,35,0,Math.PI*2,false); 36 ctx.fillStyle='rgba(128,100,162,0.7)'; 37 ctx.fill(); 38 ctx.strokeStyle='rgba(128,100,162,1)'; 39 ctx.stroke();}, false); 40 })(); 41 </script> 42 </head> 43 <body> 44 hello HTML5! 45 <canvas id="c1" width="300" height="150" ></canvas> 46 </body> 47 </html>
知識點:
1)描繪輪廓線
ctx.strokeStyle="#ff0000";
2)填充輪廓
ctx.fillStyle="#0000ff";
我本身從中練習的知識點應該是
1)匿名函數 (function(){})();的使用
2)window.addEventListener("load",function(){},false);
4.繪製方法的介紹
1) 繪製圓弧的arc()方法
arc()方法的語法以下:context.arc(x,y,半徑,開始角度,結束角度,是否逆時針旋轉);
從指定的開始角度開始至結束角度爲止,按指定方向進行圓弧繪製。最後的參數爲ture時,將按逆時針旋轉。角度不是「度」,而是「弧度」。
效果:
代碼以下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <style type="text/css"> 6 canvas { 7 border-width: 5px; 8 border-style: dashed; 9 border-color: rgba(20, 126, 239, 0.50) 10 } 11 </style> 12 13 </head> 14 <body> 15 hello HTML5! 16 <canvas id="c1" width="300" height="300" ></canvas> 17 <script type="text/javascript"> 18 var canvas=document.getElementById("c1"); 19 var ctx=canvas.getContext("2d"); 20 21 //使用顏色填充矩形 22 ctx.fillStyle="#f00ff0"; 23 ctx.fillRect(0,0,300,300); 24 //描繪圓弧 25 //路徑開始 26 ctx.beginPath(); 27 var startAngle=0; 28 var endAngle=120*Math.PI/180; 29 ctx.arc(100,100,100,startAngle,endAngle,false); 30 31 //繪製處理 32 ctx.strokeStyle="#ff0000"; 33 ctx.lineWidth=3; 34 ctx.stroke(); 35 </script> 36 </body> 37 </html>
寫完後對arc()方法瞭解多一點了。x,y是圓心的座標,如今能夠想象得出是怎樣畫出來的。。。
2)繪製圓弧的arcTo()方法
arcTo()方法的語法以下:
context.arcTo(x1,y1,x2,y2,半徑);
此方法的功能是,從路徑的起點和終點分別向座標(x1,y1)、(x2,y2)繪製直線後,在繪製指定半徑的圓弧。
效果:
代碼以下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <style type="text/css"> 6 canvas { 7 border-width: 5px; 8 border-style: dashed; 9 border-color: rgba(20, 126, 239, 0.50) 10 } 11 </style> 12 13 </head> 14 <body> 15 hello HTML5! 16 <canvas id="c1" width="300" height="300" ></canvas> 17 <script type="text/javascript"> 18 var canvas=document.getElementById("c1"); 19 var ctx=canvas.getContext("2d"); 20 21 //使用顏色填充矩形 22 ctx.fillStyle="#f00ff0"; 23 ctx.fillRect(0,0,300,300); 24 //描繪圓弧 25 //路徑開始 26 ctx.beginPath(); 27 ctx.moveTo(20,20); 28 ctx.arcTo(290,150,100,280,100); 29 ctx.lineTo(20,280); 30 31 //繪製處理 32 ctx.strokeStyle="#ff0000"; 33 ctx.lineWidth=3; 34 ctx.stroke(); 35 </script> 36 </body> 37 </html>
本身改了下座標,效果加深對這個方法的理解。。。
3)quadraticCurveTo()與bezierCurveTo()方法
① quadraticCurveTo()方法用於繪製二元拋物線,其語法格式以下。
context.quadraticCurveTo(cpx,cpy,x,y);
繪製由最後指定的位置開始至座標(x,y)的曲線。此時,使用控制點爲(cpx,cpy)的二元拋物線進行鏈接,並將位置(x,y)追加到路徑中。
② bezierCurveTo()方法用於繪製三元拋物線,語法格式爲:
bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y);
繪製由最後指定路徑位置至指定位置的曲線。此時,使用控制點分別爲(cp1x,cp1y),(cp2x,cp2y)的三元拋物線進行鏈接,並將位置(x,y)追加到路徑中,具體示意圖:(qq上對圖片的修飾彷佛還不夠熟練。。。)
代碼以下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <style type="text/css"> 6 canvas { 7 border-width: 5px; 8 border-style: dashed; 9 border-color: rgba(20, 126, 239, 0.50) 10 } 11 </style> 12 13 </head> 14 <body> 15 hello HTML5! 16 <canvas id="c1" width="300" height="300" ></canvas> 17 <script type="text/javascript"> 18 var canvas=document.getElementById("c1"); 19 var ctx=canvas.getContext("2d"); 20 21 //使用顏色填充矩形 22 ctx.fillStyle="#f00ff0"; 23 ctx.fillRect(0,0,300,300); 24 //描繪圓弧 25 //路徑開始 26 ctx.beginPath(); 27 ctx.moveTo(20,20); 28 ctx.bezierCurveTo(100,280,180,280,280,20); 29 30 31 //繪製處理 32 ctx.strokeStyle="#ff0000"; 33 ctx.lineWidth=3; 34 ctx.stroke(); 35 </script> 36 </body> 37 </html>
4)繪製矩形的rect()方法
語法格式以下:context.rect(x,y,寬度,高度); x,y爲矩形左上角座標
除此以外,Canvas中還提供了三種特定的矩形繪製方法;
① context.strokeRect(x,y,w,h) 繪製矩形的輪廓
② context.fillRect(x,y,w,h) 填充矩形
③ context.clearRect(x,y,w,h) 清空矩形
這個比較好理解就不作效果演示及代碼。
5.繪製漸變效果
線性漸變與圓形漸變
線性漸變就是從左至右(或自上而下)依次顯示逐漸變化的顏色。而圓形漸變自圓心向外圍逐漸顯示變化的顏色。
1)線性漸變
指定線性漸變時使用createLinearGradient()方法,具體語法以下:
//先建立CanvasGradient對象: CanvasGradient=context.createLinearGradient(x1,y1,x2,y2); 表示由位置(x1,y1)至位置(x2,y2)顯示漸變效果
//而後追加漸變顏色:CanvasGradient.addColorStop(顏色開始的相對位置,顏色); 指定漸變中使用的顏色,第一個參數(開始相對位置)中指定一個數字,從而決定什麼位置使用什麼顏色。
舉個栗子:
代碼爲:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <style type="text/css"> 6 canvas { 7 border-width: 5px; 8 border-style: dashed; 9 border-color: rgba(20, 126, 239, 0.50) 10 } 11 </style> 12 13 </head> 14 <body> 15 hello HTML5! 16 <canvas id="c1" width="300" height="300" ></canvas> 17 <script type="text/javascript"> 18 var canvas=document.getElementById("c1"); 19 var ctx=canvas.getContext("2d"); 20 21 //繪圖 22 var g=ctx.createLinearGradient(0,0,300,0); 23 g.addColorStop(0,"rgb(255,0,0)"); //開始位置設置爲紅色 24 g.addColorStop(1,"rgb(255,255,0)"); //黃色 25 ctx.fillStyle=g; 26 ctx.fillRect(20,20,260,260); 27 </script> 28 </body> 29 </html>
2)圓形漸變
繪製圓形漸變時,使用createRadialGradient()方法建立對象,一樣使用addColorStop()方法追加漸變顏色。具體語法以下
//建立CanvasGradient對象 CanvasGradient=context.createRadialGradient(x1,y1,r1,x2,y2,r2); 經過參數指定以(x1,y1)爲圓心,半徑爲r1的圓到以(x2,y2)爲圓心,半徑爲r2的圓的漸變效果
// 追加漸變顏色 CanvasGradient.addColorStop(顏色開始的相對位置,顏色);
舉個栗子
代碼爲:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <style type="text/css"> 6 canvas { 7 border-width: 5px; 8 border-style: dashed; 9 border-color: rgba(20, 126, 239, 0.50) 10 } 11 </style> 12 13 </head> 14 <body> 15 hello HTML5! 16 <canvas id="c1" width="300" height="300" ></canvas> 17 <script type="text/javascript"> 18 var canvas=document.getElementById("c1"); 19 var ctx=canvas.getContext("2d"); 20 21 //繪圖 22 var g=ctx.createRadialGradient(150,150,50,150,150,100); 23 g.addColorStop(0.3,"red"); //開始位置設置爲紅色 24 g.addColorStop(0.7,"yellow"); 25 g.addColorStop(1.0,"blue"); //黃色 26 ctx.fillStyle=g; 27 ctx.fillRect(20,20,260,260); 28 </script> 29 </body> 30 </html>
6.繪製圖像
Canvas 中的圖像繪製
圖像繪製的基本步驟以下:
1)讀取圖像文件
2)在Canvas中進行繪製
圖像讀取前,首先建立Image對象,在Image對象的src屬性中指定圖像文件所在路徑後就能夠讀取了。讀取結束後,觸發onload事件,基本語法以下:
var image=new Image();
image.src="圖像文件路徑";
image.onload=function(){//圖像讀取時的處理}
使用Canvas上下文中的drawImage()方法將讀取後的Image對象繪製在Canvas上,其實是將Image對象中的圖像數據輸出到Canvas中。有三種drawImage()方法用於圖像的繪製
①直接繪製 context.drawImage(image,dx,dy)
②尺寸修改(resize) context.drawImage(image,dx,dy,dw,dh)
③圖像截取 context.drawImage()
第①種方法直接將讀取的圖像繪製在座標(dx,dy)處。第②種方法按照新的寬度dw與高度dh將圖像繪製在座標(dx,dy)處。第③種方法是將原圖像的一部分截取出後再按指定尺寸繪製在Canvas上,從原圖像的座標(sx,sy)開始截取寬(sw),高(sh)的部分圖像,而後繪製在Canvas上的座標(dx,dy)處,寬度爲dw,高度爲dh。
像素處理
Canvas與SVG以及Flash稍有不一樣,繪製的圖形/圖像並不能做爲對象操做。也就是說使用stroke()或者fill()方法繪製的圖形,既不能移動它也不能刪除它。若是想操做繪製的圖形/圖像,使用SVG或者Flash實現比使用Canvas要好。
Canvas中繪製的圖形/圖像做爲一個總體的位圖保存,所以能夠訪問各個像素信息。也就是說,可使用JavaScript處理Canvas上繪製的圖像像素信息。這是Canvas的一個特點
1)像素處理的API
imagedata=ctx.getImageData(sx,sy,sw,sh) 返回以(sx,sy)爲左上頂點,寬爲sw,高爲sh的矩形圖像-imagedata對象。
ctx.putImageData(imagedata,dx,dy) 將imagedata所表示的圖像繪製在頂點座標爲(dx,dy)處。
簡述之,使用getImageData()方法取出Canvas上圖像的像素數據,經過JavaScript加工過這些像素數據後,使用putImageData方法,從新繪製到Canvas中。
ImageData對象是表明圖像像素數據的對象。此對象定義了三種屬性:
①imagedata.width 圖像數據的寬度
②imagedata.height 圖像數據的高度
③imagedata.data 圖像數據(CanvasPixelArray類型)
在JavaScript中進行像素數據讀取,並進行加工與輸出時的具體操做是,從imagedata.data中獲得CanvasPixelArray類型的對象。此對象是保存像素信息的一元數組。可是與JavaScript的Array對象不一樣,不可對其進行與一般數組同樣的操做。
舉個栗子:(本例中,當用戶將桌面上的圖像文件拖動到瀏覽器中後,首先讀取圖像文件並在瀏覽器中顯示,接着對圖像進行黑白變換,在原圖的旁邊顯示變換後的圖像)
用戶將桌面上的圖像文件拖動到瀏覽器中的界面:
進行黑白變換後的效果:
代碼以下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <style type="text/css"> 6 body{ 7 font-family:宋體,Arial,Helvetica,sans-serif; 8 font-size:80%; 9 } 10 #dp{ 11 width:200px; 12 min-height:70px; 13 border:1px solid #000000; 14 background-color:#eeeeee; 15 padding:len; 16 margin:2em; 17 } 18 #dp img{ 19 margin-right:lem; 20 } 21 </style> 22 <script> 23 (function(){ 24 25 //拖動區域的div元素 26 var dp=null; 27 //FileReader接口對象 28 var reader=null; 29 30 //頁面導入時的處理 31 window.addEventListener("load",function(){ 32 //獲取拖動區域的div元素 33 dp=document.getElementById("dp"); 34 //設置dragover事件的事件偵聽 35 dp.addEventListener("dragover",function(evt){ 36 evt.preventDefault();},false); 37 //設置drop事件的事件偵聽 38 dp.addEventListener("drop",function(evt){ 39 evt.preventDefault(); 40 file_droped(evt);},false); 41 },false); 42 43 //文件被拖入時的處理 44 function file_droped(evt) 45 { 46 //清空顯示區域 47 while(dp.firstChild) 48 { 49 dp.removeChild(dp.firstChild); 50 } 51 //拖動文件的File接口對象 52 var file=evt.dataTransfer.files[0]; 53 //FileReader接口對象 54 reader=new FileReader(); 55 //非圖像文件畫像時報錯 56 if(!/^image/.test(file.type)){alert("請拖入圖像文件");} 57 //導入拖入圖像 58 reader.readAsDataURL(file); 59 reader.onload=prepare_image; 60 } 61 62 //顯示拖入圖像文件 63 function prepare_image(evt) 64 { 65 //建立img元素,顯示拖入的圖像 66 var image=document.createElement("img"); 67 image.setAttribute("src",reader.result); 68 dp.appendChild(image); 69 //img元素中導入圖像文檔後進行後續處理 70 image.onload=function(){ 71 //獲取圖像的尺寸 72 var w=parseInt(image.width); 73 var h=parseInt(image.height); 74 //建立canvas對象,導入圖像 75 var canvas=document.createElement("canvas"); 76 canvas.width=w; 77 canvas.height=h; 78 var ctx=canvas.getContext("2d"); 79 ctx.drawImage(image,0,0); 80 //取得canvas像素數據 81 var imagedata=ctx.getImageData(0,0,w,h); 82 83 //進行黑白轉換 84 convert_image_to_gray_scale(imagedata.data); 85 86 //替換canvas中的像素數據 87 ctx.putImageData(imagedata,0,0); 88 89 //顯示canvas 90 dp.appendChild(canvas); 91 } 92 } 93 94 //黑白變換函數 95 function convert_image_to_gray_scale(data) 96 { 97 var len=data.length; 98 var pixels=len/4; 99 for(var i=0;i<pixels;i++){ 100 //取出R,G,B值 101 var r=data[i*4]; 102 var g=data[i*4+1]; 103 var b=data[i*4+2]; 104 105 //進行黑白變換 106 var t=parseInt((11*r+16*g+5*b)/32); 107 //將變換後的像素數據設置到原來數組元素中 108 data[i*4]=t; 109 data[i*4+1]=t; 110 data[i*4+2]=t; 111 } 112 } 113 114 })(); 115 </script> 116 117 </head> 118 <body> 119 <div id="dp"> 120 <p>將桌面圖像文件拖動到此處。</p> 121 </div> 122 </body> 123 </html>
7.繪製數據圖表
1)繪製方格圖
繪製方格圖是爲了最終繪製折線數據圖表作準備的,方格將做爲折線圖的基準線。繪製方格圖的邏輯很簡單,只要在Canvas上繪製一系列的橫線和豎線。
效果:
代碼以下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <style type="text/css"> 6 canvas { 7 border-width: 5px; 8 border-style: dashed; 9 border-color: rgba(20, 126, 239, 0.50) 10 } 11 </style> 12 13 </head> 14 <body> 15 hello HTML5! 16 <canvas id="c1" width="300" height="300" ></canvas> 17 <script type="text/javascript"> 18 //獲取上下文 19 var canvas=document.getElementById("c1"); 20 var ctx=canvas.getContext("2d"); 21 22 //描繪背景 23 var gradient=ctx.createLinearGradient(0,0,0,300); 24 gradient.addColorStop(0,"#e0e0e0"); 25 gradient.addColorStop(1,"#ffffff"); 26 ctx.fillStyle=gradient; 27 ctx.fillRect(0,0,canvas.width,canvas.height); 28 29 //描繪邊框 30 var grid_cols=10; 31 var grid_rows=10; 32 var cell_height=canvas.height/grid_rows; 33 var cell_width=canvas.width/grid_cols; 34 ctx.lineWidth=1; 35 ctx.strokeStyle="#a0a0a0"; 36 37 ctx.beginPath(); 38 39 //準備畫豎線 40 for( var col=0;col<=grid_cols;col++) 41 { 42 var x=col*cell_width; 43 ctx.moveTo(x,0); 44 ctx.lineTo(x,canvas.height); 45 } 46 47 //準備畫橫線 48 for( var row=0;row<=grid_rows;row++) 49 { 50 var y=row*cell_height; 51 ctx.moveTo(0,y); 52 ctx.lineTo(canvas.width,y); 53 } 54 55 //完成描繪 56 ctx.stroke(); 57 </script> 58 </body> 59 </html>
接着咱們在方格圖中追加繪製數據圖表,此處用到的數據爲某種商品12個月內的銷售數量,涉及的實例數據以下:
1月 | 2月 | 3月 | 4月 | 5月 | 6月 | 7月 | 8月 | 9月 | 10月 | 11月 | 12月 |
80 | 92 | 104 | 110 | 68 | 50 | 45 | 90 | 74 | 68 | 98 | 103 |
效果圖爲:
代碼以下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <style type="text/css"> 6 canvas { 7 border-width: 5px; 8 border-style: dashed; 9 border-color: rgba(20, 126, 239, 0.50) 10 } 11 </style> 12 13 </head> 14 <body> 15 hello HTML5! 16 <canvas id="c1" width="300" height="300" ></canvas> 17 <script type="text/javascript"> 18 //獲取上下文 19 var canvas=document.getElementById("c1"); 20 var ctx=canvas.getContext("2d"); 21 22 //定義圖表數據 23 var uriage=[80,92,104,110,68,50,45,90,74,68,98,103]; 24 25 //描繪背景 26 var gradient=ctx.createLinearGradient(0,0,0,300); 27 gradient.addColorStop(0,"#e0e0e0"); 28 gradient.addColorStop(1,"#ffffff"); 29 ctx.fillStyle=gradient; 30 ctx.fillRect(0,0,canvas.width,canvas.height); 31 32 //描繪邊框 33 var grid_cols=uriage.length+1; 34 var grid_rows=4; 35 var cell_height=canvas.height/grid_rows; 36 var cell_width=canvas.width/grid_cols; 37 38 ctx.beginPath(); 39 40 //準備畫豎線 41 for( var col=0;col<=grid_cols;col++) 42 { 43 var x=col*cell_width; 44 ctx.moveTo(x,0); 45 ctx.lineTo(x,canvas.height); 46 } 47 48 //準備畫橫線 49 for( var row=0;row<=grid_rows;row++) 50 { 51 var y=row*cell_height; 52 ctx.moveTo(0,y); 53 ctx.lineTo(canvas.width,y); 54 } 55 56 //完成描繪 57 ctx.lineWidth=1; 58 ctx.strokeStyle="#a0a0a0"; 59 ctx.stroke(); 60 61 //獲取數據中最大值 62 var max_v=0; 63 for(var i=0;i<uriage.length;i++) 64 { 65 if(uriage[i]>max_v) 66 max_v=uriage[i]; 67 } 68 //爲了能讓最大值容納在圖表內,計算座標 69 max_v=max_v*1.1; 70 //將數據換算爲座標 71 var points=[]; 72 for(var i=0;i<uriage.length;i++) 73 { 74 var v=uriage[i]; 75 var px=cell_width*(i+1); 76 var py=canvas.height-canvas.height*(v/max_v); 77 points.push({"x":px,"y":py}); 78 } 79 //描繪折線 80 ctx.beginPath(); 81 ctx.moveTo(points[0].x,points[0].y); 82 for(var i=1;i<points.length;i++) 83 { 84 ctx.lineTo(points[i].x,points[i].y); 85 } 86 ctx.lineWidth=2; 87 ctx.strokeStyle="#ee0000"; 88 ctx.stroke(); 89 90 //繪製座標圖形 91 for(var i in points) 92 { 93 var p=points[i]; 94 ctx.beginPath(); 95 ctx.arc(p.x,p.y,6,0,2*Math.PI); 96 ctx.fillStyle="#ee0000"; 97 ctx.fill(); 98 } 99 </script> 100 </body> 101 </html>
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <style type="text/css"> 6 canvas { 7 border-width: 5px; 8 border-style: dashed; 9 border-color: rgba(20, 126, 239, 0.50) 10 } 11 </style> 12 <script> 13 (function(){ 14 //canvas元素對象 15 var canvas=null; 16 //canvas的2D上下文 17 var ctx=null; 18 //canvas的尺寸 19 var cw=0; 20 var ch=0; 21 22 //頁面導入時的事件處理 23 window.addEventListener("load",function(){ 24 //canvas元素的對象 25 canvas=document.getElementById("c1"); 26 //canvas的2D上下文 27 ctx=canvas.getContext("2d"); 28 // 獲取canvas的尺寸 29 cw=parseInt(canvas.width); 30 ch=parseInt(canvas.height); 31 //將座標平面向右下移動 32 ctx.translate(cw/2,ch/2); 33 //繪製時鐘 34 draw_watch(); 35 } 36 ,false); 37 38 function draw_watch() 39 { 40 //清空Canvas 41 ctx.clearRect(-cw/2,-ch/2,cw,ch); 42 //計算針的最大長度 43 var len=Math.min(cw,ch)/2; 44 //繪製刻度盤 45 var tlen=len*0.85; 46 ctx.font="14px 'Arial'"; 47 ctx.fillStyle="black"; 48 ctx.textAlign="center"; 49 ctx.textBaseline="middle"; 50 for(var i=0;i<12;i++) 51 { 52 var tag1=Math.PI*2*(3-i)/12; 53 var tx=tlen*Math.cos(tag1); 54 var ty=-tlen*Math.sin(tag1); 55 ctx.fillText(i,tx,ty); 56 } 57 58 //獲取當前時刻的時,分,秒 59 var d=new Date(); 60 var h=d.getHours(); 61 var m=d.getMinutes(); 62 var s=d.getSeconds(); 63 if(h>12) 64 {h=h-12;} 65 //繪製時針,短 66 var angle1=Math.PI*2*(3-(h+m/60))/12; 67 var length1=len*0.5; 68 var width1=5; 69 var color1="#000000"; 70 drawhand(angle1,length1,width1,color1); 71 //繪製分針,長 72 var angle2=Math.PI*2*(15-(m+s/60))/60; 73 var length2=len*0.5; 74 var width2=5; 75 var color2="#000000"; 76 drawhand(angle2,length2,width2,color2); 77 //繪製秒針 78 var angle3=Math.PI*2*(15-s)/60; 79 var length3=len*0.5; 80 var width3=5; 81 var color3="#000000"; 82 drawhand(angle3,length3,width3,color3); 83 84 //設置timer 85 setTimeout(draw_watch,1000); 86 } 87 88 //針繪製函數 89 function drawhand(angle,len,width,color) 90 { 91 //計算針端的座標 92 var x=len*Math.cos(angle); 93 var y=-len*Math.sin(angle); 94 95 //繪製針 96 ctx.strokeStyle=color; //設置顏色 97 ctx.lineWidth=width; //設置線的粗細 98 ctx.lineCap="round";//將針尖設置爲圓形 99 ctx.beginPath(); 100 ctx.moveTo(0,0); 101 ctx.lineTo(x,y); 102 ctx.stroke(); 103 } 104 })(); 105 </script> 106 </head> 107 <body> 108 hello HTML5! 109 <canvas id="c1" width="300" height="300" ></canvas> 110 </body> 111 </html>
代碼解釋: 首先看頁面導入時的事件處理代碼: window.addEventListener("load",function() { ... //將座標平面向右下移動 ctx.translate(cw/2,ch/2); //繪製時鐘 draw_watch(); },false); 上述代碼中,使用translate()方法將繪圖基點移動到Canvas的中心(向右移動一半寬度距離,向下移動一半高度距離)。後面進行繪圖處理時,座標(0,0)就變成Canvas的中心,將大大簡化時鐘座標的計算。(巧妙之處) 再看下draw_watch()函數 第一行是清空Canvas區域,由於程序中將每隔1秒鐘從新繪製整個模擬時針,以實現動態時針的動畫效果,若是不清空,上次的秒針將一直被保留 ctx.clearRect(-cw/2,-ch/2,cw,ch); clearRect()方法的參數依次爲區域左上角x,y座標,區域寬度,區域高度。由於座標平面已經移動,因此做爲基點的左上角的座標變成(-cw/2,-ch/2) 而後是,繪製刻度盤的代碼 for(var i=0;i<12;i++) { var tag1=Math.PI*2*(3-i)/12; var tx=tlen*Math.cos(tag1); var ty=-tlen*Math.sin(tag1); ctx.fillText(i,tx,ty); } 從0時到11時的時刻數字由fillText()完成繪製 這裏終點關注座標的計算,因中心座標是(0,0),因此只要肯定好角度和半徑,就能夠計算出各個時刻的座標來(注意在刻度盤數字3的位置的角度是0度) 因此這個計算公式 var angle1=Math.PI*2*(3-(h+m/60))/12;也就好理解了。同理分針和秒針也同樣。 而後要完成沒過1秒要更新的效果,這時用到定時函數setTimeout(draw_watch,1000);表示每過一秒鐘循環調用draw_watch函數自身。
2)變形的保存於恢復
① 變形的保存與恢復的方法save()與restore()的語法格式以下
context.save();
context.restore();
這兩種方法都是基於同一堆棧(stack)構造。調用save()方法後,將變形結果保存於堆棧頂端,調用restore()方法後,從堆棧頂端取出上次保存的結果用於恢復。
看一個栗子,結合了save(),restore(),及rotate()方法
效果:
代碼以下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <style type="text/css"> 6 canvas { 7 border-width: 5px; 8 border-style: dashed; 9 border-color: rgba(20, 126, 239, 0.50) 10 } 11 </style> 12 13 </head> 14 <body> 15 hello HTML5! 16 <canvas id="c1" width="300" height="300" ></canvas> 17 <script type="text/javascript"> 18 //獲取上下文 19 var canvas=document.getElementById("c1"); 20 var ctx=canvas.getContext("2d"); 21 22 23 //定義繪製矩形的方法 24 function drawRect(context,color) 25 { 26 context.fillStyle=color; 27 context.fillRect(0,0,100,30); 28 } 29 30 //定義旋轉函數 31 function rorateDeg(context,deg) 32 { 33 alert(context); 34 alert(deg); 35 var rad=deg*Math.PI/180; 36 context.rotate(rad); 37 } 38 39 //繪製普通的矩形 ---1 畫出第一個矩形 40 drawRect(ctx,"red"); 41 42 //指定移動、旋轉後繪圖 43 ctx.save(); 44 ctx.translate(100,30);//旋轉基點 45 rorateDeg(ctx,45);//旋轉45度 46 drawRect(ctx,"blue"); //---2 畫出第二個矩形 47 ctx.restore();//恢復狀態 48 49 //指定移動,旋轉後繪圖 50 ctx.save(); 51 ctx.translate(200,50);//旋轉基點 52 rorateDeg(ctx,90);//旋轉45度 53 drawRect(ctx,"green");//---3 畫出第三個矩形 54 ctx.restore();//恢復狀態 55 </script> 56 </body> 57 </html>
②變形矩陣
與變形矩陣相關的方法有兩個,即transform()與setTransform()方法。
語法爲:
setTransform(m11,m12,m21,m22,dx,dy) 變形矩陣的指定(清空先前的指定)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <style type="text/css"> 6 canvas { 7 border-width: 5px; 8 border-style: dashed; 9 border-color: rgba(20, 126, 239, 0.50) 10 } 11 </style> 12 13 </head> 14 <body> 15 hello HTML5! 16 <img src="XiaoKeAi.jpg" width="200" height="200" alt="小可愛" id="xka"/> 17 <script type="text/javascript"> 18 (function(){ 19 //不支持window.addEventListener的瀏覽器不執行代碼 20 if(!window.addEventListener) 21 { 22 return; 23 } 24 //Canvas對象 25 var canvas=null; 26 //canvas的上下文對象 27 var ctx=null; 28 //動畫的幀率 29 var fps=60; 30 //圖像對象 31 var image=null; 32 //旋轉角度 33 var deg=0; 34 35 //頁面導入時的事件處理 36 window.addEventListener("load",function(){ 37 //img元素 38 image=document.getElementById("xka"); 39 //圖像尺寸 40 var w=parseInt(image.width); 41 var h=parseInt(image.height); 42 //建立canvas對象 43 canvas=document.createElement("canvas"); 44 canvas.width=w; 45 canvas.height=h; 46 //canvas的上下文對象 47 ctx=canvas.getContext("2d"); 48 //不支持canvas的瀏覽器返回 49 if(!ctx) 50 { 51 return; 52 } 53 //將圖像繪製入canvas中 54 ctx.drawImage(image,0,0); 55 //用canvas替換img元素 56 image.parentNode.replaceChild(canvas,image); 57 //canvas的動畫開始 58 move(); 59 } 60 ,false); 61 function move() 62 { 63 //canvas尺寸 64 var cw=parseInt(canvas.width); 65 var ch=parseInt(canvas.height); 66 //初始化變形矩陣 67 ctx.setTransform(1,0,0,1,0,0); 68 //清空canvas 69 ctx.clearRect(0,0,cw,ch); 70 //計算變形矩陣 71 var m11=Math.cos(deg*Math.PI/180); 72 var dx=(cw/2)-(cw*m11/2); 73 //變形矩陣設置 74 ctx.setTransform(m11,0,0,1,dx,0); 75 //將變形後的圖像繪製入canvas中 76 ctx.drawImage(image,0,0); 77 //旋轉角度遞增 78 deg++; 79 deg=deg%360; 80 //使用timer定時繪製下一副圖 81 setTimeout(move,1000/fps); 82 } 83 })(); 84 </script> 85 </body> 86 </html>
代碼解釋:
//頁面導入時的事件處理
window.addEventListener("load",function(){
...
//將圖像繪製入canvas中
ctx.drawImage(image,0,0);
//用canvas替換img元素
image.parentNode.replaceChild(canvas,image);
//canvas的動畫開始
move();
}
,false);
首先將顯示圖標的img元素的根對象做爲參數傳遞給drawImage()方法,將圖像粘貼到canvas上,隨後調用repalceChild()方法將img元素替換爲Canvas元素。此時img元素並無從文檔中消失,img元素的跟對象能夠用於繪製各楨,能夠無限屢次使用。
而後再看下move()函數
//初始化變形矩陣
ctx.setTransform(1,0,0,1,0,0);
//清空canvas
ctx.clearRect(0,0,cw,ch);
首先將變形矩陣恢復爲默認值,這是爲了下一個清空Canvas區域時便於座標計算。
接着計算將向setTransform()方法中傳入的各參數值。爲了Canvas座標平面看起來像在立體的旋轉,只須要變更m11和dx便可。
var m11=Math.cos(deg*Math.PI/180);
var dx=(cw/2)-(cw*m11/2);
而後再設置
ctx.setTransform(0,1,m11,0,dx,0);
最後
//將變形後的圖像繪製入canvas中
ctx.drawImage(image,0,0);
就OK啦。。。
須要連續處理因此又藉助了setTimeout函數。。這個不解釋了。。。
方法 | 說明 |
context.fillText(text,x,y) | 描繪文本,參數text是將要描繪的文本,參數x與y指定了描繪位置的座標。默認狀況下以描繪對象文本的左下爲基準 |
context.fillText(text,x,y,maxWidth) | 描繪文本,參數maxWidth是可選的,指定數值後,文本將顯示在指定的寬度內,可縮小顯示。 |
context.strokeText(text,x,y) | 描繪文件的輪廓 |
context.strokeText(text,x,y,maxWidth) | 描繪文件的輪廓 |
屬性 | 說明 |
context.font | 定義文本的樣式。與CSS的font屬性設置的內容相同 |
context.textAlign | 定義文本的對齊方式,可指定start,end,left,right,center等,水平方向的基準 |
context.textBaseline | 定義文件的基準線。可指定top,hanging(羅馬字上緣),middle,alphabetic(羅馬字基線),bottom,ideographic(羅馬字下緣)等,垂直方向的基準 |
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <style type="text/css"> 6 canvas { 7 border-width: 5px; 8 border-style: dashed; 9 border-color: rgba(20, 126, 239, 0.50) 10 } 11 </style> 12 13 </head> 14 <body> 15 hello HTML5! 16 <canvas id="c1" width="400" height="300" ></canvas> 17 <table id="tb1"> 18 <caption>會員數的變化</caption> 19 <thead> 20 <tr> 21 <th>公元</th> 22 <th>2003年</th> 23 <th>2004年</th> 24 <th>2005年</th> 25 <th>2006年</th> 26 <th>2007年</th> 27 <th>2008年</th> 28 <th>2009年</th> 29 </tr> 30 </thead> 31 <tbody> 32 <tr> 33 <th>會員數</th> 34 <th>230</th> 35 <th>360</th> 36 <th>459</th> 37 <th>654</th> 38 <th>834</th> 39 <th>956</th> 40 <th>1,085</th> 41 </tr> 42 </tbody> 43 </table> 44 45 <script type="text/javascript"> 46 (function(){ 47 //不支持window.addEventListener的瀏覽器不執行代碼 48 if(!window.addEventListener) 49 { 50 return; 51 } 52 //Canvas對象 53 var canvas=null; 54 //canvas的上下文對象 55 var ctx=null; 56 57 //頁面導入時的事件處理 58 add_event_listener(window,"load",function(){ 59 //取得canvas對象 60 var canvas=document.getElementById("c1"); 61 62 //取得table元素的根對象 63 var mytb=document.getElementById("tb1"); 64 65 //繪製圖表 66 draw_graph(mytb,canvas); 67 } 68 ); 69 70 //圖表繪製 71 function draw_graph(tb,canvas) 72 { 73 //獲取canvas的上下文 74 var ctx=canvas.getContext("2d"); 75 76 //取得橫軸的顯示文字 77 var head_cells=tb.tHead.rows[0].cells; 78 79 var heads=[]; 80 for(var i=1;i<head_cells.length;i++) 81 { 82 heads.push(head_cells[i].innerHTML); 83 } 84 //取得值,計算最大值 85 var max=0; 86 var value_cells=tb.tBodies[0].rows[0].cells; 87 var values=[]; 88 for( var i=1;i<head_cells.length;i++) 89 { 90 var v=value_cells[i].innerHTML; 91 v=parseInt(v.replace(/[^\d]/g,"")); //正則表達式,將非數字的字符替換爲空格 92 values.push(v); 93 if(v>max) 94 { 95 max=v; 96 97 } 98 } 99 //定義圖表原點 100 var basex=parseInt(canvas.width*0.1); 101 var basey=parseInt(canvas.height*0.8); 102 //計算圖表的寬度與高度 103 var gw=parseInt(canvas.width*0.8); 104 var gh=parseInt(canvas.height*0.7); 105 //繪製圖表區域的背景 106 ctx.fillStyle="#eeeeee"; 107 ctx.fillRect(basex,basey-gh,gw,gh); 108 //顯示軸 109 ctx.beginPath(); 110 ctx.moveTo(basex,basey-gh); 111 ctx.lineTo(basex,basey); 112 ctx.lineTo(basex+gw,basey); 113 ctx.strokeStyle="#666666"; 114 ctx.stroke(); 115 //定義文字的字型 116 ctx.font="12px '黑體'"; 117 //描繪圖表 118 for(var i=0;i<heads.length;i++) 119 { 120 //取得圖表的值 121 var v=values[i]; 122 //豎線中心x座標 123 var x=basex+(gw/heads.length)*i+((gw/heads.length)/2); 124 //定義豎線的寬度 125 var barw=(gw/heads.length)*0.7; 126 //定義豎線的高度 127 var barh=gh*0.9*(v/max); 128 //繪製豎線 129 ctx.fillStyle="green"; 130 ctx.fillRect(x-barw/2,basey-barh,barw,barh); 131 //檢查fillText()方法是否存在 132 if(!ctx.fillText) 133 { 134 continue; 135 } 136 //間隔與值顯示寬度的最大值 137 var tw=(gw/heads.length)*0.9; 138 //將文本的座標基準設置爲center 139 ctx.textAlign="center"; 140 //繪製X軸 141 ctx.textBaseline="top"; 142 ctx.fillStyle="black"; 143 ctx.fillText(heads[i],x,basey+3,tw); 144 //繪製值 145 ctx.textBaseline="ideographic"; 146 ctx.fillStyle="black"; 147 ctx.fillText(v,x,basey-barh-3,tw); 148 } 149 } 150 function add_event_listener(elm,type,func) 151 { 152 if(!elm) 153 { 154 return false; 155 } 156 if(elm.addEventListener) 157 { 158 elm.addEventListener(type,func,false); 159 } 160 else if(elm.attachEvent) 161 { 162 elm.attachEvent('on'+type,func); 163 } 164 else 165 { 166 return false; 167 } 168 return true; 169 } 170 })(); 171 </script> 172 </body> 173 </html>
10.動畫效果
介紹兩種動畫的實現實例
1)圓球跳動的動畫
效果:
代碼:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <style type="text/css"> 6 canvas { 7 border-width: 5px; 8 border-style: dashed; 9 border-color: rgba(20, 126, 239, 0.50) 10 } 11 </style> 12 13 </head> 14 <body> 15 hello HTML5! 16 <canvas id="c1" width="300" height="300" ></canvas> 17 <script type="text/javascript"> 18 //獲取上下文 19 var canvas=document.getElementById("c1"); 20 var ctx=canvas.getContext("2d"); 21 22 //記錄圓球的狀態 23 var ball={x:10,y:100,dir_x:5,dir_y:5}; 24 //動畫 25 setInterval(drawBall,100);//每一個100毫秒調用一次drawBall()函數 26 function drawBall() 27 { 28 //繪製背景 29 ctx.fillStyle="yellow"; 30 ctx.fillRect(0,0,300,300); 31 //繪製圓球 32 ctx.beginPath(); 33 ctx.arc(ball.x,ball.y,15,0,2*Math.PI,true); 34 ctx.fillStyle="red"; 35 ctx.fill(); 36 //讓圓球運動起來 37 ball.x+=ball.dir_x; 38 ball.y+=ball.dir_y; 39 if(ball.x<0||ball.x>300) 40 { 41 ball.dir_x*=-1; 42 } 43 if(ball.y<0||ball.y>300) 44 { 45 ball.dir_y*=-1; 46 } 47 } 48 </script> 49 </body> 50 </html>
2)待機動畫
效果:
代碼:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <style type="text/css"> 6 canvas { 7 border-width: 5px; 8 border-style: dashed; 9 border-color: rgba(20, 126, 239, 0.50) 10 } 11 </style> 12 13 </head> 14 <body> 15 hello HTML5! 16 <canvas id="c1" width="300" height="300" ></canvas> 17 <script type="text/javascript"> 18 //獲取上下文 19 var canvas=document.getElementById("c1"); 20 var ctx=canvas.getContext("2d"); 21 22 //動畫繪製開始 23 var ci=0; 24 anim(); 25 //定義動畫函數 26 function anim() 27 { 28 ctx.clearRect(0,0,300,300);//清空Canvas 29 //循環繪製36根長方形棒棒 30 for(var i=0;i<36;i++) 31 { 32 ctx.save(); 33 //旋轉 34 var r=(i*10)*Math.PI/180; 35 ctx.translate(150,150);//移動中心點 36 ctx.rotate(r); 37 //繪製細長方形 38 if(i==ci) 39 { 40 ctx.globalAlpha=1.0;//半透明效果 41 } 42 else 43 { 44 ctx.globalAlpha=0.3 45 } 46 ctx.beginPath(); 47 ctx.fillStyle="red"; 48 ctx.rect(0,0,50,6); 49 ctx.fill(); 50 ctx.restore(); 51 } 52 ci=(ci+1)%36; 53 setTimeout(anim,20);//每隔20微秒調用anim函數,實現動畫效果 54 } 55 </script> 56 </body> 57 </html>
結語:終於將Canvas這章知識點學完,HTML5很好,很強大,很好玩~~