HTML5☞canvas

 <canvas>便籤用於繪製圖像,圖表。不過,<canvas> 元素本身並沒有繪製能力(它僅僅是圖形的容器) - 您必須使用腳本JavaScript來完成實際的繪圖任務。既然你要畫出你想要的圖案,你給有畫布啊,總不能在空氣中畫畫啊,所以第一步你要創建一個畫布,給畫布一個寬高能裝下你的畫。<canvas width="500" height="500" id="canvas"></canvas>。

canvas開始標籤和結束便籤可以填充內容,填充的內容是後備信息, 如果瀏覽器不支持canvas元素,就會顯示這個後備信息。因爲是js控制,所以在腳本語言獲取這個元素。var Canvas = document.getElementById('canvas');畫布創建好了,要在這個畫布上繪圖,就須取得繪圖上下文。而取得繪圖上下文的對象引用,需調用getContext()方法並傳入上下文的名字,傳入‘2d’,就可以取得2D上下文對象。在使用canvas之前,首先要檢測getContext()方法是否存在。這一步非常重要。

if(canvas.getContext ){

  var  context = canvas.getContext("2d");

  context . strokeStyle = "red";

  context . fillStyle = "blue"

  ......

}

使用2D繪圖上下文提供的方法,可以簡單繪製2D圖形,比如矩形,弧線,和路徑 。2D上下文的座標開始於canvas元素的左上角,原始座標是(0,0)。所有座標值都是基於這個原點計算。         

填充和描邊 :填充就是用指定的樣式(顏色 漸變或圖像)填充圖形,描邊,就是隻在圖形的邊緣劃線。填充和描邊取決於兩個屬性fillStylestrokeStyle  這兩個屬值可以是字符串漸變對象,模式對象。             
繪製矩形:方法包括fillRect(),strokeRect() clearRect();這三個方法都接受4個參數,矩形x座標,y座標,矩形寬度,矩形高度。
 
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
  var context = canvas.getContext('2d');
  context.fillStyle = 'red';               //繪製紅色矩形
  context.fillRect(100, 100, 100, 100);
  context.fillStyle = 'rgba(0,0,255,0.5)'; //繪製半透明藍色矩形
  context.fillRect(150, 150, 100, 100);
}

clearRect()方法用於清除畫布上的矩形區域,本質上,這個方法可以把繪製上下文中的某一矩形區域變透明。

 

canvas  線段樣式 

context.lineCap='butt | round | square';
鏈接的線段是不會帶有圓或者方塊的
 
當兩條線條交匯時,創建邊角樣式
context.lineJoin='miter | bevel | round';

 

 

 miterLimit = 10;(默認值)只有當lineJoin爲miter時有效

 斜街長度:內角與外角的距離,當lineJoin是miter時,用於控制斜接部分的長度  miterLimit。如果斜街長度超過miterLimit的值,就會自動變成bevel   實際運算時大於limit * lineWidth / 2的值。

 

 繪製路徑
 
繪製路徑可以創造出複雜的形狀和線條。要繪製路徑,首先必須調用beginPath()方法,表示要開始繪製新路徑。然後在調用下列方法繪製實際路徑。
moveTo(x,y) 將遊標移動到(x,y),不劃線。
lineTo(x,y)    從上一點開始繪製一條直線,到(x,y)
pen.lineWidth=15;
pen.moveTo(100,100);
pen.lineTo(300,100);             //圖片中最粗的那條線
pen.strokeStyle = 'red';
pen.stroke();
 
pen.lineWidth=5;                 //畫筆由15改成5
pen.strokeStyle = 'yellow';      //顏色變黃色
pen.lineTo(200,200);        //接着上面的點畫。最末端點垂直坐高垂直於紅色的那條
pen.moveTo(300,100)         //改變起點
pen.lineTo(100,150);                        
pen.stroke();

pen.strokeStyle = 'black';
 
pen.lineWidth=1;
pen.lineTo(50,150);
pen.lineTo(50,450);
pen.stroke();

 

我們發現他們是一個路徑的(就想是一個集合),也就是你改變筆的粗細和顏色會整體改變,原因就是canvas是根據狀態進行繪製的,當改變顏色時會把當前狀態下所有的顏色進行繪製。而先前繪製的不會消失的。

