1. 程式人生 > >canvas基礎語法

canvas基礎語法

ole 高度 doc net 中心 ted ise 另一個 關於

前面的話

  canvas顧名思義是定義在瀏覽器中的畫布。它不僅是一個普通的元素,更是一個強大的編程工具。它的出現已然超過了web基於文檔的設計初衷,將網頁這一形態的應用推向了另一個高度。利用canvas,可以開發出復雜的動畫、動態圖表、遊戲等。關於canvas,有這樣一句話——canvas就像是一場文藝復興,將編程工作者徹底釋放出創造力。本文將詳細介紹canvas基礎知識

添加canvas

  在HTML中添加Canvas非常簡單,只需要在HTML的<body>部分,添加上<canvas>標簽就可以了

<canvas>
    <p>The canvas element is not supported!</p>
</canvas>

  現在,頁面是一個完完全全的空白頁面。Canvas的本意是畫布,畫布在HTML5中是透明的,是不可見的

【HTML屬性】

  在網頁上使用canvas元素時,它會創建一塊矩形區域。默認情況下,canvas的寬為300px,高為150px

技術分享

  canvas支持HTML屬性高度height和寬度width,可以在開始和結束標簽之間加入HTML來提供後備內容

height    高度
width     寬度
<canvas width="600" height="300">
    <p>The canvas element is not supported!</p>
</canvas>
技術分享

  [註意]重置canvas的寬或高可以達到清空畫布的效果

【CSS樣式】

  同大多數HTML元素一樣,canvas元素也可以通過應用CSS的樣式來增加邊框,設置內外邊距等。而且一些CSS屬性還可以被canvas內的元素繼承。比如字體樣式,在canvas內添加的文字,默認同canvas元素本身是一樣的。此外,在canvas中為繪圖上下文設置屬性同樣要遵循CSS語法

技術分享

  [註意]通過CSS樣式設置的寬高,是canvas元素的實際占據寬高;通過屬性值設置的寬度,是canvas內部編程的設置寬高;如果沒有通過CSS樣式設置寬度,則canvas元素實際占據寬高等於內容編程設置寬度

  如果按照如下進行設置,則canvas的最終寬高為400*100,相當於內部元素寬度縮小2.5倍,高度縮小2倍

    canvas.width = 1000;
    canvas.height = 200;
    canvas.style.width = ‘400px‘;  
    canvas.style.height = ‘100px‘; 

  如果按照如下進行設置,則canvas的最終寬高為400*40,相當於內部元素寬度和高度等比例縮小2.5倍

    canvas.width = 1000;
    canvas.height = 200;
    canvas.style.width = ‘400px‘;  

 

繪圖上下文

  要在canvas上繪圖,需要以下三個步驟

  1、布置畫布:通過添加<canvas>標簽,添加canvas元素

  2、獲取畫布:通過<canvas>標簽的id,獲得canvas對象

  3、取得繪圖上下文:通過canvas對象的getContext("2d")方法,獲得2D環境;如果要獲取三維上下文,使用"webgl"

  上面的三個步驟對應如下代碼

<canvas id=“canvas”></canvas>
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d")

【canvas坐標】

  使用2D上下文提供的方法可以繪制簡單的2D圖形,比如矩形、弧線和路徑。2D上下文坐標開始於canvas元素的左上角,原點坐標是(0,0)。所有坐標值都基於這個原點計算,x值越大表示越靠右,y值越大表示越靠下。默認情況下,width和height表示水平和垂直兩個方向上可用的像素數目

技術分享

填充和描邊

  2D上下文的兩種基本繪圖操作是填充和描邊

  填充是指用指定的樣式(顏色、漸變和圖像)填充圖形;描邊是只在圖形的邊緣畫線

  大多數2D上下文操作都會細分為填充和描邊兩個操作,而操作的結果取決於兩個屬性:fillStyle和strokeStyle。這兩個屬性的值可以是字符串表示的顏色、漸變對象或模式對象,它們的默認值都是#000

var context = drawing.getContext(‘2d‘);
context.strokeStyle="red";
context.fillStyle="#00f";

  關於漸變和模式對象,稍後介紹

