寫於 2016.01.25
喜歡前端,學習前端的最原始的動機,就是因為它可以製作非常酷炫的效果。然而現在上班所用的技巧,多是在業務邏輯那一塊,並非是我最初想要去做的東西。所以在下班以後,打算重新拾起自己的興趣,去學習真正的“酷炫”的東西。 Canvas,就是能夠讓我實現目標的利器之一。希望通過這一個筆記,能夠督促我高效完成學習,並且把學習的感悟分享出來。
學習資源來自慕課網/炫麗的倒數計時效果Canvas繪圖與動畫基礎,非常感謝@liuyubobobo 老師的課程分享!
建立標籤
html5的<canvas>
標籤定義了一塊“畫布”,我們所有的繪圖都是基於這一塊畫布。所以在頁面上我們先宣告一個帶id的canvas標籤
為什麼直接在標籤裡面定義width
和height
呢,是因為
這裡面的
width
和height
是canvas自己的屬性,並非css3的屬性。如果只用css3定義寬高的話只是限制了這塊畫布的大小,對內容的解析度等顯示問題並無約束(這句話有待考證)。而直接在標籤裡定義這兩個屬性的好處是能夠一併地解決畫布大小與實際顯示的問題。
標籤中間的文字內容是當瀏覽器不支援canvas自動出現的提示性話語,在瀏覽器支援canvas時這句話會被省略。
在建立好頁面標籤以後,開始進入實際的canvas繪製。它是完全通過js控制的,所以我們有關畫圖的一切都是在js中進行
建立繪圖上下文
在js中,我們這樣定義:
var canvas = document.getElementById('canvas');
var cxt = canvas.getContext('2d');
首先獲取canvas物件,然後執行它的.getContext('2d')
方法,建立一個繪圖上下文環境cxt
。以後所有在這一塊畫布進行的繪製,都是呼叫這個cxt不同的方法來完成。環境搭建好了,就可以進行真正的操作啦!
繪製圖形
教程上說得很明白,在這裡就不繼續贅述了,主要總結出不同方法的作用,效果,及其注意事項。
//把筆尖放在畫布100, 100的位置 複製程式碼
cxt.moveTo(100, 100)
//從100,100畫到700,700
cxt.lineTo(500,500)
//繼續畫完它
cxt.lineTo(500,100)
cxt.lineTo(100,100)
//設定線條寬度
cxt.lineWidth = 5
//設定線條樣式(顏色)
cxt.strokeStyle = 'pink'
//設定填充色
cxt.fillStyle = 'lightblue'
cxt.fill()
//告訴canvas我畫完了,執行stroke()方法
cxt.stroke()
複製程式碼
老師在教程裡反覆強調了一點,就是canvas是基於“狀態”的繪圖,也就是當我怎樣定義moveTo()
,lineTo()
之類的方法的時候,我定義的是一種“我想怎麼怎麼去畫”的狀態,是“未下筆”的,而當我已經想好了,定義好了這個狀態以後,才執行“把想法畫出來”的方法,即執行.fill()
、.stroke()
等方法,告訴canvas“我要畫了啊!”,然後把內容畫出來。
**正是因為canvas是基於狀態的,所以不同的狀態應該有明確的起始標誌。**如果我們想畫不同顏色的一個三角型和一條直線,我們可能會這麼寫 //把筆尖放在畫布100, 100的位置 cxt.moveTo(100, 100) //從100,100畫到700,700 cxt.lineTo(500,500) //繼續畫完這個三角形 cxt.lineTo(500,100) cxt.lineTo(100,100) //設定三角形線條顏色為粉紅色(我特喜歡粉) cxt.strokeStyle = 'pink' //告訴canvas我畫完了,執行stroke()方法 cxt.stroke()
//畫一條新的線
cxt.moveTo(50, 100)
cxt.lineTo(450,500)
//設定這條線的顏色為淺藍色
cxt.strokeStyle = 'lightblue'
//告訴canvas我畫完了,執行stroke()方法
cxt.stroke()
複製程式碼
看看效果如何:
因為canvas基於狀態,然而這倆的狀態並沒有被區分(canvas沒那麼智慧),所以後面的cxt.strokeStyle = 'lightblue'
會把前面的給覆蓋掉,也就是它只有一個線條顏色的狀態。那麼如何給它定義不同的狀態呢?有兩個方法,請看程式碼
cxt.beginPath()
//把筆尖放在畫布100, 100的位置
cxt.moveTo(100, 100)
//從100,100畫到700,700
cxt.lineTo(500,500)
//繼續畫完這個三角形
cxt.lineTo(500,100)
cxt.lineTo(100,100)
//設定三角形線條顏色為粉紅色(我特喜歡粉)
cxt.closePath()
cxt.strokeStyle = 'pink'
//告訴canvas我畫完了,執行stroke()方法
cxt.stroke()
cxt.beginPath()
//畫一條新的線
cxt.moveTo(50, 100)
cxt.lineTo(450,500)
cxt.closePath()
//設定這條線的顏色為淺藍色
cxt.strokeStyle = 'lightblue'
//告訴canvas我畫完了,執行stroke()方法
cxt.stroke()
複製程式碼
其中,beginPath()
告訴canvas我想會從這裡開始畫一段路徑,closePath()
宣告路徑的結束。雖然這兩個方法在包裹著.stroke()
方法時也生效,但是為了語義化,path指的是路徑,所以我們把這兩個方法僅用於包裹路徑即可。看看效果:
未完待續……