那要怎麼讓他們不是同一個路徑呢?用這個就可以了pen.beginPath(); 開始子路徑一個新的集合 就可以設置顏色 和 粗細了 。

pen.closePath()的作用是關閉路徑,如果當前的圖形不是封閉的,會封閉圖形。pen.beginPath()和pen.closePath()不用同時存在。

 
canvas畫弧
 
pen.arc(圓心座標,圓心座標,起始弧度,結束弧度,弧形方向);
 
也就是說無論是順時針畫弧還是逆時針畫弧,規定的pi的位置都是固定的。
 
pen.moveTo(100,100);   
pen.arc(100, 100, 30, Math.PI * 0 , Math.PI / 0.5, 0);此時的順時針就是1/4圓,逆時針就是3/4圓。 
注意起始弧度和結束弧度都是用PI的形式表示。 0順時針  1逆時針
pen.closePath();
pen.stroke();
畫出來

pen.aracTo(x1,y1,x2,y2,r); 從上一點開始繪製一條弧線(圓角)

繪製的弧線與當前點的x1,y1連線,x1,y1和x2,y2連線相切

畫一個圓角矩形

pen.moveTo(120, 100);
pen.arcTo(200, 100, 200, 200, 20);
pen.arcTo(200, 200, 100, 200, 20);
pen.arcTo(100, 200, 100, 100, 20);
pen.arcTo(100, 100, 200, 100, 20);
pen.stroke();

canvas畫貝塞爾曲線

pen.quadraticCurveTo(x1, y1, ex, ey);    二次貝塞爾曲線

x1 y1 控制點         ex  ey結束點

pen.moveTo(100, 100);
pen.quadraticCurveTo(200, 200, 300, 100);
pen.stroke();
pen.bezierCurveTo(x1, y1, x2, y2, ex, ey); 三次貝塞爾曲線
兩個控制點   一個結束點
pen.moveTo(100, 100);
pen.bezierCurveTo(200, 50, 300, 200, 400, 50);
pen.stroke();

創建路徑後,接下來有幾種可能的選擇,如果繪製一條連接到路徑的起點線條,可以使用closePath();
如果路徑以完成,你想用fillStyle填充他,可以調用fill()方法。另外,還可以調用stroke()方法對路徑描邊,最後還可以調用clip(),這個方法可以在路徑上創建一個剪裁區域。
 

canvas 繪製文本

 

繪製文本主要有兩個方法,fillText()strokeText(),這兩個方法都接收4個參數 fillText(“文本字符串” ,文字x座標,Y座標,可選的最大像素),

fillText() 用 fillStyle()屬性繪製文本,strokeText() 用 strokeStyle()屬性爲文本描邊

而且這兩個方法都已下列3個屬性爲基礎。

  • font(“font-style  font-variant  font-weight  font-size  font-family”)其中默認值是:20px sans-serif也就是說這兩個值是必須設定的
  • textAlign=“ left ” | “ center ” | “ right | start | end ”    文本對齊方式
  • textBaseline="  "   可選值見下面,文本的基線

文字基線對齊方式 textBaseline

屬性

由於繪製文本比較複雜,特別是需要把文本控制在某一區域中的時候,2D上下文提供了輔助確定文本大小的方法measureText(),這個方法接收一個參數,及要繪製的文本。返回一個TextMetrics對象,對象目前只有一個屬性width屬性。measureText()利用font, textAlign 和textBaseline的當前值計算指定的文本大小。

假設你想在一個140像素寬的矩形區域繪製文本,下面的代碼從100像素的字體開始遞減,最終會找到合適的字體大小。

var fontsize = 100;
context.font = fontsize + 'px Arial';

while (context.measureText("hellow World").width > 140) {
  fontsize--;
  context.font = fontsize + 'px Arial';
}
context.fillRect(100, 100, 140, 140);
context.fillText("hellow World", 100, 100);
context.fillText("fontseizeis"+fontsize, 30, 30);

 

canvas座標軸旋轉(跟css3的轉換差不多)
 