繪制矩形

  下面先從最簡單的矩形繪制開始說起,矩形是唯一一種可以直接在2D上下文中繪制的形狀,與矩形相關的方法包括fillRect()、strokeRect()、clearRect()。這三個方法都能接收4個參數:矩形的x坐標、矩形的y坐標、矩形寬度和矩形高度。這些參數的單位都是像素

fillRect(x,y,w,h):畫布上繪制的矩形會填充通過fillStyle屬性指定的顏色
strokeRect(x,y,w,h):畫布上繪制的矩形會使用通過strokeStyle屬性指定描邊顏色    
clearRect(x,y,w,h):用於清除畫布上的矩形區域。本質上這個方法可以把繪制上下文中的某一矩形區域變透明。通過繪制形狀然後再清除指定區域,就可以生成有意思的效果

  下面來繪制一個背景顏色為紅色,尺寸為100*100,位置為(0,0)點的矩形

技術分享
<canvas id="drawing" style="border:1px solid black">
    <p>The canvas element is not supported!</p>
</canvas>
<script>
var drawing = document.getElementById(‘drawing‘);
//確定瀏覽器支持<canvas>元素
if(drawing.getContext){
    var context = drawing.getContext(‘2d‘);
    context.fillRect(0,0,100,100);
    context.fillStyle = ‘red‘;
} 
</script>
技術分享

  結果如下,背景顏色為黑色。這是因為,使用fillRect()方法時,會使用當前的fillStyle值。由於當前還沒有設置,所以會使用默認的黑色值

技術分享

  進行如下修改後,結果符合預期

技術分享
<script>
var drawing = document.getElementById(‘drawing‘);
if(drawing.getContext){
    var context = drawing.getContext(‘2d‘);
   context.fillStyle = ‘red‘;
   context.fillRect(0,0,100,100);
} </script>
技術分享 技術分享

  下面來繪制一個半透明的藍色描邊矩形,尺寸為100*100,位置在(0,0)點

技術分享
<script>
var drawing = document.getElementById(‘drawing‘);
if(drawing.getContext){
    var context = drawing.getContext(‘2d‘);
   context.strokeStyle = ‘rgba(0,0,255,0.5)‘;
   context.strokeRect(0,0,100,100);
} </script>
技術分享 技術分享

  接下來,在(0,0)點繪制尺寸為100*100背景為半透明紅色的矩形, 1s後在(50,50)點繪制尺寸為100*100,描邊為半透明藍色的矩形,1s後使用clearRect()清除矩形

技術分享
<canvas id="drawing" style="border:1px solid black">
    <p>The canvas element is not supported!</p>
</canvas>
<script>
var drawing = document.getElementById(‘drawing‘);
if(drawing.getContext){
    var context = drawing.getContext(‘2d‘);
    context.fillStyle = ‘rgba(255,0,0,0.5)‘;
    context.fillRect(0,0,100,100);
    setTimeout(function(){
      context.strokeStyle = ‘rgba(0,0,255,0.5)‘;
      context.strokeRect(50,50,100,100);  
    },1000);
    setTimeout(function(){
      context.clearRect(0,0,300,150);
    },2000);    
} 
</script>
技術分享 技術分享

繪制文本

  繪制文本主要有兩個方法:fillText()和strokeText(),fillText()方法使用fillStyle屬性繪制文本,strokeText()方法使用strokeStyle屬性為文本描邊

  這兩個方法都可以接收4個參數:要繪制的文本字符串、x坐標、y坐標和可選的最大像素寬度

  若傳入的字符串大於最大寬度時,則繪制的文本字符的高度正確,而寬度會收縮以適應最大寬度。而且這兩個方法都以下列3個屬性為基礎:font、textAlign、textBaseline

font(與font集合樣式寫法相同)
textAlign(start\end\center)不建議使用left\right,默認為start
textBaseline(top\hanging\middle\alphabetic\ideographic\bottom),默認為alphabetic

【measureText()】

  由於繪制文本比較復雜,特別是需要把文本控制在某一區域的時候,因此提供了輔助確定文本大小的方法measureText()方法。該方法接收一個參數,即要繪制的文本,返回一個TextMetrics對象,該對象只有一個width屬性。measureText()方法利用font、textAlign、textBaseline的當前值計算指定文本的大小

  假設想在一個100px寬的矩形區域中繪制文本"小火柴",下面代碼從50px字體大小開始遞減,最終會找到合適的字體大小

