今天主要介紹canvas中比較強大的功能
例如將畫布內容抽取為圖片
獲取、修改畫布的像素資訊
以及畫布的命中檢測
首先我仍然需要建立畫布
<canvas id="myCanvas" width=500 height=500></canvas>
首先要明確的一點是
toDataURL()是canvas物件本身的方法而不是環境物件的
這個方法會將canvas的內容抽取為一張圖片(base64編碼)
我們來看一下它的使用方法
我閒著沒事用canvas做了一個太極圖
js程式碼如下
let canvas = document.getElementById('myCanvas'); let cxt = canvas.getContext('2d'); let l = canvas.width/2; const PI = Math.PI; cxt.translate(l, l);let createTaiChi = () => { cxt.clearRect(-l, -l, l, l); cxt.arc(0, 0, l, 0, 2*PI, 0); cxt.stroke(); cxt.beginPath(); cxt.arc(0, -l/2, l/2, -PI/2, PI/2, 0); cxt.arc(0, l/2, l/2, 3/2*PI, PI/2, 1); cxt.arc(0, 0, l, PI/2, PI*3/2, 0); cxt.fill(); cxt.beginPath(); cxt.fillStyle = '#fff'; cxt.arc(0, -l/2, l/7, 0, PI*2, 0); cxt.fill(); cxt.beginPath(); cxt.fillStyle = '#000'; cxt.arc(0, l/2, l/7, 0, PI*2, 0); cxt.fill(); }; createTaiChi();
再配合css做成一個持續旋轉的樣子
#myCanvas { width: 250px; height: 250px; margin: 100px; animation: rotate 3s linear infinite; }@keyframes rotate{ 0% { transform: rotateZ(0); } 100% { transform: rotateZ(360deg); }}
注意這裡我設定的css寬高要比canvas本來的寬高小一倍
(這樣可以讓canvas更清晰一些)
#下面我就要將我在canvas畫的太極圖轉化為一張圖片
首先要取得canvas的base64編碼
let data = canvas.toDataURL();console.log(data);
這裡我們在控制台列印一下看看它的樣子
我們要將它變成圖片,
只需要建立一個img標籤,然後將src設定為data即可
let img = document.createElement('img'); img.src = data;document.body.appendChild(img);
這時我們就會發現頁面中多了一個靜態的太極圖
大小與canvas的width/ height屬性相同500×500
注意這個方法是受同源策略限制的
比如說我在頁面中新增一個本地圖片
然後將這張圖片畫到canvas中
let img = document.getElementsByTagName('img')[0]; cxt.drawImage(img, 0, 0);let data = canvas.toDataURL();
瀏覽器會報錯
#我們使用本地伺服器的話就可以用這個方法
證明這個方法受同源策略限制
使用getImageData(x, y, dx, dy)可以取得canvas的像素資訊
方法由環境物件呼叫(我們這裡是cxt)
(同樣受同源策略限制)
前兩個參數是要取得影像資訊的起始座標,後兩個參數就是要取得影像資訊的寬高
(類似矩形繪製函數)
這個方法回傳一個ImageData物件(包括像素資訊數組data還有寬高width/height)
我們主要用這個物件的data屬性
我們畫布的大小是500×500
所以取得canvas上所有像素資訊就是這樣
console.log(cxt.getImageData(0, 0, 500, 500).data);
我們發現這個陣列的長度為100w
假如我們的canvas有四個像素點
每個像素點資訊有分為RGBA四個方面的值
那麼數組長度就應該是4×4 = 16
它們分別是
1R 1G 1B 1A
2R 2G 2B 2A
3R 3G 3B 3A
4R 4G 4B 4A
我們這裡的canvas一(500×500 #所以像素資訊數組大小為25w×4 = 100w
建立一個空白imageData物件
let blankImg = cxt.createImageData(250, 250); console.log(blankImg);
imgData就是imgData對象,x,y是覆蓋的起始座標
比如說我將我們上面建立的250×250的空白影像覆蓋原canvas
cxt.putImageData(blankImg, 0, 0);# 命中偵測isPointInPath()可以偵測像素點是否在路徑區域內
使用方法很簡單
cxt.rect(100, 100, 300, 300);if(cxt.isPointInPath(200, 200)){ cxt.stroke();}
不過它的相容性不是很好
#