Canvas入門到高級詳解(上)
神奇的 canvas--AICODER 全棧培訓 IT 培訓專家
一、canvas 簡介
1.1 什麽是 canvas?(了解)
- 是 HTML5 提供的一種新標簽
<canvas></canvas> 英 [‘kænv?s] 美 [‘kænv?s] 帆布 畫布
- Canvas 是一個矩形區域的
畫布
,可以用 JavaScript 在上面繪畫。控制其每一個像素。 - canvas 標簽使用 JavaScript 在網頁上繪制圖像,本身不具備繪圖功能。
- canvas 擁有多種繪制路徑、矩形、圓形、字符以及添加圖像的方法。
- HTML5 之前的 web 頁面只能用一些固定樣式的標簽:比如 p、div、h1 等
1.2 canvas 主要應用的領域(了解)
-
遊戲:canvas 在基於 Web 的圖像顯示方面比 Flash 更加立體、更加精巧,canvas 遊戲在流暢度和跨平臺方面更牛。
25 超棒的 HTML5 Canvas 遊戲 -
可視化數據.數據圖表話,比如:百度的 echart
-
banner 廣告:Flash 曾經輝煌的時代,智能手機還未曾出現。現在以及未來的智能機時代,HTML5 技術能夠在 banner 廣告上發揮巨大作用,用 Canvas 實現動態的廣告效果再合適不過。
-
未來=> 模擬器:無論從視覺效果還是核心功能方面來說,模擬器產品可以完全由 JavaScript 來實現。
-
未來=> 遠程計算機控制:Canvas 可以讓開發者更好地實現基於 Web 的數據傳輸,構建一個完美的可視化控制界面。
-
未來=> 圖形編輯器:Photoshop 圖形編輯器將能夠 100%基於 Web 實現。
-
其他可嵌入網站的內容(多用於活動頁面、特效):類似圖表、音頻、視頻,還有許多元素能夠更好地與 Web 融合,並且不需要任何插件。
-
完整的 canvas 移動化應用
-
我們課程的目標
- 我們不是主要做遊戲開發的
- 要求必須會做基本的用 canvas 繪制的特效頁面:比如,傳智前端官網。
- 會用 canvas 做一些簡單的廣告、活動頁面
-
我們課程的案例和項目演示
-
canvas 的標準:
* 最新標準:[http://www.w3.org/TR/2dcontext/](http://www.w3.org/TR/2dcontext/)
* 穩定版本的標準:[http://www.w3.org/TR/2013/CR-2dcontext-20130806/](http://www.w3.org/TR/2013/CR-2dcontext-20130806/)
* 目前來說,標準還在完善中。先用早期的 api 足夠完成所有的應用
二、canvas 繪圖基礎
2.0 sublime 配置 canvas 插件(推薦)
推薦:
安裝插件:AndyJS2
github地址: https://github.com/malun666/AndyJS2
直接下載到:X:\Users\用戶名\AppData\Roaming\Sublime Text 3\Packages
2.1 Canvas 標簽
2.1.1 canvas 標簽語法和屬性 (重點)
- canvas:畫布油布的意思 ==英 [‘kænv?s] 美 [‘kænv?s] ==
- 標簽名 canvas,需要進行閉合。就是一普通的 html 標簽。
- 可以設置 width 和 height 屬性,但是屬性值單位必須是 px,否則忽略。
- width 和 hegiht:默認 300*150 像素
- 註意:
- 不要用 CSS 控制它的寬和高,會走出圖片拉伸,
- 重新設置 canvas 標簽的寬高屬性會讓畫布擦除所有的內容。
- 可以給 canvas 畫布設置背景色
2.1.2 瀏覽器不兼容處理(重點)
- ie9 以上才支持 canvas, 其他 chrome、ff、蘋果瀏覽器等都支持
- 只要瀏覽器兼容 canvas,那麽就會支持絕大部分 api(個別最新 api 除外)
- 移動端的兼容情況非常理想,基本上隨便使用
- 2d 的支持的都非常好,3d(webgl)ie11 才支持,其他都支持
- 如果瀏覽器不兼容,最好進行友好提示
例如:
<canvas id="cavsElem">
你的瀏覽器不支持canvas,請升級瀏覽器.瀏覽器不支持,顯示此行文本
</canvas>
- 瀏覽器不兼容,可以使用flash等手段進行優雅降級
2.2 canvas 繪圖上下文 context
2.2.1 Context:Canvas 的上下文、繪制環境。(重點掌握)
- 上下文:上知天文,下知地理。是所有的繪制操作 api 的入口或者集合。
- Canvas 自身無法繪制任何內容。Canvas 的繪圖是使用 JavaScript 操作的。
- Context 對象就是 JavaScript 操作 Canvas 的接口。 *使用[CanvasElement].getContext(‘2d’)來獲取 2D 繪圖上下文。
var canvas = document.getElementById(‘cavsElem‘); //獲得畫布
var ctx = canvas.getContext(‘2d‘); //註意:2d小寫, 3d:webgl
2.3 基本的繪制路徑(重點)
2.3.1 canvas 坐標系
canvas 坐標系,從最左上角 0,0 開始。x 向右增大, y 向下增大
image2.3.2 設置繪制起點(moveTo)
* 語法:ctx.moveTo(x, y);
* 解釋:設置上下文繪制路徑的起點。相當於移動畫筆到某個位置
* 參數:x,y 都是相對於 canvas盒子的最左上角。
* 註意:**繪制線段前必須先設置起點。**
2.3.3 繪制直線(lineTo)
* 語法:ctx.lineTo(x, y);
* 解釋:從x,y的位置繪制一條直線到起點或者上一個線頭點。
* 參數:x,y 線頭點坐標。
2.3.4 路徑開始和閉合
* 開始路徑:ctx.beginPath();
* 閉合路徑:ctx.closePath();
* 解釋:如果是繪制不同狀態的線段或者形狀,必須使用開始新路徑的方法把不同的繪制操作隔開。閉合路徑會自動把最後的線頭和開始的線頭連在一起。
* beginPath: 核心的作用是將 不同繪制的形狀進行隔離,
每次執行此方法,表示重新繪制一個路徑,跟之前的繪制的墨跡可以進行分開樣式設置和管理。
2.3.5 描邊(stroke)
* 語法:ctx.stroke();
* 解釋:根據路徑繪制線。路徑只是草稿,真正繪制線必須執行stroke
* stroke: (用筆等)畫;輕撫;輕挪;敲擊;劃尾槳;劃掉;(打字時)擊打鍵盤
英 [str??k] 美 [strok]
- canvas 繪制的基本步驟:
- 第一步:獲得上下文 =>canvasElem.getContext(‘2d‘);
- 第二步:開始路徑規劃 =>ctx.beginPath()
- 第三步:移動起始點 =>ctx.moveTo(x, y)
- 第四步:繪制線(矩形、圓形、圖片...) =>ctx.lineTo(x, y)
- 第五步:閉合路徑 =>ctx.closePath();
- 第六步:繪制描邊 =>ctx.stroke();
html 部分:
<canvas id="cavsElem"> 你的瀏覽器不支持canvas,請升級瀏覽器 </canvas>
javascript 部分:
//===============基本繪制api====================
//獲得畫布
var canvas = document.querySelector(‘#cavsElem‘);
var ctx = canvas.getContext(‘2d‘); //獲得上下文
canvas.width = 900; //設置標簽的屬性寬高
canvas.height = 600; //千萬不要用 canvas.style.height
canvas.style.border = ‘1px solid #000‘;
//繪制三角形
ctx.beginPath(); //開始路徑
ctx.moveTo(100, 100); //三角形,左頂點
ctx.lineTo(300, 100); //右頂點
ctx.lineTo(300, 300); //底部的點
ctx.closePath(); //結束路徑
ctx.stroke(); //描邊路徑
- 綜合案例:02 繪制定位表格.html
- 綜合案例:03 畫畫板.html
2.3.7 填充(fill)
* 語法:ctx.fill();
* 解釋:填充,是將閉合的路徑的內容填充具體的顏色。默認黑色。
* 註意:交叉路徑的填充問題,“非零環繞原則”,順逆時針穿插次數決定是否填充。
以下是非0環繞原則的原理:(了解即可,非常少會用到復雜的路徑)
“非零環繞規則”是這麽來判斷有自我交叉情況的路徑的:對於路徑中的任意給定區域,從該區域內部畫一條足夠長的線段,
使此線段的終點完全落在路徑範圍之外。
圖2-14中的那三個箭頭所描述的就是上面這個步驟。
接下來,將計數器初始化為0,
然後,每當這條線段與路徑上的直線或曲線相交時,
就改變計數器的值。如果是與路徑的順時針部分相交,則加1,
如果是與路徑的逆時針部分相交,則減1。若計數器的最終值不是0,那麽此區域就在路徑裏面,在調用fill()方法時,
瀏覽器就會對其進行填充。
如果最終值是0,那麽此區域就不在路徑內部,瀏覽器也就不會對其進行填充了
* 案例: 04填充矩形.html
2.3.8 快速創建矩形 rect()方法
* 語法:ctx.rect(x, y, width, height);
* 解釋:x, y是矩形左上角坐標, width和height都是以像素計
* rect方法只是規劃了矩形的路徑,並沒有填充和描邊。
* 改造案例:04填充矩形.html
*rect: abbr. 矩形(rectangular);收據(receipt)
2.3.9 快速創建描邊矩形和填充矩形
* 語法: ctx.strokeRect(x, y, width, height);
- 參數跟2.3.8相同,註意此方法繪制完路徑後立即進行stroke繪制
* 語法:ctx.fillRect(x, y, width, height);
- 參數跟2.3.8相同, 此方法執行完成後。立即對當前矩形進行fill填充。
2.3.10 清除矩形(clearRect)
* 語法:ctx.clearRect(x, y, width, hegiht);
* 解釋:清除某個矩形內的繪制的內容,相當於橡皮擦。
2.4 繪制圓形(arc)
-
概述:arc() 方法創建弧/曲線(用於創建圓或部分圓)。
- 語法:ctx.arc(x,y,r,sAngle,eAngle,counterclockwise);
- arc: 弧(度)弧形物;天穹 英 [ɑ?k] 美 [ɑrk]
- counter 反擊,還擊;反向移動,對著幹;反駁,回答 [‘ka?nt?] 美 [‘ka?nt?]
- 解釋: - x,y:圓心坐標。 - r:半徑大小。 - sAngle:繪制開始的角度。 圓心到最右邊點是 0 度,順時針方向弧度增大。 - eAngel:結束的角度,註意是弧度。π - counterclockwise:是否是逆時針。true 是逆時針,false:順時針 - 弧度和角度的轉換公式:
rad = deg\*Math.PI/180;
- 在 Math 提供的方法中sin、cos 等都使用的弧度
[圖片上傳失敗...(image-a5bab2-1550761584130)]
-
案例:05 繪制圓形.html
-
案例:06 繪制餅狀圖.html
2.5 繪制文字(會使用就可以了)
2.5.1 繪制上下文的文字屬性 (有印象就行了)
- font 設置或返回文本內容的當前字體屬性
- font 屬性使用的語法與 CSS font 屬性相同。
例如:ctx.font = "18px ‘微軟雅黑‘";
- textAlign 設置或返回文本內容的當前對齊方式
- start : 默認。文本在指定的位置開始。
- end : 文本在指定的位置結束。
- center: 文本的中心被放置在指定的位置。
- left : 文本左對齊。
- right : 文本右對齊。
對齊圖片例如:ctx.textAlign = ‘left‘;
- textBaseline 設置或返回在繪制文本時使用的當前文本基線
- alphabetic : 默認。文本基線是普通的字母基線。
- top : 文本基線是 em 方框的頂端。。
- hanging : 文本基線是懸掛基線。
- middle : 文本基線是 em 方框的正中。
- ideographic: 文本基線是 em 基線。
- bottom : 文本基線是 em 方框的底端。
設置文字為主 image例如: ctx.textBaseline = ‘top‘; 單詞: alphabetic: 字母的;照字母次序的 [,ælf?‘b?t?k] ideographic:表意的;表意字構成的 英 [,?d???‘ɡræf?k] 美 [,?d??‘græf?k]
2.5.2 上下文繪制文字方法
* ctx.fillText() 在畫布上繪制“被填充的”文本
* ctx.strokeText() 在畫布上繪制文本(無填充)
* ctx.measureText() 返回包含指定文本寬度的對象
* 單詞:measure 測量;估量;權衡 英 [‘me??] 美 [‘m???]
//綜合案例代碼:
ctx.moveTo(300, 300);
ctx.fillStyle = ‘purple‘; //設置填充顏色為紫色
ctx.font = ‘20px "微軟雅黑"‘; //設置字體
ctx.textBaseline = ‘bottom‘; //設置字體底線對齊繪制基線
ctx.textAlign = ‘left‘; //設置字體對齊的方式
//ctx.strokeText( "left", 450, 400 );
ctx.fillText(‘Top-g‘, 100, 300); //填充文字
2.5.3 案例 07 文字繪制.html
2.6 繪制圖片(drawImage) (重點)
2.6.1 基本繪制圖片的方式
context.drawImage(img,x,y);
參數說明: x,y 繪制圖片左上角的坐標, img是繪制圖片的dom對象。
2.6.2 在畫布上繪制圖像,並規定圖像的寬度和高度
context.drawImage(img,x,y,width,height);
參數說明:width 繪制圖片的寬度, height:繪制圖片的高度
如果指定寬高,最好成比例,不然圖片會被拉伸</em>
等比公式: toH = Height * toW / Width; //等比
設置高 = 原高度 * 設置寬/ 原寬度;
2.6.3 圖片裁剪,並在畫布上定位被剪切的部分
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
參數說明:
sx,sy 裁剪的左上角坐標,
swidth:裁剪圖片的高度。 sheight:裁剪的高度
其他同上
2.6.4 用 JavaScript 創建 img 對象
第一種方式:
var img = document.getElementById(‘imgId‘);
第二種方式:
var img = new Image(); //這個就是 img標簽的dom對象
img.src = ‘/aicoder_vip_doc/images/arc.gif‘;
img.alt = ‘文本信息‘;
img.onload = function() {
//圖片加載完成後,執行此方法
};
2.6.5 面向對象基礎復習補充:
- 創建對象的方式:
var o = { name: ‘123‘, age: 18 }; //json方式創建
var o = new Object(); //通過new的方式創建
var o = new Persion(); //通過類的構造函數創建
- JS 中對象的屬性創建方式
* json的方式: var o = { age: 19 };
* 直接添加屬性:var o = {}; o.age = 19;//太分散了,不利於管理
* 由於js動態語言的特性,如果屬性不存在的時候,直接添加屬性。
* 構造函數添加屬性
* 原型添加公共的屬性
-
JS 的構造函數的原型 構造函數的原型就是:構造對象的模板,構造函數原型裏面的所有的屬性和方法都會共享給所有的 構造函數構造出來的所有實例。
2.6.6 補充 sublime 制作代碼段
第一步:sublime 菜單欄 → 工具 → 制作代碼段
第二步:修改輸出的 sublime 代碼段文本
<snippet>
<content><![CDATA[
1、這裏放要tab鍵 輸出的內容
2、 ${1:this} 占位符,tab可以進行切換,數字是切換的索引。
:後面的是默認的文本。
]]></content>
<!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
<tabTrigger>簡寫的字母</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 是我自己新建的文件夾。
視頻
配套視頻請戳:https://www.bilibili.com/video/av26151775/
關註AICODER官網: https://www.aicoder.com
Canvas入門到高級詳解(上)