首先得推薦大家一個
免費的家教老師:
W3school,今天只要看到有不懂的字詞,都可以先上去搜尋,以今天的主題Canvas為例,進到網站內,透過搜尋功能直接輸入:Canvas,就會看到下面這個畫面拉! 因為Canvas是HTML的元素,所以會出現在HTML分類後面。
準備好一個專門的資料夾,開始學習Canvas吧!
打開這個網頁,就會看到,左上角有一塊灰色的區塊拉,那就是我們剛剛創建的Canvas元素,灰色則是我設定的#E1DCD9,此時大家應該會好奇,是怎麼決定Canvas有多大的呢? 那就先按下F12,使用上排工具列的第一個圖案,或是鍵盤Shift+Ctrl+C,並把滑鼠移到灰色的Canvas上面,下方便會顯示其相關資訊,大小是300 x 150 px,也是他預設的大小。
如果想要讓他全螢幕,該如何做呢? 這時候就要出動Javascript了! 這邊有幾個步驟要分開講解:
- document.getElementById
這是HTML DOM的方法之一,允許你取得Html上的元素,並在Javascript中修改元素的屬性(寬、高、字體大小等等)
- getContext("2d")
取得Canvas元素後,以此2D物件來進行繪圖(只是一直都沒有準備開發3D的跡象就是了xd)
- Canvas Reference
這是Canvas內建的語法,允許你以2D的方式繪圖,擁有許多不同的繪圖方式,今天會從最簡單的矩形-Rectangles來嘗試
有了大概的認識後,再來看這段程式碼應該就不難了
var canvas = document.getElementById("mycanvas");
var context = canvas.getContext("2d");
其中canvas和context都是變數名稱,可自行修改,第一行先透過ID取得Canvas元素,一開始筆者將id取作mycanvas,所以這邊要用一樣的id,記得大小寫必須相同,也有人喜歡更簡短的程式碼,例如今天id="Cava",可以寫成:
var c = document.getElementById("Cava");
var ctx = c.getContext("2d");
接著就可以修改Canvas的寬高了,那麼如何知道畫面的寬高呢? 就要用到Web API中,在一開始打開瀏覽器時,就存在的物件
window,該物件有非常多的屬性,其中就有我們想要的寬高。
Read only 指的是該屬性為「唯獨」,不允許修改
於是我們可以很簡單的覆寫Canvas的寬高屬性:
到這邊已經完成一半了,加油!堅持下去!請原諒我寫得如此詳盡,其實這裡有很多重點,如果隨意帶過,很容易成為新手的罩門,所以現在多花時間,其實是幫大家省時間!希望能讓大家少走彎路。
那麼,該如何開始畫圖呢?程式發開者在設計Canvas API時,就以一個很直覺的方式來設計,如同我們在現實生活中畫畫一樣,動作依序為:提筆、著色、提筆、著色......依此類推。分別為
context.beginPath(); //提筆
context.fill(); //著色 (填滿)
context.beginPath(); //提筆
context.stroke(); //著色 (外框)
//......
在現實中畫畫,每畫完一個部分,就會把筆拿起來,同樣地,在程式中,每次畫新的圖之前,都必須把筆拿起來,才不會對在畫布上面亂圖。
但是,光是這樣寫,是無法畫出圖形的,必須要提供「路徑」和「顏色」兩個部分,才能進行著色,顏色比較好懂,就像各大繪圖軟體一樣,會有「填滿顏色」和「外框顏色」,至於路徑,就在剛剛提到的
Canvas Reference中,有各式各樣的函式可以做使用。
Rectangles -今天會用到的四種矩形工具/函式
- rect() -路徑
- fillRect() -路徑+填滿
- strokeRect() -路徑+外框
- clearRect() -清除路徑(橡皮擦)
rect(x, y, w, h) 中有四個參數,分別表示矩形的x y座標,和w h寬高,寫入下列程式碼並再次開啟網頁,就可以看到畫面中出現了一個寬高皆為100px的矩形坐落在座標(100, 100)處,也可以注意到,這邊跟國高中學習的直角座標不同,沿用了網頁排版從左上角開始的概念,因此原點坐落於左上角,y座標剛好反過來。
context.beginPath();
context.rect(100, 100, 100, 100);
context.fillStyle = "#A67F78";
context.fill(); //填滿
但是如果每次畫一個圖形,都要這麼多行程式碼,還是有點麻煩是吧!除了自己設置一個function以外,Canvas API也有貼心的準備好更方便的方法,將以上四行程式碼,簡化成兩行:
context.fillStyle = "#32435F";
context.fillRect(150,300,100,100);
其中fillStyle如同繪圖軟體一樣,設定一次顏色,再次修改前,都不會跑掉,因此顏色只要設定過一次,若沒有修改的需求,無須重複寫兩次。
beginPath()只會清除路徑,不會影響到顏色和其他屬性
同樣道理,也有strokeRect()方法可以做使用:
context.strokeStyle = "#32435F";
context.strokeRect(200,400,100,100);
三段程式碼合起來就會得到:
最後一個clearRect()是非常有趣的函式,未來會用這個教大家弄些好玩的東西,如果平常有在繪圖軟體中,使用過「剪裁遮色片」功能的話,應該就會明白我在說什麼。
如同字面上意思呢,它可以把矩形範圍內的像素點全部清除,如同橡皮擦一樣,擦掉,因為顏色被擦掉了,就會露出後面的背景,假如我們加入這段程式碼:
var W = window.innerWidth;
var H = window.innerHeight;
context.clearRect(0, 0, W, H);
就會發現,只剩下背景了,方塊全部被擦掉了!
innerWidth指的是整個網頁的寬度,同理innerHeight指的是高度,如果忘了沒關係,再回去前面複習一下,因此上面的動作,等於清空整個畫布。
那麼今天的教學就先......嘿嘿~還沒結束,還沒派作業呢,相信細心的大家有發現,現在我們已經學會了畫圖,又學會了清空畫布,畫畫+清空=重繪,那麼我們只要不斷地重繪,是不是就能輕鬆做出動畫了呢? 這邊提供大家一個神器:
再加上relativeX和relativeY,在每次刷新時改變,就可以作出動畫效果,但是 ,如果只是像範例這樣,方塊們只會一直往右走,並且消失在畫面外,有沒有辦法設計得更好呢?
那麼,實作時間來拉!以上面這份html文檔為基礎,去設計修改relativeX和relativeY,試著做出一個循環動畫,讓方塊們沿著固定的軌跡來回運行,來試著實現類似以下的效果吧!