1.translate(dx,dy)位置重新映射畫布上的(0,0)
pen.translate(100, 100);
pen.strokeRect(0, 0, 100, 100);
2.scale(sx,sy)  縮放當前的繪圖
3.rotate(Math.PI)旋轉當前的繪圖
4.save() restore ()
保存當前圖像狀態的一份拷貝(保存畫布狀態)壓如棧中
從棧中彈出存儲的圖形狀態並恢復
5.setTransform(  a  ,  b  ,  c  ,  d  ,  e  ,  f  )先重置,在變換
參數:水平縮放 水平傾斜 垂直傾斜 垂直縮放 水平移動 垂直移動
transform(a,b,c,d,e,f)在之前的狀態基礎上變換
 
canvas 在水平和垂直方向重複圖像:
1.createPattern(image,“repeat | repeat-x | repeat-y | no-repeat”);
img元素(Image對象),canvas元素 ,video元素(有圖形的)
var img = new Image();
img.src = "hat.png";      //異步加載圖片所以用onload保證加載完成
img.onload = function(){
  var bg = pen.createPattern(img, "repeat");
  pen.fillStyle=bg;
  pen.fillRect(0,0,100,100);
 
}

 

重複canvas元素

 

 

canvas繪製圖像 

 

drawImage() 方法在畫布上繪製圖像、畫布或視頻。

drawImage() 方法也能夠繪製圖像的某些部分,以及/或者增加或減少圖像的尺寸。

context.drawImage(img,x,y); 在canvas的位置

context.drawImage(img,x,y,width,height); 在畫布上定位圖像,並規定圖像的寬度和高度:

context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height); 前四個設定目標元素的位置和寬高,後四個設定canvas元素定位位置寬和高

 

canvas漸變

 

線性漸變

createLinearGradient(x1,y1,x2,y2);線性漸變必須在填充漸變區域裏定義漸變,否則沒有效果。

把線性漸變保存在一個變量bg裏,bg.addColorStop(numbe(小數),顏色);  把變量填充fillStyle.

徑向漸變

createRadialGradient(x1, y1, r1, x2, y2, r2);   起始點的座標和半徑    結束點的座標和半徑
 

 

 canvas 陰影

shadowColor   shadowOffsetX     shadowOffsetY       shadowBlur

 

canvas剪切

clip() 方法從原始畫布中剪切任意形狀和尺寸。

提示:一旦剪切了某個區域,則所有之後的繪圖都會被限制在被剪切的區域內(不能訪問畫布上的其他區域)。您也可以在使用 clip() 方法前通過使用 save() 方法對當前畫布區域進行保存,並在以後的任意時間對其進行恢復(通過 restore() 方法)。

整個畫布都設置透明度globalAlpha = 1(默認值)

canvas 合成(新像素和舊像素的合併方式)

默認source-over  常用source-over   destination-over  copy

 

將canvas內容導出  (注意:受同源策略限制,需開啓服務器,否則會報錯)canvas.toDataURL();是canvas自身的方法不是上下文對象。將canvas的內容抽取成一張圖片以base64的編碼格式,將canvas的內容放入ing元素裏

獲取canvas像素信息

getImageData() 方法返回 ImageData 對象,該對象拷貝了畫布指定矩形的像素數據。

對於 ImageData 對象中的每個像素,都存在着四方面的信息,即 RGBA 值:

  • R - 紅色 (0-255)
  • G - 綠色 (0-255)
  • B - 藍色 (0-255)
  • A - alpha 通道 (0-255; 0 是透明的,255 是完全可見的

getImageData(x,y,dx,dy);//受同源策略

您也可以使用 getImageData() 方法來反轉畫布上某個圖像的每個像素的顏色。

var imgData=ctx.getImageData(10,10,50,50);
ctx.putImageData(imgData,10,70);

putImageData(imgData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight);

canvas命中檢測    isPointPath(x,y)檢測是否在區域內    isPointStroke(x,y)檢測是否在直線上   返回 true 或  false

還可以檢測當前的的像素值,如果爲透明,則該點不在路徑上

Canvas的fill方法之“非零環繞原則nonzero”與“奇偶原則evenodd”https://www.jianshu.com/p/d4b8b5d931df

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章