03媳友、HTML5-Canvas(畫布)

一、什么是 Canvas撒轮?

  • HTML5 的 canvas 元素使用 JavaScript 在網(wǎng)頁上繪制圖像
  • 畫布是一個矩形區(qū)域乞旦,可以控制其每一像素
  • canvas 擁有多種繪制路徑、矩形题山、圓形兰粉、字符以及添加圖像的方法

二、canvas基本使用

  • 添加canvas元素(創(chuàng)建畫布)
// 在頁面中添加一個canvas標(biāo)簽(默認(rèn)畫布是300*150)
<canvas id="view1" width="300" height="300">
      <i>不支持canvas瀏覽器</i>
 </canvas>
  • 通過JavaScript繪制圖像
<script>
    // 1顶瞳、獲取到canvas元素
    var oView = document.getElementById("view1");
    // 2玖姑、通過getContext獲取繪制環(huán)境(多種繪制路徑、矩形慨菱、圓形焰络、字符以及添加圖像的方法)
    var oGC = oView.getContext('2d');
    // 3、填充矩形
    oGC.fillRect(30, 30, 100, 100);
</script>

三符喝、繪制的方法

  • 繪制矩形
    1闪彼、fillRect(X, Y, W, H) --- 填充矩形(默認(rèn)是黑色)
    X: 矩形左上角的X坐標(biāo)
    Y: 矩形左上角的Y坐標(biāo)
    W: 矩形寬度
    H: 矩形高度

2、 strokeRect(L, T, W, H) --- 邊框矩形(默認(rèn)1px黑色邊框)

 X: 矩形左上角的X坐標(biāo)
 Y: 矩形左上角的Y坐標(biāo)
 W: 矩形寬度
 H: 矩形高度

注: strokeRect(30, 30, 100, 100); 表從(30, 30)位置開始,繪制寬高為100的矩形畏腕;但是邊框?qū)嶋H顯示2px并不為1px缴川,原因是邊框繪制是圍繞邊框線往兩邊延伸的,即左邊0.5px右邊0.5px描馅,但實(shí)際顯示都只能是整數(shù)把夸,即變?yōu)樽筮?px右邊1px∶郏【解決方式 strokeRect(30.5, 30.5, 100, 100)】

  • 設(shè)置繪圖
    1恋日、fillStyle: 填充樣式
    2、lineWidth: 線寬
    3嘹狞、strokeStyle: 邊線樣式
  • 邊界繪制
    1谚鄙、lineJoin: 邊界連接點(diǎn)樣式
  miter(默認(rèn))/round(圓角)/bevel(斜角)

2、lineCap: 端點(diǎn)樣式(邊線的兩個端點(diǎn))

 butt(默認(rèn))/round(圓角)/square(高度多出為寬一半的值)
  • 繪制路徑
    1刁绒、beginPath(): 開始繪制路徑
    2闷营、closePath:() 結(jié)束繪制路徑(有閉合作用)
    3、moveTo(x, y): 移動到繪制的新目標(biāo)點(diǎn)
    4知市、lineTo(x, y): 新的目標(biāo)點(diǎn)
    5傻盟、stroke(): 畫線(默認(rèn)黑色)
    6、fill(): 填充(默認(rèn)黑色)
    7嫂丙、rect(): 矩形區(qū)域
    8娘赴、clearRect(x, y, w, h): 刪除畫布的矩形區(qū)域
    9、save(): 保存當(dāng)前圖像狀態(tài)的一份拷貝
    10跟啤、restore(): 恢復(fù)上次保存的圖片狀態(tài)

案例: 簡易畫板
案例: 移動的矩形

四诽表、其他曲線

  • 繪制圓形
arc(x, y, 半徑, 起始弧度, 結(jié)束弧度, 旋轉(zhuǎn)方向)
  - x/y: 起始位置
  - 半徑: 圓形的半徑大小
  - 弧度與角度的關(guān)系: 弧度 = 角度*Math.PI / 180;
  - 旋轉(zhuǎn)方向: 順時針(默認(rèn))false、逆時針true【起始位置是在3點(diǎn)鐘方向!!!】
旋轉(zhuǎn)方向

案例: 繪制一個鐘表

  • 繪制其他曲線
    1隅肥、arcTo(x1, y1, x2, y2, r)
    - 第一組坐標(biāo)广鳍、第二組坐標(biāo)了牛、半徑
    oGC.moveTo(50, 50);  // 起始點(diǎn)
    oGC.quadraticCurveTo(30, 220 ,250, 250); // 第二組左邊、結(jié)束坐標(biāo)
    oGC.stroke();
    

  2、quadraticCurveTo(dx, dy, x1, y1)
  • 貝塞爾曲線: 第一組控制點(diǎn)房维、第二組結(jié)束坐標(biāo)
    oGC.moveTo(100, 200); // 起始點(diǎn)
    oGC.quadraticCurveTo(100, 100, 200, 200);
    oGC.stroke();
