1. 程式人生 > >Canvas繪圖教程及簡單實踐

Canvas繪圖教程及簡單實踐

一、前言
    最近想嘗試用程式碼畫圖,最開始考慮的是用css,用css畫圖的本質就是不斷地拼接div,熟悉一些基本的css屬性根據需求去設定,有一定的耐心就可以實現。網上有很多優秀的例子,如下面教程中的哆啦A夢。
    https://blog.csdn.net/qq_29326717/article/details/73690980
    但是覺得這樣的方式並不靈活,在查閱資料的過程中深入瞭解了一下canvas繪圖,之前只是知道canvas繪圖功能,沒有深入接觸,瞭解之後,覺得用canvas繪圖很方便,可以靈活實現效果。


二、基本用法
    用canvas畫圖,首先要新建一個canvas畫布,注意畫布的寬高要在<canvas>標籤中設定,用css設定會導致圖片變形。


    繪圖前的基本步驟如下,首先獲取canvas畫布,在確定瀏覽器支援之後再呼叫canvas的getContext(‘2d’)方法取得2D上下文物件,就可以開始繪製圖形啦。


三、常用方法和屬性
    下面介紹一些canvas繪圖常用的方法和屬性。
    1、基本繪圖操作填充fill和描邊stroke
    2D上下文有兩種基本繪圖操作:填充和描邊,對應的兩個屬性是fillStyle和strokeStyle。例如我們取得的2D上下文物件是context,那麼我們就可以作如下設定。

    2、繪製矩形
    矩形是唯一一種可以直接在2D上下文中繪製的形狀。
    fillRect(x, y, w, h):繪製填充顏色的矩形,這裡的x,y是相對於canvas畫布的座標,畫布的左上角座標是(0, 0),向右和向下遞 增,fillRect()中的引數x,y是矩形的起始座標,w和h代表繪製矩形的寬度和高度。
    strokeRect(x, y, w, h):繪製描邊的矩形。描邊的時候可以通過lineWidth屬性調節描邊線條的寬度。
    clearRect(x, y, w, h)

:清除畫布上的矩形區域。
    演示程式碼:


    效果:


    3、繪製路徑
    canvas繪圖主要通過繪製路徑實現。
    moveTo(x, y):將繪圖遊標移動到點(x, y),一般是一個路徑的起點位置。
    lineTo(x, y):從上一個點到點(x, y)畫一條直線。


    arcTo(x1, y1, x2, y2, radius):從上一個點開始繪製一條弧線,到(x2, y2),並以給定的半徑穿過(x1, y1)。

     
    arc(x, y, radius, startAngle, endAngle, counterclockwise):以(x, y)為圓心,r = radius畫弧線,startAngle和 endAngle是起始角度和結束角度,用弧度表示,最後一個引數counterclockwise表示是否按逆時針方向畫圖,true為逆時針方向,false為順時針方向。預設是false即順時針方向。

 


    rect(x, y, width, height):從(x, y)開始繪製一個寬等於width高等於height的矩形,這個矩形是路徑,與之前用strokeRect()繪製的獨立矩形不一樣。
    quadraticCurveTo(cx, cy, x ,y):從上一點開始繪製一條二次貝塞爾曲線,(x, y)是結束點,(cx, cy)是控制點。
 


    bezierCurveTo(c1x, c1y, c2x, c2y,x, y):從上一點開始繪製一條三次貝塞爾曲線,(x, y)是結束點,(c1x, c1y), (c2x, c2y)是控制點。
 


    fill():填充路徑
    stroke(): 路徑描邊,
    注意著兩者的使用順序,以下是對比
 


    先描邊再填充的線條只有線條寬度的一半,因為後來填充的原因被覆蓋了一半的寬度。
    以上這些是最基本的圖形路徑,要得到複雜圖形,就要精細計算和排列。我自己做了一個小demo,連結在文後,想參考的小夥伴可以開啟看看。

    4、beginPath()和closePath()
    beginPath()
    繪製一個新路徑前必須呼叫該方法,因為canvas路徑是以上一點為起始畫的,比如我們畫好了一條直線,我們想畫第二條平行線,如果沒有在再次繪製之前呼叫beiginPath()的話,就會會出現下面的情況,


    我們想要得到的是兩條平行線,但是第一條線的末尾卻和第二條線相連了,這是因為我們沒有重新beginPath,canvas只是在畫一條路徑,就會出現上圖的情況,加上beginPath後就沒有問題了。

 

    closePath()
    說到beginPath就要提到closePath(),closePath()嘗試從畫筆結束的點到路徑起始點畫一條直線。
    如果沒有呼叫closePath畫出來的線是這樣,

 
    加了closePath()之後就是一條閉合路徑


    四、將canvas畫布匯出為圖片
    canvas繪製的圖形可以匯出為圖片,呼叫canvas的toDataURL()方法,利用a標籤實現下載。預設是png格式,也可以自定義成jpeg,但是這個方法是後來才追加的,使用的時候要注意瀏覽器是否支援。


    五、畫布變換
    除了繪製路徑,我們還可以對畫布進行調整,有
    Translate(), scale(), rotate(),  setTransform()和transform()這幾種方法,具體可以參考:
    https://www.cnblogs.com/fangsmile/p/5647390.html
    需要注意的是對畫布進行操作時,要使用save()和restore()來儲存和恢復狀態。如果不用save()函式的話, 下一次變換的參照就不是初始位置,而是上一次變換結束的位置,例如第一次變換了30度,如果不使用save(),那麼我們執行第二次變換60度時,出來的效果就是變換了30+60度,使用save()才會得到想要的60度變換。

    以上就是我自己總結的一些canvas繪圖的知識點,我自己做了一個小demo,你可以在頁面上檢視效果:
    http://feiyu.qywyyztp.top/#/painting


    這是我個人網站的一個頁面,我的個人網站專案程式碼託管在github上,歡迎訪問:
    https://github.com/Lindsayyyy/My-Website