1. 程式人生 > >Canvas入門到高級詳解(上)

Canvas入門到高級詳解(上)

lar 普通 要求 相交 limit class 底部 pla game

神奇的 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 主要應用的領域(了解)

  1. 遊戲:canvas 在基於 Web 的圖像顯示方面比 Flash 更加立體、更加精巧,canvas 遊戲在流暢度和跨平臺方面更牛。
    25 超棒的 HTML5 Canvas 遊戲

  2. 可視化數據.數據圖表話,比如:百度的 echart

  3. banner 廣告:Flash 曾經輝煌的時代,智能手機還未曾出現。現在以及未來的智能機時代,HTML5 技術能夠在 banner 廣告上發揮巨大作用,用 Canvas 實現動態的廣告效果再合適不過。

  4. 未來=> 模擬器:無論從視覺效果還是核心功能方面來說,模擬器產品可以完全由 JavaScript 來實現。

  5. 未來=> 遠程計算機控制:Canvas 可以讓開發者更好地實現基於 Web 的數據傳輸,構建一個完美的可視化控制界面。

  6. 未來=> 圖形編輯器:Photoshop 圖形編輯器將能夠 100%基於 Web 實現。

  7. 其他可嵌入網站的內容(多用於活動頁面、特效):類似圖表、音頻、視頻,還有許多元素能夠更好地與 Web 融合,並且不需要任何插件。

  8. 完整的 canvas 移動化應用

  9. 我們課程的目標

    • 我們不是主要做遊戲開發的
    • 要求必須會做基本的用 canvas 繪制的特效頁面:比如,傳智前端官網。
    • 會用 canvas 做一些簡單的廣告、活動頁面
  10. 我們課程的案例和項目演示

  11. 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 向下增大

技術分享圖片 image

2.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 方框的底端。

例如: ctx.textBaseline = ‘top‘; 單詞: alphabetic: 字母的;照字母次序的 [,ælf?‘b?t?k] ideographic:表意的;表意字構成的 英 [,?d???‘ɡræf?k] 美 [,?d??‘græf?k]

技術分享圖片 設置文字為主 技術分享圖片 image

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入門到高級詳解(上)