技術分享
<script>
var drawing = document.getElementById(‘drawing‘);
if(drawing.getContext){
    var context = drawing.getContext(‘2d‘);
    var fontSize = 50;
    context.font= fontSize + ‘px arial‘;
    while(context.measureText(‘小火柴‘).width > 100){
        fontSize--;
        context.font= fontSize + ‘px arial‘;
    }
    context.fillText(‘小火柴‘,10,30);
    context.fillText(‘字體大小是‘ + fontSize + ‘px‘ ,10,80);    
} 
</script>
技術分享 技術分享

描邊線條

  關於描邊線條有4個常用屬性分別是lineWidth、lineCap、lineJoin和miterLimit

lineWidth:描邊線條寬度(默認為1)
lineCap:描邊線條末端形狀是平頭、圓頭還是方頭(butt、round、square)(默認為butt)
lineJoin:描邊線條相交方式是圓交、斜交還是斜接(round、bevel、miter)(默認為miter)
miterLimit:描邊線條的最大斜接長度

  斜接長度是指兩條交匯處內角和外角之間的距離,邊角的角度越小,斜接長度就越大,為了避免斜接長度過長,可以使得miterLimit屬性,如果斜接長度超過miterLimit的值,邊角會以lineJoin的"bevel"類型來顯示

  [註意]只有當lineJoin屬性為"miter"時,miterLimit才有效

技術分享 技術分享

漸變

  填充和描邊除了可以取顏色值之外,還可以取漸變值,漸變由canvasGradient實例表示

【創建漸變】

  漸變分為線性漸變和徑向漸變

  調用createLinearGradient()方法創建線性漸變,這個方法接收4個參數:起點的x坐標、y坐標,終點的x坐標、y坐標

  調用createRadialGradient()方法創建徑向漸變,這個方法接收6個參數,對應兩個圓的圓心和半徑。前三個參數指定起點圓的圓心(x和y)及半徑。後三個參數指定終點圓的圓心(x和y)及半徑。可以把徑向漸變想象成一個長圓桶,而這6個參數定義的正是這個桶的兩個圓形開口的位置

  [註意]如果想從某個形狀的中心點開始創建一個向外擴散的徑向漸變效果,要將兩個圓定義為同心圓

【指定色標】

  接下來使用addColorStop()方法來指定色標。這個方法接收兩個參數:色標位置和CSS顏色值。色標位置是一個0(開始的顏色)到1(結束的顏色)之間的數字

  最後將漸變對象實例賦值給fillStyle或strokeStyle,進而可以繪制圖形

  下面來創建一個垂直方向的從品紅到淺藍色的線性漸變

技術分享
<canvas id="drawing" style="border:1px solid black">
    <p>The canvas element is not supported!</p>
</canvas>
<script>
var drawing = document.getElementById(‘drawing‘);
if(drawing.getContext){
    var context = drawing.getContext(‘2d‘);
    var linearGradient = context.createLinearGradient(0,0,0,100);    
    linearGradient.addColorStop(0,‘pink‘);
    linearGradient.addColorStop(1,‘lightblue‘);
    context.strokeStyle = linearGradient;
    context.fillStyle = linearGradient;
    context.fillRect(10,10,100,100);
    context.strokeRect(120,10,100,100);
    context.font="20px/50px 宋體";
    context.textAlign = ‘end‘;
    context.textBaseline = ‘top‘;
    context.strokeText("小火柴",290,10);    
} 
</script>
技術分享 技術分享

  下面來創建一個從品紅到淺藍色的徑性漸變

技術分享
<canvas id="drawing" style="border:1px solid black">
    <p>The canvas element is not supported!</p>
</canvas>
<script>
var drawing = document.getElementById(‘drawing‘);
if(drawing.getContext){
    var context = drawing.getContext(‘2d‘);
    var radialGradient = context.createRadialGradient(50,50,0,50,50,50);    
    radialGradient.addColorStop(0,‘pink‘);
    radialGradient.addColorStop(1,‘lightblue‘);
    context.fillStyle = radialGradient;
    context.fillRect(0,0,100,100);    
} 
</script>
技術分享 技術分享

