這周因為給朋友的遊戲配場景的BGM,沒能寫什麼教程demo(其實就是懶),但是又不能讓你們看出我啥也沒幹,於是就有了這篇應用與優化的話題,同時也是一篇預告貼,下週開始,將會是一期連續的實戰 個人頭像生成器
原料: vue express mongo canvas node
火候: 每章都會有關核心實現,不會索然無味
週期: 1-2周內完成
特色: 如何根據使用者的輸入qq郵箱來生成獨一無二的個人頭像
預告到此結束…….
進入正題
什麼時候用dom 什麼時候canvas/svg
dom方便操作是因為因為dom具有層級結構與一大堆爽手的互動api,但是在瀏覽器渲染的時候卻並不輕鬆,大量巢狀dom將增大瀏覽器深度遍歷的時間,所以才有了virtual dom
與diff
的配合利器。
canvas單層渲染,哪怕是如同之前的偽3d中的層級效果,也只是在同一層dom中,並不會因為渲染問題增大瀏覽器在渲染頁面時的耗時。
開發時,我們可以考慮將一些淺互動的效果統一拋給canvas(如輪播圖)去處理,這樣,我們就可以在增強視覺效果的同時降低瀏覽器的渲染損耗。
有關getImageData跨域的問題
這個問題也是有很多人在群裡問我的,其實一般出現這種問題大多是本地執行的時候,這個問題網上也有答案的,辦法有點低俗,就是推薦你換一個瀏覽器或者掛在伺服器上。
因為本地的資料夾預設是沒有域名的。
"Uncaught DOMException: Failed to execute `getImageData` on `CanvasRenderingContext2D`: The canvas has been tainted by cross-origin data.
複製程式碼
如果你在伺服器上也跨域了,那你可以試試
var img = new Image();
img.crossOrigin = ``;
img.onload = function () {
ctx.drawImage(this, 0, 0);
ctx.getImageData(0, 0,200,200);
};
複製程式碼
快取問題
在使用canvas的時候,可能會存在沒有圖形被繪製出來的情況,除卻程式碼的問題,則是因為上一幀的圖形還未繪製完成,便被clearRect
了,所以我們會需要一個快取進行來預處理,這裡需要的就是離屏處理。
var offscreen = document.createElement("canvas");
offscreen.width = 1000;
offscreen.height = 1000;
var offctx =offscreen.getContext("2d");
複製程式碼
我們建立了離屏畫布後,可以把需要處理繪製的東西交由它處理,繪製後再直接使用drawImage
來將它繪製到主畫布上。
當需要處理的物件越多,一個離屏可能也會造成畫面卡頓的其情況,這時候,我們就可以把離屏規劃給小物件,讓每個物件都擁有一個自己的繪製環境,這樣,就大大提升了渲染的流暢度。
這裡是個測試用例,我不知道你們如何,我這邊跑個千把個小球沒啥問題
畫素處理的選擇
當我們要做畫素的處理的時候,可以使用bitmap
或者Arradata
,這時我們就需要去做一個選擇,bitmap
具有寬高,我們可以較容易對平面內的畫素點去進行座標的定位,但是其同時其時間複雜度與空間複雜度就比Arraydata
要高,所以在選擇的時候要根據實際情況來做選擇。
如何學習canvas
有人問了我這個問題,canvas的api很少,哪怕webgl都比它要多,只是webgl的難點不在於api,而是在於shader
的編寫。
- 如果你打算只做2d,那麼可以考慮入手一款軟體ps/sketch,演算法上不做要求,畢竟我也很菜,但是要有一定的高數與物理基礎,以及少量圖形學的基礎,如果你是PS玩的比較熟的,那就另當別論,我是從初二開始入的PS的坑,上手canvas所以有一定優勢。
- 在學canvas的時候,網上有很多比較淺顯的視訊教程,可以去看一看,更多的是要接觸圖形引擎(包括包含畫面邏輯的遊戲),想一想它們如何實現,可以提升邏輯的思維
- 如果向入手webgl,那可以先從
three.js
來上手,再去了解webgl,是真的挺難的,我也是個菜雞,不過在學習的過程中,可以很大的提升你對圖形的繪製渲染瞭解。
以上幾種是常遇到的問題,也有可能我沒有提到的,可以向我提問,我會盡可能地為你們解惑。
不定期更新canvas與svg的相關技術教程,有實戰型,也會有主原理型的,2d 2.5d 3d都會包含到,同時涉及的有 線性代數 物理 圖形學等相關的基礎知識。
歡迎各位客官收藏關注 投硬幣包養