神奇的 canvas--AICODER 全棧培訓(xùn) IT 培訓(xùn)專家
一、canvas 簡(jiǎn)介
1.1 什么是 canvas?(了解)
- 是 HTML5 提供的一種新標(biāo)簽
<canvas></canvas> 英 ['k?nv?s] 美 ['k?nv?s] 帆布 畫布
- Canvas 是一個(gè)矩形區(qū)域的
畫布
驾霜,可以用 JavaScript 在上面繪畫宴抚∈雇茫控制其每一個(gè)像素。 - canvas 標(biāo)簽使用 JavaScript 在網(wǎng)頁上繪制圖像球凰,本身不具備繪圖功能。
- canvas 擁有多種繪制路徑腿宰、矩形呕诉、圓形、字符以及添加圖像的方法吃度。
- HTML5 之前的 web 頁面只能用一些固定樣式的標(biāo)簽:比如 p甩挫、div、h1 等
1.2 canvas 主要應(yīng)用的領(lǐng)域(了解)
游戲:canvas 在基于 Web 的圖像顯示方面比 Flash 更加立體椿每、更加精巧伊者,canvas 游戲在流暢度和跨平臺(tái)方面更牛。
25 超棒的 HTML5 Canvas 游戲可視化數(shù)據(jù).數(shù)據(jù)圖表話间护,比如:百度的 echart
banner 廣告:Flash 曾經(jīng)輝煌的時(shí)代删壮,智能手機(jī)還未曾出現(xiàn)。現(xiàn)在以及未來的智能機(jī)時(shí)代兑牡,HTML5 技術(shù)能夠在 banner 廣告上發(fā)揮巨大作用央碟,用 Canvas 實(shí)現(xiàn)動(dòng)態(tài)的廣告效果再合適不過。
未來=> 模擬器:無論從視覺效果還是核心功能方面來說均函,模擬器產(chǎn)品可以完全由 JavaScript 來實(shí)現(xiàn)亿虽。
未來=> 遠(yuǎn)程計(jì)算機(jī)控制:Canvas 可以讓開發(fā)者更好地實(shí)現(xiàn)基于 Web 的數(shù)據(jù)傳輸,構(gòu)建一個(gè)完美的可視化控制界面苞也。
未來=> 圖形編輯器:Photoshop 圖形編輯器將能夠 100%基于 Web 實(shí)現(xiàn)洛勉。
其他可嵌入網(wǎng)站的內(nèi)容(多用于活動(dòng)頁面、特效):類似圖表如迟、音頻收毫、視頻攻走,還有許多元素能夠更好地與 Web 融合,并且不需要任何插件此再。
完整的 canvas 移動(dòng)化應(yīng)用
-
我們課程的目標(biāo)
- 我們不是主要做游戲開發(fā)的
- 要求必須會(huì)做基本的用 canvas 繪制的特效頁面:比如昔搂,傳智前端官網(wǎng)。
- 會(huì)用 canvas 做一些簡(jiǎn)單的廣告输拇、活動(dòng)頁面
我們課程的案例和項(xiàng)目演示
canvas 的標(biāo)準(zhǔn):
* 最新標(biāo)準(zhǔn):[http://www.w3.org/TR/2dcontext/](http://www.w3.org/TR/2dcontext/)
* 穩(wěn)定版本的標(biāo)準(zhǔn):[http://www.w3.org/TR/2013/CR-2dcontext-20130806/](http://www.w3.org/TR/2013/CR-2dcontext-20130806/)
* 目前來說摘符,標(biāo)準(zhǔn)還在完善中。先用早期的 api 足夠完成所有的應(yīng)用
二策吠、canvas 繪圖基礎(chǔ)
2.0 sublime 配置 canvas 插件(推薦)
推薦:
安裝插件:AndyJS2
github地址: https://github.com/malun666/AndyJS2
直接下載到:X:\Users\用戶名\AppData\Roaming\Sublime Text 3\Packages
2.1 Canvas 標(biāo)簽
2.1.1 canvas 標(biāo)簽語法和屬性 (重點(diǎn))
- canvas:畫布油布的意思 ==英 ['k?nv?s] 美 ['k?nv?s] ==
- 標(biāo)簽名 canvas逛裤,需要進(jìn)行閉合。就是一普通的 html 標(biāo)簽猴抹。
- 可以設(shè)置 width 和 height 屬性带族,但是屬性值單位必須是 px,否則忽略蟀给。
- width 和 hegiht:默認(rèn) 300*150 像素
- 注意:
- 不要用 CSS 控制它的寬和高,會(huì)走出圖片拉伸炉菲,
- 重新設(shè)置 canvas 標(biāo)簽的寬高屬性會(huì)讓畫布擦除所有的內(nèi)容。
- 可以給 canvas 畫布設(shè)置背景色
2.1.2 瀏覽器不兼容處理(重點(diǎn))
- ie9 以上才支持 canvas, 其他 chrome坤溃、ff拍霜、蘋果瀏覽器等都支持
- 只要瀏覽器兼容 canvas,那么就會(huì)支持絕大部分 api(個(gè)別最新 api 除外)
- 移動(dòng)端的兼容情況非常理想薪介,基本上隨便使用
- 2d 的支持的都非常好祠饺,3d(webgl)ie11 才支持,其他都支持
- 如果瀏覽器不兼容汁政,最好進(jìn)行友好提示
例如:
<canvas id="cavsElem">
你的瀏覽器不支持canvas道偷,請(qǐng)升級(jí)瀏覽器.瀏覽器不支持,顯示此行文本
</canvas>
- 瀏覽器不兼容记劈,可以使用flash等手段進(jìn)行優(yōu)雅降級(jí)
2.2 canvas 繪圖上下文 context
2.2.1 Context:Canvas 的上下文勺鸦、繪制環(huán)境。(重點(diǎn)掌握)
- 上下文:上知天文目木,下知地理换途。是所有的繪制操作 api 的入口或者集合。
- Canvas 自身無法繪制任何內(nèi)容刽射。Canvas 的繪圖是使用 JavaScript 操作的军拟。
- Context 對(duì)象就是 JavaScript 操作 Canvas 的接口。 *使用[CanvasElement].getContext(‘2d’)來獲取 2D 繪圖上下文誓禁。
var canvas = document.getElementById('cavsElem'); //獲得畫布
var ctx = canvas.getContext('2d'); //注意:2d小寫懈息, 3d:webgl
2.3 基本的繪制路徑(重點(diǎn))
2.3.1 canvas 坐標(biāo)系
canvas 坐標(biāo)系,從最左上角 0,0 開始摹恰。x 向右增大辫继, y 向下增大
2.3.2 設(shè)置繪制起點(diǎn)(moveTo)
* 語法:ctx.moveTo(x, y);
* 解釋:設(shè)置上下文繪制路徑的起點(diǎn)怒见。相當(dāng)于移動(dòng)畫筆到某個(gè)位置
* 參數(shù):x,y 都是相對(duì)于 canvas盒子的最左上角。
* 注意:**繪制線段前必須先設(shè)置起點(diǎn)姑宽。**
2.3.3 繪制直線(lineTo)
* 語法:ctx.lineTo(x, y);
* 解釋:從x,y的位置繪制一條直線到起點(diǎn)或者上一個(gè)線頭點(diǎn)遣耍。
* 參數(shù):x,y 線頭點(diǎn)坐標(biāo)。
2.3.4 路徑開始和閉合
* 開始路徑:ctx.beginPath();
* 閉合路徑:ctx.closePath();
* 解釋:如果是繪制不同狀態(tài)的線段或者形狀低千,必須使用開始新路徑的方法把不同的繪制操作隔開咸产。閉合路徑會(huì)自動(dòng)把最后的線頭和開始的線頭連在一起朴艰。
* beginPath: 核心的作用是將 不同繪制的形狀進(jìn)行隔離,
每次執(zhí)行此方法亚亲,表示重新繪制一個(gè)路徑,跟之前的繪制的墨跡可以進(jìn)行分開樣式設(shè)置和管理救拉。
2.3.5 描邊(stroke)
* 語法:ctx.stroke();
* 解釋:根據(jù)路徑繪制線难审。路徑只是草稿,真正繪制線必須執(zhí)行stroke
* stroke: (用筆等)畫亿絮;輕撫告喊;輕挪;敲擊派昧;劃尾槳黔姜;劃掉;(打字時(shí))擊打鍵盤
英 [str??k] 美 [strok]
- canvas 繪制的基本步驟:
- 第一步:獲得上下文 =>canvasElem.getContext('2d');
- 第二步:開始路徑規(guī)劃 =>ctx.beginPath()
- 第三步:移動(dòng)起始點(diǎn) =>ctx.moveTo(x, y)
- 第四步:繪制線(矩形蒂萎、圓形秆吵、圖片...) =>ctx.lineTo(x, y)
- 第五步:閉合路徑 =>ctx.closePath();
- 第六步:繪制描邊 =>ctx.stroke();
html 部分:
<canvas id="cavsElem"> 你的瀏覽器不支持canvas,請(qǐng)升級(jí)瀏覽器 </canvas>
javascript 部分:
//===============基本繪制api====================
//獲得畫布
var canvas = document.querySelector('#cavsElem');
var ctx = canvas.getContext('2d'); //獲得上下文
canvas.width = 900; //設(shè)置標(biāo)簽的屬性寬高
canvas.height = 600; //千萬不要用 canvas.style.height
canvas.style.border = '1px solid #000';
//繪制三角形
ctx.beginPath(); //開始路徑
ctx.moveTo(100, 100); //三角形五慈,左頂點(diǎn)
ctx.lineTo(300, 100); //右頂點(diǎn)
ctx.lineTo(300, 300); //底部的點(diǎn)
ctx.closePath(); //結(jié)束路徑
ctx.stroke(); //描邊路徑
- 綜合案例:02 繪制定位表格.html
- 綜合案例:03 畫畫板.html
2.3.7 填充(fill)
* 語法:ctx.fill();
* 解釋:填充纳寂,是將閉合的路徑的內(nèi)容填充具體的顏色。默認(rèn)黑色泻拦。
* 注意:交叉路徑的填充問題毙芜,“非零環(huán)繞原則”,順逆時(shí)針穿插次數(shù)決定是否填充争拐。
以下是非0環(huán)繞原則的原理:(了解即可腋粥,非常少會(huì)用到復(fù)雜的路徑)
“非零環(huán)繞規(guī)則”是這么來判斷有自我交叉情況的路徑的:對(duì)于路徑中的任意給定區(qū)域,從該區(qū)域內(nèi)部畫一條足夠長(zhǎng)的線段架曹,
使此線段的終點(diǎn)完全落在路徑范圍之外灯抛。
圖2-14中的那三個(gè)箭頭所描述的就是上面這個(gè)步驟。
接下來音瓷,將計(jì)數(shù)器初始化為0对嚼,
然后,每當(dāng)這條線段與路徑上的直線或曲線相交時(shí)绳慎,
就改變計(jì)數(shù)器的值纵竖。如果是與路徑的順時(shí)針部分相交漠烧,則加1,
如果是與路徑的逆時(shí)針部分相交靡砌,則減1已脓。若計(jì)數(shù)器的最終值不是0,那么此區(qū)域就在路徑里面通殃,在調(diào)用fill()方法時(shí)度液,
瀏覽器就會(huì)對(duì)其進(jìn)行填充。
如果最終值是0画舌,那么此區(qū)域就不在路徑內(nèi)部堕担,瀏覽器也就不會(huì)對(duì)其進(jìn)行填充了
* 案例: 04填充矩形.html
2.3.8 快速創(chuàng)建矩形 rect()方法
* 語法:ctx.rect(x, y, width, height);
* 解釋:x, y是矩形左上角坐標(biāo), width和height都是以像素計(jì)
* rect方法只是規(guī)劃了矩形的路徑曲聂,并沒有填充和描邊霹购。
* 改造案例:04填充矩形.html
*rect: abbr. 矩形(rectangular);收據(jù)(receipt)
2.3.9 快速創(chuàng)建描邊矩形和填充矩形
* 語法: ctx.strokeRect(x, y, width, height);
- 參數(shù)跟2.3.8相同朋腋,注意此方法繪制完路徑后立即進(jìn)行stroke繪制
* 語法:ctx.fillRect(x, y, width, height);
- 參數(shù)跟2.3.8相同齐疙, 此方法執(zhí)行完成后。立即對(duì)當(dāng)前矩形進(jìn)行fill填充旭咽。
2.3.10 清除矩形(clearRect)
* 語法:ctx.clearRect(x, y, width, hegiht);
* 解釋:清除某個(gè)矩形內(nèi)的繪制的內(nèi)容贞奋,相當(dāng)于橡皮擦。
2.4 繪制圓形(arc)
-
概述:arc() 方法創(chuàng)建弧/曲線(用于創(chuàng)建圓或部分圓)穷绵。
- 語法:ctx.arc(x,y,r,sAngle,eAngle,counterclockwise);
- arc: 灰涿(度)弧形物;天穹 英 [ɑ?k] 美 [ɑrk]
- counter 反擊请垛,還擊催训;反向移動(dòng),對(duì)著干宗收;反駁漫拭,回答 ['ka?nt?] 美 ['ka?nt?]
- 解釋: - x,y:圓心坐標(biāo)。 - r:半徑大小混稽。 - sAngle:繪制開始的角度采驻。 圓心到最右邊點(diǎn)是 0 度,順時(shí)針方向弧度增大匈勋。 - eAngel:結(jié)束的角度礼旅,注意是弧度。π - counterclockwise:是否是逆時(shí)針洽洁。true 是逆時(shí)針痘系,false:順時(shí)針 - 弧度和角度的轉(zhuǎn)換公式:
rad = deg\*Math.PI/180;
- 在 Math 提供的方法中sin、cos 等都使用的弧度
[圖片上傳失敗...(image-a5bab2-1550761584130)]
案例:05 繪制圓形.html
案例:06 繪制餅狀圖.html
2.5 繪制文字(會(huì)使用就可以了)
2.5.1 繪制上下文的文字屬性 (有印象就行了)
- font 設(shè)置或返回文本內(nèi)容的當(dāng)前字體屬性
- font 屬性使用的語法與 CSS font 屬性相同饿自。
例如:ctx.font = "18px '微軟雅黑'";
- textAlign 設(shè)置或返回文本內(nèi)容的當(dāng)前對(duì)齊方式
- start : 默認(rèn)汰翠。文本在指定的位置開始龄坪。
- end : 文本在指定的位置結(jié)束。
- center: 文本的中心被放置在指定的位置复唤。
- left : 文本左對(duì)齊健田。
- right : 文本右對(duì)齊。
例如:ctx.textAlign = 'left';
- textBaseline 設(shè)置或返回在繪制文本時(shí)使用的當(dāng)前文本基線
- alphabetic : 默認(rèn)佛纫。文本基線是普通的字母基線妓局。
- top : 文本基線是 em 方框的頂端。呈宇。
- hanging : 文本基線是懸掛基線好爬。
- middle : 文本基線是 em 方框的正中。
- ideographic: 文本基線是 em 基線攒盈。
- bottom : 文本基線是 em 方框的底端抵拘。
例如: ctx.textBaseline = 'top'; 單詞: alphabetic: 字母的哎榴;照字母次序的 [,?lf?'b?t?k] ideographic:表意的型豁;表意字構(gòu)成的 英 [,?d???'ɡr?f?k] 美 [,?d??'gr?f?k]
2.5.2 上下文繪制文字方法
* ctx.fillText() 在畫布上繪制“被填充的”文本
* ctx.strokeText() 在畫布上繪制文本(無填充)
* ctx.measureText() 返回包含指定文本寬度的對(duì)象
* 單詞:measure 測(cè)量;估量尚蝌;權(quán)衡 英 ['me??] 美 ['m???]
//綜合案例代碼:
ctx.moveTo(300, 300);
ctx.fillStyle = 'purple'; //設(shè)置填充顏色為紫色
ctx.font = '20px "微軟雅黑"'; //設(shè)置字體
ctx.textBaseline = 'bottom'; //設(shè)置字體底線對(duì)齊繪制基線
ctx.textAlign = 'left'; //設(shè)置字體對(duì)齊的方式
//ctx.strokeText( "left", 450, 400 );
ctx.fillText('Top-g', 100, 300); //填充文字
2.5.3 案例 07 文字繪制.html
2.6 繪制圖片(drawImage) (重點(diǎn))
2.6.1 基本繪制圖片的方式
context.drawImage(img,x,y);
參數(shù)說明: x,y 繪制圖片左上角的坐標(biāo)迎变, img是繪制圖片的dom對(duì)象。
2.6.2 在畫布上繪制圖像飘言,并規(guī)定圖像的寬度和高度
context.drawImage(img,x,y,width,height);
參數(shù)說明:width 繪制圖片的寬度衣形, height:繪制圖片的高度
如果指定寬高,最好成比例姿鸿,不然圖片會(huì)被拉伸</em>
等比公式: toH = Height * toW / Width; //等比
設(shè)置高 = 原高度 * 設(shè)置寬/ 原寬度;
2.6.3 圖片裁剪谆吴,并在畫布上定位被剪切的部分
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
參數(shù)說明:
sx,sy 裁剪的左上角坐標(biāo),
swidth:裁剪圖片的高度苛预。 sheight:裁剪的高度
其他同上
2.6.4 用 JavaScript 創(chuàng)建 img 對(duì)象
第一種方式:
var img = document.getElementById('imgId');
第二種方式:
var img = new Image(); //這個(gè)就是 img標(biāo)簽的dom對(duì)象
img.src = '/aicoder_vip_doc/images/arc.gif';
img.alt = '文本信息';
img.onload = function() {
//圖片加載完成后句狼,執(zhí)行此方法
};
2.6.5 面向?qū)ο蠡A(chǔ)復(fù)習(xí)補(bǔ)充:
- 創(chuàng)建對(duì)象的方式:
var o = { name: '123', age: 18 }; //json方式創(chuàng)建
var o = new Object(); //通過new的方式創(chuàng)建
var o = new Persion(); //通過類的構(gòu)造函數(shù)創(chuàng)建
- JS 中對(duì)象的屬性創(chuàng)建方式
* json的方式: var o = { age: 19 };
* 直接添加屬性:var o = {}; o.age = 19;//太分散了,不利于管理
* 由于js動(dòng)態(tài)語言的特性热某,如果屬性不存在的時(shí)候腻菇,直接添加屬性。
* 構(gòu)造函數(shù)添加屬性
* 原型添加公共的屬性
-
JS 的構(gòu)造函數(shù)的原型 構(gòu)造函數(shù)的原型就是:構(gòu)造對(duì)象的模板昔馋,構(gòu)造函數(shù)原型里面的所有的屬性和方法都會(huì)共享給所有的 構(gòu)造函數(shù)構(gòu)造出來的所有實(shí)例筹吐。
2.6.6 補(bǔ)充 sublime 制作代碼段
第一步:sublime 菜單欄 → 工具 → 制作代碼段
第二步:修改輸出的 sublime 代碼段文本
<snippet>
<content><![CDATA[
1、這里放要tab鍵 輸出的內(nèi)容
2秘遏、 ${1:this} 占位符丘薛,tab可以進(jìn)行切換,數(shù)字是切換的索引邦危。
:后面的是默認(rèn)的文本榔袋。
]]></content>
<!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
<tabTrigger>簡(jiǎn)寫的字母</tabTrigger>
<!-- Optional: Set a scope to limit where the snippet will trigger -->
<!-- <scope>source.python</scope> -->
</snippet>
第三步:保存到插件的文件夾中周拐,后綴名為:.sublime-snippet 比如我存放的位置:
C:\Users\malunmac\AppData\Roaming\Sublime Text 3\Packages\User\snippets
snippets 是我自己新建的文件夾。
視頻
配套視頻請(qǐng)戳:https://www.bilibili.com/video/av26151775/
關(guān)注AICODER官網(wǎng): https://www.aicoder.com