繪制路徑

  繪制路徑包括開始繪制、實際繪制和結束繪制三個步驟

【開始繪制】

  要繪制路徑,首先必須調用beginPath()方法,表示要開始繪制新路徑

  [註意]beginPath()之後的strokeStyle或fillStyle用於當前路徑

【實際繪制】

  實際繪制路徑時可以使用以下方法:

  1、moveTo(x,y):將繪圖遊標移動到(x,y),不畫線。如果其他方法需要使用上一點的坐標,一定要先使用moveTo(x,y)確定坐標

context.moveTo(100,100)

  表示移動畫筆至(100,100)這個點(單位是px)

  2、lineTo(x,y):從上一點開始繪制一條直線,到(x,y)為止

context.lineTo(600,600)

  表示從上一筆的停止點繪制到(600,600)

  3、arcTo(x1,y1,x2,y2,radius):從上一點開始繪制一條弧線到(x2,y2)為止,並以給定半徑radius穿過(x1,y1)

context.arcTo(30,80,100,100,60);

  表示從上一點開始繪制一條弧線到(100,100)為止,該弧線穿過(30,80),且半徑為60

  4、arc(x,y,radius,startAngle,endAngle,counterclockwise):以(x,y)為圓心繪制一條弧線,弧線半徑為radius,起始和結束角度(用弧度表示)分別為startAngle和endAngle。最後一個參數表示startAngle和endAngle是否按逆時針方向計算。默認值為false表示按順時針方向計算

技術分享
context.arc(50,50,40,0,2*Math.PI,false);

  表示以(50,50)為圓心繪制一條弧線,半徑為40,起始和結束角度分別為0和2PI,按順時針方向計算

  5、bezierCurveTo(c1x,c1y,c2x,c2y,x,y):從上一點開始繪制一條曲線,到(x,y)為止,並且以(c1x,c1y)和(c2x,c2y)為控制點

context.bezierCurveTo(0,50,100,50,100,0);

  表示從上一點開始繪制一條曲線,到(100,0)為止,並且以(0,50)和(100,50)為控制點

  6、quadraticCurveTo(cx,cy,x,y):從上一點開始繪制一條二次曲線,到(x,y)為止,並且以(cx,cy)為控制點

context.quadraticCurveTo(50,50,0,100);

  表示從上一點開始繪制一條二次曲線,到(0,100)為止,並且以(50,50)為控制點

  7、rect(x,y,width,height):從點(x,y)開始繪制一個矩形,寬度和高度分別由width和height指定。這個方法繪制的是矩形路徑,而不是strokeRect()和fillRect()所繪制的獨立的形狀

context.rect(20,20,50,50);

  表示從(20,20)開始繪制一個矩形,寬高分別是50和50

【結束繪制】

  創建路徑後有以下4種選擇

  1、用fillStyle填充,調用fill()方法

  2、用strokeStyle描邊,調用stroke()方法

  [註意]如果fill()和stroke()同時使用,應該先使用fill(),後使用stroke()。否則,fill()會覆蓋stroke()的部分線條寬度

  3、在路徑上創建一個剪切區域,調用clip()方法

  [註意]canvas中的clip()方法用於從原始畫布中剪切任意形狀和尺寸。一旦剪切了某個區域,則所有之後的繪圖都會被限制在被剪切區域內(不能訪問畫布上的其他區域)。也可以在使用clip()方法前通過使用save()方法對當前畫布區域進行保存,並在以後任意時間通過restore()方法對其進行恢復。可以使用clip()實現類似於探照燈效果

  4、繪制一條連接到路徑起點的線條,調用closePath()方法

  在2D繪圖上下文中,路徑是一種主要的繪圖方式,因為路徑能為要繪制的圖形提供更多控制。由於路徑的使用很頻繁,所以有一個isPointInPath()方法,接收x和y坐標作為參數,用於在路徑被關閉之前確定畫布上的某一點是否位於路徑上

if(context.isPointInPath(100,100)){
    console.log(‘this point is in the path‘);
}

canvas基礎語法