1. 程式人生 > 其它 >HTML5(六)——Canvas 高階操作

HTML5(六)——Canvas 高階操作

上一篇文章《HTML5(五)——Canvas API》介紹 canvas 繪製基本圖形,這節開始介紹canvas的高階操作。

一、canvas 轉換

canvas 轉換常用的幾種方法介紹,如下:

方法

描述

scale()

縮放當前繪圖至更大或更小。

rotate()

旋轉當前繪圖。

translate()

重新對映畫布上的 (0,0) 位置。

transform()

替換繪圖的當前轉換矩陣。

setTransform()

將當前轉換重置為單位矩陣。然後執行 transform()。

1.1 、scale - 縮放

使用語法:scale(x,y)

x:表示水平方向的縮放倍數

y:表示垂直方向的縮放倍數

eg:canvas 繪製的矩形框放大兩倍,程式碼如下:

var canvas = document.getElementById("canvas")
var ctx = canvas.getContext("2d")
ctx.scale(2,2)
ctx.fillStyle="red"
ctx.fillRect(0,0,200,200)

1.2、translate - 畫布平移

使用語法:translate(x,y)

x:新增到水平座標上的位置

y:新增到垂直座標上的位置

設定之後開始繪製的圖片位置從(x,y)算起。

eg:繪製兩個一樣的矩形,一個在平移前繪製,一個在平移後繪製,程式碼如下:

var canvas = document.getElementById("canvas")
var ctx = canvas.getContext("2d")
ctx.fillStyle="red"
        
ctx.fillRect(0,0,200,200)
//平移
ctx.translate(200,200)
ctx.fillRect(0,0,200,200)

執行結果如圖:

1.3 、rotate- 旋轉

使用語法:rotate(angle)

angle 旋轉弧度,如果想使用角度,可以把角度轉成弧度,公式為:deg * Path.PI/180。

eg:將一個矩形旋轉45度,程式碼如下:

var canvas = document.getElementById("canvas")
var ctx = canvas.getContext("2d")
//旋轉45度
ctx.rotate(45*Math.PI/180)
ctx.fillStyle="red"
ctx.fillRect(0,0,200,200)

執行結果如圖:

根據上述結果我們發現旋轉的時候,預設原點是畫布的起始點,我們想要的旋轉是在矩形框中心為原點的旋轉,此時我們需要藉助上translate平移,重置一下原點,修改上述程式碼為:

<canvas width="400" height="400" id="canvas"></canvas>

var canvas = document.getElementById("canvas")
var ctx = canvas.getContext("2d")

ctx.translate(200,200)
ctx.rotate(45*Math.PI/180)
ctx.translate(-200,-200)

ctx.fillStyle="red"
ctx.fillRect(100,100,200,200)

執行結果如圖:

1.4、transform - 矩陣變換

使用語法:transform(a,b,c,d,e,f)

  • a:水平縮放
  • b:水平傾斜
  • c:垂直傾斜
  • d:垂直縮放
  • e:水平移動
  • f:垂直移動

transform可以替代前邊平移、縮放、旋轉三者,如下:

// 平移
translate(x,y) <=> transform(1,0,0,1,x,y) <=> transform(0,1,1,0,x,y)
// 縮放
sacle(x,y) <=> transform(x,0,0,y,0,0) 
// 旋轉
rotate(angle) <=> transform(Math.cos(angle*Math.PI/180), Math.sin(angel*Math.PI/180), -Math.sin(angle*Math.PI/180), Math.cos(angle*Math.PI/180))

1.5、setTransform - 矩陣變換

setTransform()方法將變換的矩陣進行重置,它把當前的變換矩陣重置為單位矩陣
使用語法:transform(a,b,c,d,e,f)
各引數說明:水平旋轉、水平傾斜、垂直傾斜、垂直縮放、水平移動、垂直移動

setTransform() 方法把當前的變換矩陣重置為單位矩陣,然後以相同的引數執行transform()。

二、canvas 操作圖片

drawImage() 在畫布上繪製圖像、畫布或視訊。也能夠繪製圖片的一部分,增加或減少影象的尺寸。以下是三種常見使用語法:

  • 語法1:drawImage( img , x , y )
  • 語法2:drawImage( img , x , y , width , height )
  • 語法3:drawImage( img , sx , sy , swidth, sheight , x , y , width , height )

上述引數表示的意義如下:

引數

描述

img

規定要使用的影象、畫布或視訊。

sx

可選。開始剪下的 x 座標位置。

sy

可選。開始剪下的 y 座標位置。

swidth

可選。被剪下影象的寬度。

sheight

可選。被剪下影象的高度。

x

在畫布上放置影象的 x 座標位置。

y

在畫布上放置影象的 y 座標位置。

width

可選。要使用的影象的寬度。(伸展或縮小影象)

height

可選。要使用的影象的高度。(伸展或縮小影象)

eg:利用語法3,進行繪製圖片的部分內容,實現如下效果:

給上述兔子順便加一個點選螢幕暫停開始功能,完整程式碼如下:

<canvas width="400" height="400" id="canvas"></canvas>
<script>
 var canvas = document.getElementById("canvas")
 var ctx = canvas.getContext("2d")
 var img = new Image()
 let pause = false,frameCounter = 0,i=0;
 img.src = "./rotate.png"
 img.onload = function(){
  requestAnimationFrame(next)
 }
function next(){
 ctx.clearRect(0,0,canvas.width,canvas.height)
 if(frameCounter%5 == 0){ //frameCounter 控制動畫速度
  i++
  if(i==11)i=0
 }
 ctx.drawImage(img,
  0,i*240,240,240,
  0,0,240,240) // 每張圖片寬高都是240,具體引數根據圖片而定
  frameCounter ++
  if(!pause)requestAnimationFrame(next)
 }
window.onclick = function(){
 pause = !pause
 next()
}
</script>

eg:使用 canvas 畫布處理視訊,使用定時器繪製視訊的當前幀,連續起來就是一個視訊,需要注意的是必須處理暫停和開始播放兩種操作,具體程式碼如下:

var v=document.getElementById("video1");
var c=document.getElementById("myCanvas");
ctx=c.getContext('2d');
v.addEventListener('play',function() {var i=window.setInterval(function() 
{ctx.drawImage(v,0,0,270,135)},20);},false);
v.addEventListener('pause',function() {window.clearInterval(i);},false);
v.addEventListener('ended',function() {clearInterval(i);},false);

三、畫素級操作

常見的畫素級的操作有三種:

  • getImageData() - 獲取畫布畫素資料
  • createImageData() - 建立新的、空白畫素
  • putImageData() - 影象畫素資料放回畫布

3.1、getImageData

使用語法:getImageData( x , y , width , height )

  • x:要被提取的影象資料矩形區域的左上角 x 座標。
  • y:要被提取的影象資料矩形區域的左上角 y 座標。
  • width:被提取的影象資料矩形區域的寬度
  • height:被提取的影象資料矩形區域的高度

返回一個 imageData 物件,用來描述 canvas 區域隱含的畫素資料,這個區域通過畫素表示,起點是( x , y ),寬高為 widht 和 height 。

imageData 物件包含三個屬性:

  • imageData.height - 畫素描述的矩形實際高度。
  • imageData.width - 畫素描述的矩形實際寬度。
  • imageData.data - 包含 rgba 順序資料的一個數組,資料使用0-255直接整數表示。

3.2、createImageData

使用語法:

createImageData( width , height )

建立一個空白的 imageData 物件,新物件的預設畫素值 transparent black。對於imageData物件中的每個畫素值,都存在 rgba 這四方面的資訊,即:

  • r - 紅色(0-255)
  • g - 綠色(0-255)
  • b - 藍色(0-255)
  • a - alpha(0-255,0是透明,255是完全可見)

新物件預設畫素值為(0,0,0,0)。

eg:如果我們想把 imageData 中一個畫素變為紅色時,可以改變第一和第四位資訊,程式碼如下:

var imageData = ctx.createImageData(100,100)
imageData.data[0] = 255
imageData.data[1] = 0
imageData.data[2] = 0
imageData.data[3] = 255

3.1、putImageData

使用語法:

putImageData( imgData , x , y , dirtyX , dirtyY , dirtyWidth ,dirtyHeight );

引數及意義:

引數

描述

imgData

規定要放回畫布的 ImageData 物件。

x

ImageData 物件左上角的 x 座標,以畫素計。

y

ImageData 物件左上角的 y 座標,以畫素計。

dirtyX

可選。水平值(x),以畫素計,在畫布上放置影象的位置。

dirtyY

可選。水平值(y),以畫素計,在畫布上放置影象的位置。

dirtyWidth

可選。在畫布上繪製圖像所使用的寬度。

dirtyHeight

可選。在畫布上繪製圖像所使用的高度。

通過 getImageData 複製的指定矩形畫素資料,編輯之後,通過 putImageData 方法將影象資料放回畫布上。

eg:新增濾鏡效果:上述兔子是白色的變換成紅色兔子,這時需要把綠色和藍色都設定成0即可,程式碼如下:

<canvas width="400" height="400" id="canvas"></canvas>
<script>
 var canvas = document.getElementById("canvas")
 var ctx = canvas.getContext("2d")
 var img = new Image()
 let w = canvas.width,h = canvas.height;
 img.src = "./rotate.png"
 img.onload = function(){
  ctx.drawImage(img,0,0,240,240,0,0,240,240)
 let imageData = ctx.getImageData(0,0,w,h)
 for(let r=0;r<w;r++){
  for(let c=0;c<h;c++){
   imageData.data[(r*w+c)*4+2 ] = 0 // 把藍色設定成0
   imageData.data[(r*w+c)*4+1] = 0 // 把藍色設定成0
  }
 }
 ctx.putImageData(imageData,0,0)
}
</script>