SVG是構建XML樹的方式來達到繪制圖形的,canvas是通過調用相關的方法來繪制圖形的。
區別:SVG繪制圖形,通過移除或者更改DOM方式來而使用canvas需要把圖片從新擦除。
繪制的API在繪制上下文中定義。而不在畫布中定義。
需要獲得上下文對象的時候,需要調用畫布的getContext方法,獲得繪畫的上下文。
畫布元素和上下文,屬于兩個不同的對象,其中畫布元素為canvas畫布,而上下文對象為繪制需要的上下文。
關于3D圖形,即,webGL 為封裝了基本的OPENGL,當調用webGL的時候,其瀏覽器會調用OpenGL相關的API
<!DOCTYPE html> <html lang="zh_CN" xmlns="http://www.w3.org/1999/html"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div>第一個園</br> <canvas id="square" width="10" height="100"> </canvas> </div> <div> 第二個園 <canvas id="circle" width="10" height="10"> </canvas> </div> <script src="./js/index.js" charset="UTF-8"></script> </body> </html> // 獲取畫布元素 let canvas = document.getElementById("square"); // 獲取繪制2D元素上下文 let context = canvas.getContext("2d"); // 設置填充顏色為紅色 context.fillStyle = "#f00"; // 填充一個正方形 context.fillRect(10,0,10,10);
// 獲取畫布元素
let canvas = document.getElementById("square");
// 獲取繪制2D元素上下文
let context = canvas.getContext("2d");
// 開始一條路徑
context.beginPath();
// 從100,100 開始定義一條新的子路徑
context.moveTo(100,100);
// 從100 100 到 200 200 繪制一條線段
context.lineTo(200,200);
// 從200 200 到 100 200 繪制一條線段
context.lineTo(100,200);
// 從100 200 到 100 100 繪制一條路徑
context.lineTo(100,100);
// 繪制邊
context.stroke();
// 進行填充
context.fill();
以五邊形為例子,
var canvas = document.getElementById("square"); var context = canvas.getContext("2d"); // 繪制一個以100,100為中心,半徑為20的柜子N變形,每個定點均勻分布在圓角上,第一個定點放置在最上下 // 偏轉角度為0 // 開始定義一條子路徑 context.moveTo(100 + 20 * Math.sin(0), 100 - 20 * Math.cos(0)); // 計算兩個頂點之間夾角 // 其中2π為一個園,除以邊數,得到需要旋轉的角度 var delta = 2 * Math.PI/5; console.log(delta); // 循環剩余每個頂點 var angle = 0; for(var i = 1; i < 5; i++){ // 角度累加 angle += delta; // 通過旋轉繪制下一個頂點,不斷的旋轉繪制 context.lineTo(100 + 20 * Math.sin(angle), 100 - 20*Math.cos(angle)); } // 最后一個頂點和起點進行連接 context.closePath(); // 從新開始一條新路徑 context.stroke(); context.fill();
同理,畫圓
var canvas = document.getElementById("square"); var context = canvas.getContext("2d"); // 繪制一個以100,100為中心,半徑為20的柜子N變形,每個定點均勻分布在圓角上,第一個定點放置在最上下 // 偏轉角度為0 // 開始定義一條子路徑 context.moveTo(100 + 20 * Math.sin(0), 100 - 20 * Math.cos(0)); // 計算兩個頂點之間夾角 // 其中2π為一個園,除以邊數,得到需要旋轉的角度 var delta = 2 * Math.PI/500000; console.log(delta); // 循環剩余每個頂點 var angle = 0; for(var i = 1; i < 500000; i++){ // 角度累加 angle += delta; // 通過旋轉繪制下一個頂點,不斷的旋轉繪制 context.lineTo(100 + 20 * Math.sin(angle), 100 - 20*Math.cos(angle)); } // 最后一個頂點和起點進行連接 context.closePath(); // 從新開始一條新路徑 context.stroke(); context.fill();
非零繞數原則
要檢測一個點p是否在路徑內部,使用非零繞數原則,即,一條從點p出發沿著任意方向無限延伸,或者一直延伸到路徑所在的區域外某點的射線,現在從0開始初始化一個計數器,對穿過這條射線的路徑進行枚舉,每當一條路徑順時針方向穿過射線的時候,計數器加1,逆時針減1,最后,枚舉完所有路徑以后,如果計時器的值不是0,那么就認為p在路徑內,反過來,計數器的值為0,p在路徑外。
js根據非零繞數原則確定那個在路徑內,那個在路徑外,用于進行填充。
可以通過設置畫布上下文的fillStyle等屬性,設置圖形的屬性,例如對畫布上下文的fillStyle的屬性進行設置,即,可以設置出填充時的顏色,漸變,圖案等樣式。
對于canvas來說,每次獲取上下文對象的時候,都會返回同一個上下文對象,即,上下文對象為單例的。
還可以使用save方法,把當前的狀態,壓入已經保存的棧中,調用restore方法,把狀態進行恢復,即彈棧。
畫布的默認的坐標系為左上角的坐標原點(0,0),右邊數值大,下數值大,使用浮點數指定坐標,但不會自動轉換為整數,會用反鋸齒的方式,模擬填充部分元素。
畫布尺寸不能隨意改變,對任意屬性進行操作,都會清空整個畫布。
每一個點的坐標都會映射到css像素上,css像素會映射到一個或多個設備像素。
畫布中的特定操作,屬性使用默認坐標系。
畫布還有當前變換矩陣。
畫布還有當前變換矩陣,當前變換矩陣作為圖形狀態的一部分。矩陣定義了當前畫布的坐標系。
畫布的操作會把該點映射到當前的坐標系中。
坐標變換
當調用c.translate(dx,dy)方法的時候,會進行如下變換
translate會進行坐標的上下移動
x' = x + dy; y' = y + dy;
縮放
如要進行縮放,進行的是如下的變換
x' = sx * x; y' = sy * y;
進行旋轉操作,進行的是如下變換
x' = x * cos(a) - y * sin(a); y' = y * cos(a) - x * sin(a);
如果要先變換再伸縮,進行如下變換
需要先把現有坐標系映射成為坐標系中的點x’, y’ 然后再變換到x‘’ , y‘’
x'' = sx*x + dx; y'' = sy*y + dy;
如果變換順序相反進行如下變換
x'' = sx*(x + dx); y'' = sy*(y + dy);
這種變換稱為仿射變換,并且仿射變換會修改點的距離和線段間的夾角。對于平行線來說,仿射變換也會保持平行。仿射變換用6個參數描述成為如下表述
x' = ax + cy + e; y' = bx + dy + f;
通過傳入參數實現仿射變換
對于坐標變換來說,除非進行刷新,否則,已經繪制的圖形,不會進行消失,所有的變換,都不能對已經繪制的圖形進行更改。栗子如下
var canvas = document.getElementById("square"); var context = canvas.getContext("2d"); // 通過坐標變換實現科赫雪花 // 開始一條路徑 context.beginPath(); // 開始繪制子路徑 context.moveTo(100,100); // 繼續繪制 context.lineTo(200,200); // 繼續繪制 context.lineTo(200,200); // 進行繪制邊 context.stroke(); context.translate(200,200); // 開始一條路徑 context.beginPath(); // 開始繪制子路徑 context.moveTo(100,100); // 繼續繪制 context.lineTo(200,200); // 繼續繪制 context.lineTo(200,200); // 進行繪制邊 context.stroke();
已經繪制的圖形不會進行改變,改變的是已經繪制的圖形
var canvas = document.getElementById("square");
var context = canvas.getContext("2d");
// 通過坐標變換實現科赫雪花
// 當前狀態入棧
function leg(n) {
// 保存狀態
context.save();
// 遞歸畫
if(n == 0){
context.lineTo(50, 0);
}else{
// 定義為v字型
context.scale(1/2,1/2);
// 遞歸第一條
context.rotate(60 * (Math.PI / 180));
leg(n - 1);
context.rotate(-120 * (Math.PI / 180));
leg(n - 1);
}
// 坐標恢復變換
context.restore();
// 恢復下一個坐標為0,0
context.translate(50, 0);
}
context.save();
context.moveTo(50, 50);
// 繪制第一條
leg(1);
context.stroke();
繪制一些常見的圖形
var canvas = document.getElementById("square"); var context = canvas.getContext("2d"); // 工具函數,角度轉弧度 function rads(x) { return Math.PI * x / 180; } // 繪制園 context.beginPath(); context.arc(100,100,40, 0, rads(360), false); context.stroke(); context.fill();
同理繪制貝塞爾曲線也是同理。
繪制一個漸變
需要使用createLinearGradient獲取一個進行漸變的上下文,對這個上下文進行處理。然后其顏色設置為這個漸變的上下文,即,fillStyle屬性。
封頂
對于線段,有三種封頂方式,即,butt,square,round
在繪制圖形以后,會參數尖角,圓角,平角,三種。
lineCap屬性
和css類似,基線問題。
直接調動clip即可,當前路徑也會被裁剪進入,路徑外的統統不會顯示。
設置shadow屬性即可
畫布API支持位圖圖片,同時也支持canvas導出成為圖片。
// 創建一個img元素 let img = document.createElement("img"); // 設置src屬性 img.src = canvas.toDataURL(); // 追加到文檔后面 document.body.appendChild(img);
一些api不在闡述
調用getImageDate方法返回ImageDate對象
使用createImageDate()可以創建像素容器
進行動態模糊先獲取像素的ImageDate對象,然后再獲取該對象的data屬性,該data為一個數組。為一個維數組。每四個元素代表紅色分量,綠色分量,藍色分量,透明度分量。(Alpha分量)
其色素直為0-1,即,數組元素中保存的數組為色素值。
每四個每四個元素遍歷。然后把其色素值的1/ n + 上一個色塊的m/n 然后賦值給新的色塊,代碼如下
// row為行數 for(var row = 0; row < height; row++){ // 獲得每行第二個元素的偏移量,其中width為行的色素塊。 var i = row * width * 4; // 每4個的色素值進行處理 for(var col = 1; col < width; col++, i+=4){ // 對紅色分量處理 data[i] = (data[i] + data[i - 4] * m) / n; // 對綠色分量處理 data[i + 1] = (data[i + 1] + data[i + 1 - 4] * m) / n; // 對藍色分量處理 data[i + 2] = (data[i + 2] + data[i + 2 - 4] * m) / n; // 對透明度分量處理 data[i + 3] = (data[i + 3] + data[i + 3 - 4] * m) / n; } }
然后把其色素塊進行復制回去即可。
其中每個像素占據一個字節,一個四個字節。
isPointInPath方法用來確定一個點是否落在當前路徑中。
即命中檢測。
命中檢測可以和鼠標事件相互轉化
但是坐標需要進行轉換。
lt;canvas> 標簽定義圖形,比如圖表和其他圖像,你必須使用腳本來繪制圖形。
比如在畫布上(Canvas)畫一個紅色矩形,漸變矩形,彩色矩形,和一些彩色的文字。
什么是 canvas?
HTML5 <canvas> 元素用于圖形的繪制,通過腳本 (通常是JavaScript)來完成.
<canvas> 標簽只是圖形容器,您必須使用腳本來繪制圖形。
你可以通過多種方法使用 canvas 繪制路徑,盒、圓、字符以及添加圖像。
iphone
創建一個畫布(Canvas)
一個畫布在網頁中是一個矩形框,通過 <canvas> 元素來繪制。
注意: 默認情況下 <canvas> 元素沒有邊框和內容。
<canvas>簡單實例如下:
<canvas id="myCanvas" width="200" height="100"></canvas>
注意: 標簽通常需要指定一個id屬性 (腳本中經常引用), width 和 height 屬性定義的畫布的大小。
提示:你可以在HTML頁面中使用多個 <canvas> 元素.
1.使用 style 屬性來添加邊框:
<canvas id="myCanvas" width="200" height="100"
style="border:1px solid #000000;">
</canvas>
2.使用 JavaScript 來繪制圖像
canvas 元素本身是沒有繪圖能力的。所有的繪制工作必須在 JavaScript 內部完成:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillStyle="#FF0000";
ctx.fillRect(0,0,150,75);
實例解析:
3.首先,找到 <canvas> 元素:
var c=document.getElementById("myCanvas");
4.然后,創建 context 對象:
var ctx=c.getContext("2d");
getContext("2d") 對象是內建的 HTML5 對象,擁有多種繪制路徑、矩形、圓形、字符以及添加圖像的方法。
下面的兩行代碼繪制一個紅色的矩形:
ctx.fillStyle="#FF0000";
ctx.fillRect(0,0,150,75);
設置fillStyle屬性可以是CSS顏色,漸變,或圖案。fillStyle 默認設置是#000000(黑色)。
fillRect(x,y,width,height) 方法定義了矩形當前的填充方式。
iphone
Canvas 坐標
canvas 是一個二維網格。
canvas 的左上角坐標為 (0,0)
上面的 fillRect 方法擁有參數 (0,0,150,75)。
意思是:在畫布上繪制 150x75 的矩形,從左上角開始 (0,0)。
坐標實例
如下圖所示,畫布的 X 和 Y 坐標用于在畫布上對繪畫進行定位。鼠標移動的矩形框上,顯示定位坐標。
Canvas - 路徑
在Canvas上畫線,我們將使用以下兩種方法:
moveTo(x,y) 定義線條開始坐標
lineTo(x,y) 定義線條結束坐標
繪制線條我們必須使用到 "ink" 的方法,就像stroke().
定義開始坐標(0,0), 和結束坐標 (200,100)。然后使用 stroke() 方法來繪制線條:
Canvas - 文本
使用 canvas 繪制文本,重要的屬性和方法如下:
font - 定義字體
fillText(text,x,y) - 在 canvas 上繪制實心的文本
strokeText(text,x,y) - 在 canvas 上繪制空心的文本
使用 fillText():
使用 "Arial" 字體在畫布上繪制一個高 30px 的文字(實心):
JavaScript:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.font="30px Arial";
ctx.fillText("Hello World",10,50);
大家有沒有學會呢?沒學會的話記得私信小編"011"哦~
記得在過去的Web前端開發中,如果你需要繪圖或者生成相關圖形的話,使用Flash可能是你唯一或者說最強大的實現方式,而在近些年的技術熱點HTML5標準中,(畫布)能夠更加方便的幫助你實現2D繪制圖形圖像及其各種動畫效果功能。
首先我們先來了解一下什么是HTML Canvas?
我們可以在HTML中使用屬性width和height來定義Canvas。但是實現Canvas的相關功能主要還依賴于Javascript實現,即HTML5 Canvas API。我們使用javascript來訪問和控制Canvas相關的區域,比如調用相關繪圖的方法,用來動態的生成需要的動畫或者圖形。
接下來我們來看看canvas的特性:
互動性:Canvas支持互動,可以很好的響應用戶的操作,我們可以通過Javascript來監鍵盤,鼠標,及其觸摸設備相關事件。
動 畫:任何被canvas繪制的圖形都可以添加動畫,簡單的彈跳球或者復雜的HTML5游戲都可以實現
靈活性:開發人員可以使用Canvas來繪制任何的內容,比如,直線,圖形,文字,圖片等,可以包含動畫或者不包含。同時你可以添加音頻或者視頻瀏覽器支持:幾乎所有的現代瀏覽器都支持,并且被廣泛的各種設備支持,例如,桌面,平板,智能手機等等。
流行度:canvas目前很流行,很多的開發人員都使用它來開發類似游戲或者繪圖類應用
web標準:只需要有瀏覽器就可以運行,而非flash或者silverlight,需要安裝相關的插件
開發一次,任何瀏覽器都可以運行(當然,不包括老式瀏覽器)
可以使用免費擁有大量的開發工具及其類庫。
使用HTML5 Canvas我們能開發那些相關產品或者應用呢?
1 可視化數據: 各類統計圖表,比如:百度的echart
2 場景秀:用Canvas實現動態的廣告效果能夠非常融洽的跨平臺運行。如:手機中微產品.在移動端兼容性很好。
3 游戲:canvas在基于Web的圖像顯示方面比Flash更加立體、更加精巧,canvas成為HTML5小游戲開發首選。現階段h5做游戲,營業方式不是很明確. 25 超棒的 HTML5 Canvas 游戲。
4 其他可嵌入網站的內容 (多用于活動頁面、特效):類似圖表、音頻、視頻,還有許多元素能夠更好地與Web融合,并且不需要任何插件。
5 趨勢=> 模擬器: 無論從視覺效果還是核心功能方面來說,模擬器產品可以完全由JavaScript來實現。模擬真實硬件環境,如移動端各種類型手機.
6 趨勢=> 遠程計算機控制: Canvas可以讓開發者更好地實現基于Web的數據傳輸,構建一個完美的可視化控制界面。
7 趨勢=> 圖形編輯器: Photoshop圖形編輯器將能夠100%基于Web實現。
如何使用HTML5 Canvas?
使用HTML5 canvas其實非常簡單, 每一個canvas都擁有一個上下文(context)。使用它你可以來調用相關的畫布方法。
<canvas id="mycanvas" width="500" height ="400">
<p>您的瀏覽器不支持HTML5 Canvas</p>
</canvas>
以上代碼我們在HTML中添加了一個canvas標簽,如果瀏覽器不支持canvas,會顯示<p>標簽的內容,當然,如果你需要支持老式瀏覽器你也可以使用flash或者其它方法來做一個替代的解決方案。
var canvas = document.getElementById('mycanvas'),
context = canvas.getContext('2d');
以上代碼我們通過canvas取到2D的context。
在HTML5 Canvas的2D結構中,坐標(0,0)在左上方,這和傳統的坐標不太一樣。大家需要注意一下,如下圖所示:
save():保存當前環境的狀態
restore():返回之前保存過的路徑狀態和屬性
createEvent()
getContext():返回一個對象,指出訪問繪圖功能必要的API
toDateURL():返回canvas圖像的URL
fillStyle:設置或返回用于填充繪畫的顏色、漸變或模式
strokeStyle:設置或返回用于筆觸的顏色、漸變或模式
shadowColor:設置或返回用于陰影的顏色
shadowBlur:設置或返回用于陰影的模糊級別
shadowOffsetX:設置或返回陰影距形狀的水平距離
shadowOffsetY:設置或返回陰影距形狀的垂直距離
createLinearGradient():創建線性漸變(用在畫布內容上)
createPattern():在指定的方向上重復指定的元素
createRadialGradient():創建放射狀/環形的漸變(用在畫布內容上)
addColorStop():規定漸變對象中的顏色和停止位置
lineCap:設置或返回線條的結束端點樣式
lineJoin:設置或返回兩條線相交時,所創建的拐角類型
lineWidth:設置或返回當前的線段寬度
miterLimit:設置或返回最大斜接長度
fill():填充當前繪圖(路徑)
stroke():繪制已定義的路徑
beginPath():起始一條路徑,或重置當前路徑
moveTo():把路徑移動到畫布中的指定點,不創建線條
closePath():創建從當前點回到起始點的路徑
lineTo():添加一個新點,創建從該點到最后指定點的線條
clip():從原始畫布剪切任意形狀和尺寸的區域
quadraticCurveTo():創建二次貝塞爾曲線
bezierCurveTo():創建三次貝塞爾曲線
arc():創建弧/曲線(用于創建圓形或部分圓)
arcTo():創建兩切線之間的弧/曲線
isPointInPath():如果指定的點位于當前路徑中,返回布爾值
scale():縮放當前繪圖至更大或更小
rotate():旋轉當前繪圖
translate():重新映射畫布上的(0,0)位置
transform():替換繪圖的當前轉換矩陣
setTransform():將當前轉換重置為單位矩陣,然后運行transform()
font:設置或返回文本內容的當前字體屬性
textAlign:設置或返回文本內容的當前對齊方式
textBaseline:設置或返回在繪制文本時使用的的當前文本基線
fillText():在畫布上繪制"被填充的"文本
strokeText():在畫布上繪制文本(無填充)
measureText():返回包含指定文本寬度的對象
drawImage():向畫布上繪制圖像、畫布或視頻
Canvas的API-像素操作方法和屬性
width:返回ImageData對象的寬度
height:返回ImageData對象的高度
data:返回一個對象,其包含指定的ImageData對象的圖像數據
createImageData():創建新的、空白的I馬哥Data對象
getImageData():返回ImageData對象,該對象為畫布上指定的矩形復制像素數據
putImageData():把圖像數據(從指定的ImageData對象)放回畫布上
globalAlpha:設置或返回繪圖的當前alpha或透明值
globalCompositeOperation:設置或返回新圖像如何繪制到已有的圖像上
直接使用Canvas來繪制圖形相對來說比較乏味并且麻煩,所以在現代的HTML5 Canvas中我們使用一些現成的第三方類庫幫助我們多快好省的實現圖形繪制的功能:Echart.js
*請認真填寫需求信息,我們會在24小時內與您取得聯系。