學習canvas基礎的總結

簡單介紹canvas

<canvas><img>標籤很像,可是沒有src和alt屬性,只有width和height屬性。 css定義的尺寸與canvas的尺寸比例不一致時,會出現扭曲。css

canvas起初是空白的,要找到渲染上下文來繪製。 getContext() 該方法用來獲取渲染上下文和繪製功能。web

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');// 須要檢查支持性,是否支持canvas.getContext
複製代碼

矩形

fillRect(x, y, width, height);// 填充矩形
strokeRect(x, y, width, height);//矩形邊框
clearRect(x, y, width,height);// 清除指定矩形區域,清除部分爲透明的
複製代碼

繪製路徑:

  • 建立路徑的起始點
  • 使用畫圖命令,畫出路徑
  • 路徑封閉
  • 路徑生成,繪製圖形(描邊,填充)

beginPath()
新建一條路徑,生成以後,圖形繪製命令被指向到路徑上生成路徑。
列表清空重置,從新繪製新的圖形。canvas

closePath()
閉合路徑以後圖形繪製命令又從新指向到上下文中。
非必需,當你調用fill()函數時,全部沒有閉合的形狀都會自動閉合,因此你不須要調用closePath()函數。可是調用stroke()時不會自動閉合。數組

stroke()
經過線條來繪製圖形。若是用線條繪製必須用closePath()來閉合曲線。緩存

fill()
經過填充路徑的內容區域生成實心的圖形。bash

moveTo(x, y)
將筆觸移動到x,y座標點處。dom

lineTo(x, y)
繪製直線。函數

arc(x, y, radius, startAngle, endAngle, anticlockwise)
圓心座標,半徑,起始角度,結束角度,false順時針,true逆時針。
三點鐘方向爲0°(弧度),弧度=(Math.PI/180)*角度。性能

arcTo(x1, y1, x2, y2, radius)
根據給定的控制點和半徑畫一段圓弧,再以直線鏈接兩個控制點。學習

rect(x, y, width, height)
繪製一個左上角座標爲(x,y),寬高爲width以及height的矩形。筆觸自動置回(0,0)。

quadraticCurveTo(cp1x, cp1y, x,y)
繪製二次貝塞爾曲線,cp1x,cp1y爲一個控制點,x,y爲結束點。

bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
繪製三次貝塞爾曲線,cp1x,cp1y爲控制點一,cp2x,cp2y爲控制點二,x,y爲結束點。藍色是起始點和結束點,紅色是控制點。

path2D對象:用來緩存和記錄繪畫命令,可快速回顧繪製路徑。

Path2D()會返回一個新初始化的Path2D對象(可能將某一個路徑做爲變量——建立一個它的副本,或者將一個包含SVG path數據的字符串做爲變量)。

new Path2D(); // 空的Path對象
new Path2D(path); // 克隆Path對象
new Path2D(d); // 從SVG創建Path對象
Path2D.addPath(path [, transform]);// 添加了一條路徑到當前路徑(可能添加了一個變換矩陣)。
複製代碼

新的Path2D API有另外一個強大的特色,就是使用SVG path data來初始化canvas上的路徑。這將使你獲取路徑時能夠以SVG或canvas的方式來重用它們。

var p = new Path2D("M10 10 h 1 80 v 80 h -80 Z");// 將先移動到點 (M10 10) 而後再水平移動80個單位(h 80),而後下移80個單位 (v80),接着左移80個單位 (h -80),再回到起點處 ( z)。
複製代碼

透明度:TransparencyValue

globalAlpha = transparencyValue;// 有效值(0.0~1.0),徹底透明~徹底不透明
複製代碼

線性樣式

lineWidth = value
設置線條寬度。屬性值必須爲正數。默認值是1.0。

lineCap = type
設置線條末端樣式。type的值有buttroundsquare。默認是 butt

lineJoin = type
設定線條與線條間接合處的樣式。round, bevelmiter。默認是 miter

miterLimit = value
限制當兩條線相交時交接處最大長度。
所謂交接處長度(斜接長度)是指線條交接處內角頂點到外角頂點的長度。

getLineDash()
返回一個包含當前虛線樣式,長度爲非負偶數的數組。

setLineDash(segments)
設置當前虛線樣式。

lineDashOffset = value
設置虛線樣式的起始偏移量。
setLineDash方法和 lineDashOffset 屬性來制定虛線樣式。
setLineDash方法接受一個數組,來指定線段與間隙的交替;
lineDashOffset 屬性設置起始偏移量。

漸變:以用線性或者徑向的漸變來填充或描邊

新建一個 canvasGradient 對象,而且賦給圖形的 fillStyle 或 strokeStyle 屬性。

createLinearGradient(x1, y1, x2, y2)
createLinearGradient 方法接受 4 個參數,表示漸變的起點 (x1,y1) 與終點 (x2,y2)
createRadialGradient(x1, y1, r1, x2, y2, r2)
createRadialGradient 方法接受 6 個參數,前三個定義一個以 (x1,y1) 爲原點,半徑爲 r1 的圓,後三個參數則定義另外一個以(x2,y2) 爲原點,半徑爲 r2 的圓。
gradient.addColorStop(position, color)
addColorStop 方法接受 2 個參數,position 參數必須是一個 0.0 與 1.0 之間的數值,表示漸變中顏色所在的相對位置。

圖案樣式patterns

createPattern(image, type)
該方法接受兩個參數。Image 能夠是一個 Image對象的引用,或者另外一個 canvas對象。
Type 必須是下面的字符串值之一:repeatrepeat-xrepeat-yno-repeat

陰影shadow