![貝塞爾曲線1](http://upload-images.jianshu.io/upload_images/1801379-9bdb2ce92dc203db.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  
  3弥姻、bezierCurveTo(dx1, dy1, dx2, dy2, x1, y1)
  • 貝塞爾曲線: 第一組控制點(diǎn)银亲、第二組控制點(diǎn)变姨、第三組結(jié)束坐標(biāo)
    oGC.moveTo(50, 50); // 起始點(diǎn)
    oGC.bezierCurveTo(30, 140, 270, 180, 250, 250);
    oGC.stroke();
![貝塞爾曲線2](http://upload-images.jianshu.io/upload_images/1801379-a877a91ce0b82587.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## 五、變換
- translate(x, y)

偏移: 從起始點(diǎn)為基準(zhǔn)种柑,移動到當(dāng)前坐標(biāo)位置
oGC.translate(100, 100);
// 起始點(diǎn)原本是(0,0)岗仑,因?yàn)槠疲宰優(yōu)?100, 100)
oGC.fillRect(0, 0, 100, 100);


- rotate(angle)

旋轉(zhuǎn): 參數(shù)是弧度
oGC.rotate(10*Math.PI/180);
oGC.fillRect(100,100,100,50);


- scale(x, y)

縮放: 默認(rèn)不縮放即是1
oGC.scale(0.7, 0.7);
oGC.fillRect(100, 100, 100, 100);


> 案例: 旋轉(zhuǎn)并縮放的方塊

## 六聚请、繪制圖片
- drawImage(oImg, x, y, w , h): 插入圖片
  • oImg: 插入的圖片
  • x/y: 坐標(biāo)位置
  • w/h: 圖片寬高

// 創(chuàng)建圖片對象
var oImg = new Image();
// 獲取圖片
oImg.src = 'qq.png';
// 繪制圖片
oGC.drawImage(oImg, 0, 0, 100, 100);

圖片預(yù)加載: 在onload中調(diào)用方法(先加載完圖片荠雕,后通過canvas繪制)
oImg.onload = function(){ // 圖片加載完成 }

> 案例: 圖片旋轉(zhuǎn)效果

- createPattern(oImg, repeat): 設(shè)置背景

平鋪方式: repeat/repeat-x/repeat-y/no-repeat

// 創(chuàng)建圖片對象
var oImg = new Image();
// 獲取圖片
oImg.src = 'qq.png';
// 設(shè)置背景
var bg = oGC.createPattern(oImg, 'repeat-x');
// 以背景形式填充
oGC.fillStyle = bg;
// 如果需要移動,通過translate操作
oGC.translate(100, 100);
// 繪制矩形
oGC.fillRect(0, 0, 100, 100);

 
## 七、漸變
- createLinearGradient(x1, y1, x2, y2): 線性漸變
  • x1/y1: 起始點(diǎn)坐標(biāo)
  • x2/y2: 結(jié)束點(diǎn)坐標(biāo)
  • addColorStop(位置舞虱, 顏色): 添加漸變點(diǎn)

// 創(chuàng)建線性漸變
var obj = oGC.createLinearGradient(60, 60, 170, 170);
// 添加漸變點(diǎn)(可以添加多個)
obj.addColorStop(0, 'purple');
obj.addColorStop(0.5, 'yellow');
obj.addColorStop(1, 'red');
// 設(shè)置填充
oGC.fillStyle = obj;
// 繪制矩形
oGC.fillRect(30, 30, 200, 200);

- createRadialGradient(x1, y1, r1, x2, y2, r2): 放射性漸變
  • x1/y1/r1: 第一個圓的坐標(biāo)和半徑
  • x2/y2/r2: 第二個圓的坐標(biāo)和半徑

// 放射性漸變
var obj = oGC.createRadialGradient(150, 150, 150, 150, 150, 60);
// 添加漸變點(diǎn)(可以添加多個)
obj.addColorStop(0, 'white');
obj.addColorStop(0.5, 'yellow');
obj.addColorStop(1, 'red');
// 設(shè)置填充
oGC.fillStyle = obj;
// 繪制矩形
oGC.fillRect(0, 0, 300, 300);


## 八欢际、繪制文本
- strokeText(text母市,x, y): 文字邊框

oGC.strokeText('你是誰啊?', 2, 2);


- fillText(text, x, y): 文字填充

oGC.fillText('你是誰啊?', 0, 0);


- font: 文字屬性

// 文字大小和文字類型(必須得寫矾兜,另外樣式很少)
oGC.font = '30px impact';


- textAlign(end/right/center): 水平對齊方式

oGC.textAlign = 'left';


- textBaseline(top/middle/bottom): 垂直對齊方式

oGC.textBaseline = 'top';


- measureText(): 文本寬度(只有寬度)

var width = oGC.measureText('你是誰啊?').width

> 案例: 文本居中設(shè)置

- shadowOffsetX: x軸偏移

oGC.shadowOffsetX = 5;
oGC.shadowColor = 'red';

> 文字陰影屬性text-shadow: x y blur color
x       橫向偏移
y       縱向偏移
blur        模糊距離
color       陰影顏色
例如: text-shadow: 3px 3px 5px red;

- shadowOffsetY: y軸偏移

oGC.shadowOffsetY = 5;
oGC.shadowColor = 'red';


- shadowBlur: 高斯模糊值

oGC.shadowBlur = 3;

> 圖像處理軟件會提供"模糊"(blur)濾鏡,使圖片產(chǎn)生模糊的效果患久,"模糊"的算法有很多種椅寺,其中有一種叫做[高斯模糊](http://en.wikipedia.org/wiki/Gaussian_blur)(Gaussian Blur)。高斯模糊的原理中蒋失,它是根據(jù)[高斯模糊](http://en.wikipedia.org/wiki/Gaussian_blur)調(diào)節(jié)像素色值返帕,它是有選擇地模糊圖像。

- shadowColor: 陰影顏色

oGC.shadowColor = 'red';


## 九篙挽、像素操作
- getImageData(x, y, w, h): 獲取圖片數(shù)據(jù)

var oImg = oGC.getImageData(0, 0, 100, 100);


- putImageData(獲取圖像, x, y): 設(shè)置新的圖片數(shù)據(jù)

oGC.putImageData(oImg, 100, 100);


- 像素屬性
  • width: 一行的像素個數(shù)
  • height: 一列的像素個數(shù)
  • data: 一個數(shù)組荆萤,包含每個像素的rgba四個值,注意每個值都在0~255之間的整數(shù)

- createImageData(w,h): 生成新的像素矩陣【初始值全透明的黑色铣卡,即(0,0,0,0)】

var oImg = oGC.createImageData(100, 100);

> 案例: 像素點(diǎn)方式顯示文字

## 十链韭、事件操作
- isPointlnPath: 是否在點(diǎn)擊范圍內(nèi)

oView.onmousedown = function(ev){
ev = ev || window.event;
// 獲取鼠標(biāo)相對于畫布的位置
var dowx = ev.offsetX;
var dowy = ev.offsetY;

// 判斷是否在范圍之內(nèi)
if( oGC.isPointInPath(dowx, dowy) ){
    alert('我被點(diǎn)擊了');
}

}


## 十一、將畫布內(nèi)容保存為圖片

// 參數(shù): canvas元素對象
function convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL("image/png");

// 返回一個img對象
return image;
}


## 十二煮落、圖表庫框架
Echarts敞峭,JS圖標(biāo)庫框架,底層依賴與canvas類庫(http://echarts.baidu.com/)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蝉仇,一起剝皮案震驚了整個濱河市旋讹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌轿衔,老刑警劉巖沉迹,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異害驹,居然都是意外死亡胚股,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門裙秋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來琅拌,“玉大人,你說我怎么就攤上這事摘刑〗Γ” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵枷恕,是天一觀的道長党晋。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么未玻? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任灾而,我火速辦了婚禮,結(jié)果婚禮上扳剿,老公的妹妹穿的比我還像新娘旁趟。我一直安慰自己,他們只是感情好庇绽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布锡搜。 她就那樣靜靜地躺著,像睡著了一般瞧掺。 火紅的嫁衣襯著肌膚如雪耕餐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天辟狈,我揣著相機(jī)與錄音肠缔,去河邊找鬼。 笑死哼转,一個胖子當(dāng)著我的面吹牛明未,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播释簿,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼亚隅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了庶溶?” 一聲冷哼從身側(cè)響起煮纵,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎偏螺,沒想到半個月后行疏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡套像,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年酿联,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片夺巩。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡贞让,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出柳譬,到底是詐尸還是另有隱情喳张,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布美澳,位于F島的核電站销部,受9級特大地震影響摸航,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜舅桩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一酱虎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧擂涛,春花似錦读串、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽甥雕。三九已至踩身,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間社露,已是汗流浹背挟阻。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留峭弟,地道東北人附鸽。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像瞒瘸,于是被迫代替她去往敵國和親坷备。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一:canvas簡介 1.1什么是canvas情臭? ①:canvas是HTML5提供的一種新標(biāo)簽 ②:HTML5 ...
    GreenHand1閱讀 4,685評論 2 32
  • 一省撑、canvas簡介 1.1 什么是canvas?(了解) 是HTML5提供的一種新標(biāo)簽 Canvas是一個矩形區(qū)...
    Looog閱讀 3,942評論 3 40
  • 0x001 Canvas是啥俯在? 說白了Canvas就是一塊畫布竟秫,可以使用js當(dāng)畫筆在上面繪畫的畫布,可以顯示在網(wǎng)頁...
    賣梳子的鯉魚閱讀 1,856評論 1 21
  • 一跷乐、canvas簡介 1.1 什么是canvas肥败?(了解) 是HTML5提供的一種新標(biāo)簽 Canvas是一個矩形區(qū)...
    J_L_L閱讀 1,516評論 0 4
  • 一、簡介 HTML5 中的定義:“它是依賴分辨率的位圖畫布愕提,你可以在 canvas 上面繪制任何圖形馒稍,甚至加載照片...
    destiny0904閱讀 10,545評論 1 4