最近研究了一下出來了很久的HTML5,總結了一下,准備來個系列,文中也許有很多問題,歡迎大家指正。
Canvas介紹
canvas用於在網頁中繪制圖形的一個元素,具體內容請查看 -> HTML5 Canvas
這里說些w3school中沒有的。
立即模式
canvas元素是立即模式的圖形系統,意味着當你提出要求時,他會立即繪制,然后立即忘記(繪制完成一個對象,就會銷毀這個對象)。其它的圖形系統(例如:SVG),使用了保留模式的圖形系統,就是說繪制時他們會保留一系列將要繪制的對象。正因未Canvas不需要維護這一系列對象,所以Canvas的運行速度要快很多。
雙緩存機制
在上面,我們提到了立即模式,但這里的“立即繪制”並不是大家所謂的立即,此處需要進一步說明。
在瀏覽器調用我們定義的繪制方法(假設這個方法是DrawGame)繪制當前動畫幀時,Canvas元素並不是立即繪制出你指定的內容。相反,它會創建另一個Canvas元素(我們叫它Canvas2),所有的繪制實際上都在Canvas2中進行。當DrawGame方法返回時,瀏覽器會通過一個圖形操作,復制Canvas2內容到屏幕上,我們將這種技術稱為雙緩存技術,雙緩存技術讓動畫的實現變得平滑。
坐標系統(translate)
translate(x,y)這是Canvas元素的一個方法,游戲的背景移動,大多通過該方法來實現。游戲中,我們不會通過頻繁對大量元素進行坐標計算來實現對象的滾動,因為這樣的計算不僅消耗計算機性能,還增加了代碼的維護難度。
注意:為了不影響后續的繪制,在使用translate(x,y)修改坐標系統后,需要再次調用translate(-x,-y)來恢復坐標系統。
具體內容請查看 -> HTML5 canvas translate()
創建Canvas鏡像和恢復Canvas
在進行動畫繪制時,我們會經常的對Canvas元素的繪圖環境(context)進行修改,例如strokeStyle,lineWidth等。這些修改操作都是永久的,也就意味着對他們的修改將會影響接下來任何你在Canvas元素的圖形操作。那么如何讓這些操作只是臨時有效呢?這里我們可以使用save()和restore()方法對當前Canvas元素的繪圖環境狀態創建鏡像和恢復。任何寫在這兩個方法間的環境屬性修改,在執行restore后,都會恢復成save時的狀態。
注意:save()和restore()需要成對出現,也就是有save,就要有restore。
實現平滑的HTML5動畫
所謂的動畫,說白了就是一張一張的圖片不斷的連續更換。所以,通過編程實現動畫也就是不斷的通過替換圖片,來達到動畫的效果。
但是,這種不斷地替換,當然不能使用死循環while(true)來實現,傳統的方法是使用setTimeout()和setInterval()方法,這兩個方法雖然都提供了毫秒級的精確度,但實際上,卻達不到毫秒級(參考此處:setTimeout精度測試、setInterval精度測試)。所以為了保證動畫的平滑度,我們不應該繼續使用setTimeout和setInterval方法來實現對時間有着苛刻要求的動畫,用什么來代替?我們在下一節講到。
requestAnimationFrame()方法
在w3c中的Timing Control for Script-based Animations(參考此處 -> w3c-Script-based Animations)說明中,定義了一個requestAnimationFrame()窗口對象的方法。不同於setTimeout和setInterval方法,requestAnimationFrame是專門用來實現動畫的,它使用瀏覽器的時間間隔進行繪制,不會掉幀。
這里需要注意的是,requestAnimationFrame方法在窗體沒激活或者頁簽不可見的時候,動畫會暫停。
下面是盜的圖,支持requestAnimationFrame方法的瀏覽器及版本(來源:HTML5 requestAnimationFrame( ) 動畫API)
javascript實例:
1 function animate(now) 2 { 3 DrawGame(now); 4 requestAnimationFrame(animate); 5 } 6 ... 7 requestAnimationFrame(animate);
制作基於時間的運動
游戲幀速率是不穩定的,也許此時能夠60幀/秒,下一刻也許就成了10幀/秒。游戲幀的速率是變化的,我們不能讓游戲幀的速率影像到游戲中物體運動的速率,例如:人物的運動,背景的滾動,子彈的速度等等。所以,游戲中物體的運動必須是基於時間的,並且僅僅依賴於時間(例如:像素/秒),而不是動畫幀速率。
在上一節的實例中,我們可以發現animate有個參數是now,它代表當前繪制的時間,既然有了這個參數,我們就能知道兩次時間間隔,從而計算出運動的距離。
javascript實例:
1 var speed = 50; 2 var lastAnimationTime = new Date(); 3 var offsetX = 0; 4 function SetBackgroundOffsetX(now) 5 { 6 offsetX += speed * (now - lastAnimationTime)/1000 7 ... 8 //如果一直加下去,背景會慢慢移出屏幕,下面的代碼自己寫吧 9 }
結尾
到這里,關於圖形與動畫的內容就差不多結束了,內容不多,代碼很少,但是我覺得已經夠了,畢竟大部分的基礎知識都能在網上找到哈哈。
本人不是HTML5大佬,如文中有問題,請大家幫忙指正,謝謝大家~