shadowOffsetX = float;
shadowOffsetY = float複製代碼

shadowOffsetXshadowOffsetY 用來設定陰影在X和Y軸的延伸距離,它們是不受變換矩陣所影響的。負值表示陰影會往上或左延伸,正值則表示會往下或右延伸,它們默認都爲 0。

shadowBlur = float
複製代碼

shadowBlur 用於設定陰影的模糊程度,其數值並不跟像素數量掛鉤,也不受變換矩陣的影響,默認爲 0。

shadowColor = color
複製代碼

shadowColor 是標準的 CSS 顏色值,用於設定陰影顏色效果,默認是全透明的黑色。

canvas填充規則:

  • nonzero:non-zero winding rule, 默認值. 填充
  • evenodd: even-odd winding rule,鏤空

動畫:

  1. 清空canvas:clearRect();
  2. 保存canvas狀態
  3. 繪製動畫圖形:重繪動畫幀
  4. 恢復canvas狀態:若是已經保存了 canvas的狀態,能夠先恢復它,而後重繪下一幀。

你可使用setInterval()方法,它就能夠按期執行指定代碼。若是咱們須要作一個遊戲,咱們可使用鍵盤或者鼠標事件配合上setTimeout()方法來實現。經過設置事件監聽,咱們能夠捕捉用戶的交互,並執行相應的動做。 採用window.requestAnimationFrame()實現動畫效果。這個方法提供了更加平緩並更加有效率的方式來執行動畫,當系統準備好了重繪條件的時候,才調用繪製動畫幀。通常每秒鐘回調函數執行60次,也有可能會被下降。

變形transformations:

save()restore(): save 和 restore 方法是用來保存和恢復 canvas 狀態的,canvas的狀態保存在棧中。
tanslate(x, y); 左右,上下平移。
rotate旋轉。
scale縮放。
transform(m11, m12, m21, m22, dx, dy) 這個方法是將當前的變形矩陣乘上一個基於自身參數的矩陣,在這里咱們用下面的矩陣

m11   m21   dx    
m12   m22   dy  
0     0     1    
複製代碼
m11:水平方向的縮放     
 m12:水平方向的傾斜偏移     
 m21:豎直方向的傾斜偏移     
 m22:豎直方向的縮放 
 dx:水平方向的移動
 dy:豎直方向的移動
複製代碼
setTransform(m11, m12, m21, m22, dx, dy)
 resetTransform()
複製代碼

canvas優化

使用requestAnimationFrame進行動畫循環

setTimeoutsetInterval並不是是專爲連續循環產生的 API,因此可能沒法達到流暢的動畫表現,故用 requestAnimationFrame,可能須要polyfill

const raf = window.requestAnimationFrame
  || window.webkitRequestAnimationFrame
  || window.mozRequestAnimationFrame
  || window.oRequestAnimationFrame
  || window.msRequestAnimationFrame
  || function(callback) {
    window.setTimeout(callback, 1000 / 60)
  }
複製代碼

利用剪輯區域來處理動畫背景或其餘不變的圖像

背景比較複雜可使用剪輯區域技術,經過每幀較少的繪製來得到較好的性能。

利用剪輯區域技術來恢復上一幀動畫所佔背景圖的執行步驟:

  • 調用 context.save(),保存屏幕 canvas的狀態
  • 經過調用 beginPath來開始一段新的路徑
  • 在 context對象上調用 arc()、rect()等方法來設置路徑
  • 調用 context.clip()方法,將當前路徑設置爲屏幕 canvas的剪輯區域
  • 擦除屏幕 canvas中的圖像(實際上只會擦除剪輯區域所在的這一塊範圍)
  • 將背景圖像繪製到屏幕canvas上(繪製操做實際上只會影響剪輯區域所在的範圍,因此每幀繪製圖像像素數更少)
  • 恢復屏幕 canvas的狀態參數,重置剪輯區域

離屏緩衝區(離屏canvas)

先繪製到一個離屏 canvas中,而後再經過 drawImage把離屏 canvas 畫到主 canvas中,就是把離屏 canvas當成一個緩存區。把須要重複繪製的畫面數據進行緩存起來,減小調用 canvas的 API的消耗。

const cacheCanvas = document.createElement('canvas')
const cacheCtx = cacheCanvas.getContext('2d')
cacheCtx.width = 200
cacheCtx.height = 200
// 繪製到主canvas上
ctx.drawImage(0, 0)
複製代碼

必要時,可使用多個離屏 canvas另外,離屏canvas再也不使用時,最好把手動將引用重置爲 null,避免由於 js和dom之間存在的關聯,致使垃圾回收機制沒法正常工做,佔用資源。

儘可能利用CSS

儘可能少的調用 canvas API

相比於正常的js操做,頻繁的調用canvasAPI更加消耗資源。

避免阻塞

在進行某些耗時操做,例如計算大量數據,一幀中包含了太多的繪製狀態,大規模的 DOM操做等,可能會致使頁面卡頓,影響用戶體驗,能夠經過如下兩種手段:

  • web worker
    web worker最經常使用的場景就是大量的頻繁計算,減輕主線程壓力,若是遇到大規模的計算,能夠經過此 API分擔主線程壓力,此 API兼容性已經很不錯了,既然 canvas能夠用,那 web worker也就徹底能夠考慮使用。

  • 分解任務
    知足:
    1.循環處理操做並不要求同步
    2.數據並不要求按照順序處理

    根據任務總量分配:   
      根據運行時間分配:
    複製代碼

以上內容均是看文檔學習概括的經常使用的基礎的知識點,以爲有用的小夥伴點個當心心吧

相關文章
相關標籤/搜索