2021-02-13|閱讀時間 ‧ 約 9 分鐘

Canvas動畫入門(1) 開始畫圖吧!

    首先得推薦大家一個免費的家教老師:W3school,今天只要看到有不懂的字詞,都可以先上去搜尋,以今天的主題Canvas為例,進到網站內,透過搜尋功能直接輸入:Canvas,就會看到下面這個畫面拉! 因為Canvas是HTML的元素,所以會出現在HTML分類後面。
    搜尋Canvas
    搜尋Canvas
    準備好一個專門的資料夾,開始學習Canvas吧!
    • 首先,準備好一個Html檔案,像是這樣:
    其中先重置Css,把Html和Body的marginborderpadding設為0,然後在Body裡面創建一個Canvas元素,並試著在Style裡面為該元素加上背景
    打開這個網頁,就會看到,左上角有一塊灰色的區塊拉,那就是我們剛剛創建的Canvas元素,灰色則是我設定的#E1DCD9,此時大家應該會好奇,是怎麼決定Canvas有多大的呢? 那就先按下F12,使用上排工具列的第一個圖案,或是鍵盤Shift+Ctrl+C,並把滑鼠移到灰色的Canvas上面,下方便會顯示其相關資訊,大小是300 x 150 px,也是他預設的大小。
    開發者工具檢視
    如果想要讓他全螢幕,該如何做呢? 這時候就要出動Javascript了! 這邊有幾個步驟要分開講解:
    1. document.getElementById 這是HTML DOM的方法之一,允許你取得Html上的元素,並在Javascript中修改元素的屬性(寬、高、字體大小等等)
    2. getContext("2d") 取得Canvas元素後,以此2D物件來進行繪圖(只是一直都沒有準備開發3D的跡象就是了xd)
    3. 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 -今天會用到的四種矩形工具/函式

    1. rect()     -路徑
    2. fillRect()    -路徑+填滿
    3. strokeRect()  -路徑+外框
    4. 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指的是高度,如果忘了沒關係,再回去前面複習一下,因此上面的動作,等於清空整個畫布。
    那麼今天的教學就先......嘿嘿~還沒結束,還沒派作業呢,相信細心的大家有發現,現在我們已經學會了畫圖,又學會了清空畫布,畫畫+清空=重繪,那麼我們只要不斷地重繪,是不是就能輕鬆做出動畫了呢? 這邊提供大家一個神器:
    • window.requestAnimationFrame 簡單來說,如果你的電腦顯示禎數有60次,那麼,每次要刷新畫面之前,都會透過這個函式先行呼叫,如果把上述所有繪圖的程式碼,包成一個函式,就可以讓使用者每一禎都看到畫面的改變,避免因重繪的次數過少而閃爍,或過多而浪費效能。
    再加上relativeX和relativeY,在每次刷新時改變,就可以作出動畫效果,但是 ,如果只是像範例這樣,方塊們只會一直往右走,並且消失在畫面外,有沒有辦法設計得更好呢?
    那麼,實作時間來拉!以上面這份html文檔為基礎,去設計修改relativeX和relativeY,試著做出一個循環動畫,讓方塊們沿著固定的軌跡來回運行,來試著實現類似以下的效果吧!
    分享至
    成為作者繼續創作的動力吧!
    © 2024 vocus All rights reserved.